CSS代码:
zxx-circle {
display: block;
width: 207px; height: 250px;
color: white;
background-color: deepskyblue;
text-shadow: 1px 1px rgba(0,0,0,.5);
padding: 10px;
text-align: justify;
}
HTML代码:
<zxx-circle>在CSS Shapes布局问世之前,文字像杂志一样的任意形状的排版几乎是不可能的,一直都是用网格、盒子和直线构造。CSS Shapes允许我们定义文本环绕的几何形状。这些形状可以是圆、椭圆、简单或复杂的多边形,甚至是任意的图像和多彩的渐变。</zxx-circle>
JS代码:
class HTMLZxxCircleElement extends HTMLElement {
constructor() {
self = super();
let shadow = this.attachShadow({
mode: 'open'
});
// 文本内容移动到shadow dom元素中
let style = document.createElement('style');
shadow.appendChild(style);
// 前后元素
let before = document.createElement('zxx-before');
let after = document.createElement('zxx-after');
shadow.prepend(after);
shadow.prepend(before);
// 内容
let content = document.createElement('div');
shadow.appendChild(content);
let ro = new ResizeObserver( entries => {
for (let entry of entries) {
self._updateRendering();
}
});
// 观察当前元素尺寸变化
ro.observe(this);
}
connectedCallback() {
// 执行渲染更新
this._updateRendering();
}
_updateRendering() {
// 根据变化的属性,改变组件的UI
let shadow = this.shadowRoot;
let content = shadow.querySelector('div');
let before = shadow.querySelector('zxx-before');
before.style.height = 'auto';
// 内容更新
content.innerHTML = this.innerHTML;
// 此时内容高度
let heightContent = parseFloat(getComputedStyle(content).height);
let heightBefore = parseFloat(getComputedStyle(before).height);
if (heightContent == 0) {
return;
}
// 没有设置具体的高度值
if (heightBefore == 0 && heightContent != 0) {
// 同样面积的椭圆的高度是?
// s = π×a×b
let height = (2 * heightContent * 2 / Math.PI) + 'px';
console.warn('<zxx-circle> no height, set it to ' + height + '!');
this.style.height = height;
}
before.removeAttribute('style');
// 样式设置
shadow.querySelector('style').textContent = `:host {
border-radius: 50%;
}
zxx-before,
zxx-after {
width: 50%; min-height: 100%; height: ${heightContent}px;
}
zxx-before {
float: left;
shape-outside: radial-gradient(farthest-side ellipse at right, transparent 100%, red);
}
zxx-after {
float: right;
shape-outside: radial-gradient(farthest-side ellipse at left, transparent 100%, red);
}`;
}
}
// 定义zxx-circle标签元素
customElements.define('zxx-circle', HTMLZxxCircleElement);