月是故乡明
<div class="codebox" data-prev="1"><svg id="msvg" width="800" height="400" viewBox="-200 -100 400 200"></svg>
<script type="module">
import Dr from 'https://638183.freep.cn/638183/svgdr/svgdr.mod.min.js';
var dr = Dr.dr('msvg');
const txt = '月是故乡明';
const path = 'M-150 92 A150 150 0 0 1 150 92';
dr.setsvg({style: 'background: #333;'});
dr.defs('defs');
dr.path(path, 'none', 'olive').id('tpath').addTo('defs');
dr.text(txt)
.style(`
font: bold 50px sans-serif;
fill: #fdb813;
stroke: #daa520;
stroke-width: 1;
text-anchor: middle;
dominant-baseline: middle;
`)
.sets({
textLength: 400,
lengthAdjust: 'spacing'
})
.textPath('tpath', '50%');
dr.circle(0, 40, 50, '#fdb813');
</script>
</div>
<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script> 本帖最后由 马黑黑 于 2025-10-6 13:09 编辑
本帖演示:svg文本在路径上均匀分布
svg文本设置相关知识点:
/**
CSS属性:
① text-anchor: middle; // 文本锚点,缺省或start从路径中间开始,end文本结束处在中间
② dominant-baseline: middle; // 垂直定位,缺省在路径上方、hanging在路径下方
非CSS属性:
① letter-spacing : 调节字符间距,针对单词间距应使用 word-spacing
② textLength : 文本长度,文本会根据此属性值自动调整间距。如果需要可以设置和路径一样的长度,路径长度可以使用语句 路径.getTotalLength() 获取
③ lengthAjust : 配合 textLength 属性设置文本变化规则,spacing 调整字符间距,spacingAndGlyphs 调整字宽
【注意】如果使用了 textLength 属性设置文本长度,letter-spacing 属性应缺省
**/
本例,通过文本的CSS基础设置,主要处理文本字体、水平方向对齐、垂直方向对齐、填充、描边等文本设置,再通过CSS text标签的属性 textLenth(文本长度)、lengthAjust(文本对齐规则)设置文本在路径上的排列行为,实现了文本在路径上均匀分布的效果。
核心:textLength 文本长度设置
主要是得事先知道路径的长度,可以使用JS语句 路径.getTotalLength() 获取,例如本例的路径 id="tpath",可以在控制台打印出它的长度:
console.log(tpath.getTotalLength());
然后根据需要设置文本 text 标签的属性 textLength,可以和路径长度一样,也可以略小一些。textLength 属性能将文本均匀分布于该距离。
至于 lengthAjust 属性,它是辅助性属性,配合 textLength 制定文本的排列行为,有两个值可选,spacing 和 spacingAndGlyphs,上面已经有说明。 我复制了代码预览了效果月亮很圆很大,文字也是大,效果不错,不敢发这里,怕代码冲突 小辣椒 发表于 2025-10-6 13:09
我复制了代码预览了效果月亮很圆很大,文字也是大,效果不错,不敢发这里,怕代码冲突
不会冲突 马黑黑 发表于 2025-10-6 13:10
不会冲突
不会啊,那我发这里看看
<svg id="msvg" width="800" height="400" viewBox="-200 -100 400 200"></svg>
<script type="module">
import Dr from 'https://638183.freep.cn/638183/svgdr/svgdr.mod.min.js';
var dr = Dr.dr('msvg');
const txt = '月是故乡明';
const path = 'M-150 92 A150 150 0 0 1 150 92';
dr.setsvg({style: 'background: #333;'});
dr.defs('defs');
dr.path(path, 'none', 'olive').id('tpath').addTo('defs');
dr.text(txt)
.style(`
font: bold 50px sans-serif;
fill: #fdb813;
stroke: #daa520;
stroke-width: 1;
text-anchor: middle;
dominant-baseline: middle;
`)
.sets({
textLength: 400,
lengthAdjust: 'spacing'
})
.textPath('tpath', '50%');
dr.circle(0, 40, 50, '#fdb813');
</script> 不行,不能发二个,一个不出来了 还要给出文本长度啊,还以为给出路径了,有路径长度,就直接自动去分配文字了呢。
学习了,感谢黑黑好帖{:4_199:} 红影 发表于 2025-10-6 14:39
还要给出文本长度啊,还以为给出路径了,有路径长度,就直接自动去分配文字了呢。
学习了,感谢黑黑好帖{: ...
如果不给文本长度,可以考虑 letter-spacing,设置恰当的值也是可以的。当需要文本基本占满路径,设置文本长度为路径长度然后配合其它设置的做法效果更佳 本帖最后由 马黑黑 于 2025-10-6 15:22 编辑
小辣椒 发表于 2025-10-6 13:38
不行,不能发二个,一个不出来了
里面涉及到 id 问题。HTML、XML元素的id是唯一的,同一页里只能有一个,否则冲突。前面我说不冲突指的是不和我的一楼产生冲突,因为一楼并没有直接运行代码,不存在 id="msvg"、id="tpath" 这几个 id 的真实元素。而你发了一个,就存在了,发第二个得相应修改 id(有多少个 id 就得修改多少个,除了前面提到的还有一个 id="defs",第二个你得修改为别的、且 addTo 语句得和修改的一样)。
id 是标签的唯一身份证,和你用身份证住酒店一个道理:假如你住进了404房间,别人的身份证就不能同时也登记入住了(除非是你实现安排好的约会,但那也不需要再登记的,偷偷入住就好{:4_189:})。 文G时,陈白达说:毛主席是最红最红的太阳,我是最黄最黄的月亮{:4_170:}后来,被造F派揪出来批判得够呛{:4_170:} 樵歌 发表于 2025-10-6 17:14
文G时,陈白达说:毛主席是最红最红的太阳,我是最黄最黄的月亮后来,被造F派揪出来批判得够呛{:4 ...
现在没关系了:金黄代表富丽堂皇,是至高荣耀。 马黑黑 发表于 2025-10-6 15:20
里面涉及到 id 问题。HTML、XML元素的id是唯一的,同一页里只能有一个,否则冲突。前面我说不冲突指的是 ...
还有一个修改了颜色,反正感觉也是蛮漂亮的 小辣椒 发表于 2025-10-6 20:36
还有一个修改了颜色,反正感觉也是蛮漂亮的
{:4_190:} 马黑黑 发表于 2025-10-6 17:48
现在没关系了:金黄代表富丽堂皇,是至高荣耀。
那个年代,啥都上纲上线,{:4_189:} 樵歌 发表于 2025-10-7 07:05
那个年代,啥都上纲上线,
民智尚未开启,很多荒唐的事情轻而易举推行
页:
[1]