文本椭圆形布局演示
本帖最后由 马黑黑 于 2023-6-5 12:57 编辑 <br /><br /><style>.papa > p { margin: 10px 0; }
.mama { margin-left: 40px; position: relative; }
.hCode, .hLineNum { padding: 10px; width: calc(100% - 40px); font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; background: #f9f9f9; box-sizing: border-box; overflow-x: auto; tab-size: 3; position: absolute; }
.hCode { left: 40px; margin-left: -40px; padding-left: 45px; }
.hLineNum { width: 40px; background: #ccc; border-right: 1px solid #ccc; text-align: right; pointer-events: none; }
.stage { display: grid; place-items: center; }
.hidden { display: none; }
._red { color: red; }
</style>
<div class="papa">
<p>本例,每一个文本个体所在的 span 元素通过 offset-distance 设置自己在 offset-path 路径上的位置,具体定位的实现在 JS 里完成:</p>
<div class="mama">
<pre class="hCode"><style>
#wrapper {
width: 400px;
height: 200px;
margin: 20px auto;
position: relative;
border: 1px solid gray;
}
#wrapper > span {
display: block;
position: absolute;
width: 40px;
height: 40px;
text-align: center;
font: bold 20px / 40px sans-serif;
color: blue;
background: gray;
border-radius: 50%;
<span class="_red">offset-path</span>: path('M80 100 a120 80 0 1 0 240 0 a120 80 0 1 0 -240 0z');
<span class="_red">offset-rotate</span>: 0deg;
}
</style>
<div id="wrapper"></div>
<script>
let text_ar = '君不见黄河之水天上来'.split('');
text_ar.forEach( (item,key) => {
let sp = document.createElement('span');
sp.innerText = item;
sp.style.cssText += `
<span class="_red">offset-distance</span>: ${100 / text_ar.length * key}%;
`;
wrapper.appendChild(sp);
});
</script></pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>提示:offset-rotate 规定元素在 offset-path 上自身朝向的属性,默认值为 auto,随路径变化而自然改变自己的朝向。本例是文本布局,所以值设为 0,不调整朝向,永远躺平。</p>
</div>
<script>
let btns = document.querySelectorAll('.btnok'),
stages = document.querySelectorAll('.stage'),
hCodes = document.querySelectorAll('.hCode'),
hLineNums = document.querySelectorAll('.hLineNum'),
mamas = document.querySelectorAll('.mama');
hCodes.forEach((item,key) => {
let lines = hCodes.innerText.trim().split('\n').length;
let str = '';
for(let i = 0; i < lines; i ++) {
str += i + 1 + '\n';
}
hLineNums.innerText = str;
mamas.style.cssText += `height: ${hCodes.offsetHeight + 20}px`;
if(!btns) return;
btns.onclick = () => {
let val = btns.value;
val === '运行代码' ? codeRun(hCodes.innerText, stages) : codeRun('',stages);
btns.value = btns.innerText = val === '运行代码' ? '关闭运行' : '运行代码';
};
});
let codeRun = (str,ele) => {
let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
let js_str, html_str;
if(str.match(reg) !== null) {
js_str = str.match(reg);
html_str = str.replace(js_str, '').trim();
js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
} else {
js_str = '';
html_str = str.trim();
}
ele.innerHTML = html_str;
let myfunc = new Function(js_str);
myfunc();
};
</script>
沙发看天文{:4_173:} 给黑黑老师{:4_199:} 纯css加JS的椭圆形文字排布,真棒。{:4_187:} 椭圆上的圆圈其实css就做完了,关键是文字的加入。原来只要给出offset-distance 就能把文字一个个排布上去了呢{:4_187:} 感谢老师的分享,问好!{:4_190:} 梦缘 发表于 2023-6-5 15:24
感谢老师的分享,问好!
下午好 一斛珠 发表于 2023-6-5 13:26
沙发看天文
好看不 一斛珠 发表于 2023-6-5 13:26
给黑黑老师
谢鼓 红影 发表于 2023-6-5 13:58
纯css加JS的椭圆形文字排布,真棒。
还行吧?主要是演示一下原理 红影 发表于 2023-6-5 14:01
椭圆上的圆圈其实css就做完了,关键是文字的加入。原来只要给出offset-distance 就能把文字一个个排布上去 ...
offset-path路径中,offset-distance是定位元素,还有一个重要的值就是 offset-rotate,是否跟随路径旋转 文本位置的教程 南无月 发表于 2023-6-5 20:47
文本位置的教程
文本只是个示例,严格讲,这是元素沿 offset-path 定位 马黑黑 发表于 2023-6-5 18:05
还行吧?主要是演示一下原理
嗯嗯,通过这个知道怎么弄了{:4_187:} 马黑黑 发表于 2023-6-5 18:07
offset-path路径中,offset-distance是定位元素,还有一个重要的值就是 offset-rotate,是否跟随路径旋转
对对,除了定位了,还对旋转也做限制{:4_199:} 马黑黑 发表于 2023-6-5 21:18
文本只是个示例,严格讲,这是元素沿 offset-path 定位
那就是元素定位教程。 南无月 发表于 2023-6-6 18:30
那就是元素定位教程。
是演示 红影 发表于 2023-6-6 16:12
对对,除了定位了,还对旋转也做限制
必要的时候 红影 发表于 2023-6-6 16:11
嗯嗯,通过这个知道怎么弄了
不错 马黑黑 发表于 2023-6-6 19:15
是演示
那就是描红本儿