马黑黑 发表于 2024-11-10 08:35

svgdr教程·text文本

<style>
        .art > p { margin: 12px 0; font: normal 18px/24px sans-serif; }
        .art mark { padding: 2px 6px; background: lightblue; }
        .art svg { outline: 1px solid silver; }
        .tRed { color: red; }
</style>

<div class="art">
        <h2>text文本、tspan子文本、textPath文本路径</h2>
        <p><strong>一、text 文本</strong></p>
        <p>指令:<mark>text()</mark>
        <p>参数:<mark>text, x, y, fill</mark>
        <p>语法:<mark>text(text, x, y, fill)</mark>
        <p><span class="tRed">&lt;text&gt;</span> 标签的属性其实很多,出于简化,svgdr 仅封装:</p>
        <blockquote>
                ① text - <span class="tRed">&lt;text&gt;</span> 标签要显示的文本,字符型<br>
                ② x - 文本起始点X坐标,数值<br>
                ③ y - 文本起始点Y坐标,数字<br>
                ④ fill - 文本填充色,字符型,缺省默认黑色
        </blockquote>
        <p>其它属性繁多,可通过 style() 和 set() 指令额外添加。这些未纳入 text() 指令的属性,有基于描边的 stroke、stroke-width、stroke-dasharray、stroke-dashoffset,基于文本间距的 letter-spacing、word-spacing,基于字体的 font-family、font-size、font-weight,基于文本对齐的 text-anchor、dominant-baseline 等等等等,要了解更多,可以参阅 <a href="http://mhh.52qingyin.cn/api/svgdr/" target="_blank">svgdr文档</a> 文本章节和text()指令的介绍,也应该查阅其它更详细的资料。</p>
        <p>看实例来理解 text() 指令的用法:</p>
        <svg id="svg1" width="800" height="400"></svg>
        <p>svgdr绘制代码:</p>
        <div id="div1"><pre id="pre1">
//普通输出文本 :注意x、y的设置
dr1.text('天时地利与人和', 20, 30);
//文本着色、用 set() 指令设置字号
dr1.text('天时地利与人和', 20, 120, 'purple').set('font-size', 60);
//使用 style() 指令设置更多的属性
dr1.text('天时地利与人和', 20, 220).style('font-size: 60; fill: purple; stroke: red;');
//更多的属性设置 : dx、dy 未纳入CSS管理范畴
dr1.text('天时地利与人和', 20, 320).style('font-size: 60; fill: none; stroke: red; stroke-width: 2; stroke-dasharray: 2;').set('dx','100');
//垂直文本
dr1.text('天时地利与人和', 650, 20).set('font-size', 50).style('writing-mode: tb');
        </pre></div>
        <p>生成的SVG代码:</p>
        <div id="div2"><pre id="pre2"></pre></div>
        <p>text标签没有换行功能,如果需要分行,分多少行就得设计多少个text标签。为了更方便换行,也为了能有更灵活的实现文本布局,svg提供了text元素的子元素——</p>
        <p><strong>二、tspan子文本</strong></p>
        <p>指令:<mark>tspan()</mark>
        <p>参数:<mark>str, x, y, dx, dy, style</mark>
        <p>语法:<mark>tspan(str, x, y, dx, dy, style)</mark>
        <p><span class="tRed">tspan</span> 是 text 的子元素,和HTML的span同理但比span更强大,可以独立设置其所管辖的文本。指令的参数中:</p>
        <blockquote>
                ① str - 要在tspan中输出的文本,字符型<br>
                ② x - 文本起始点X坐标,数值<br>
                ③ y - 文本起始点Y坐标,数值<br>
                ④ dx - 文本水平方向偏移值,数值<br>
                ⑤ dy - 文本垂直方向偏移值,数值<br>
                ⑥ style - 内联CSS样式表中<br>
                * <span class="tRed">tspan()</span> 指令可以链接在 <span class="tRed">text()</span> 指令之后,也可以在 text() 指令写完后另起一行用 dr.tspan() 完成自己的工作。
        </blockquote>
        <p>以下示例,svgdr 展示了如何在text标签内使用tspan子标签实现一首小诗的分行输出,里面的技巧只是改变一下span()指令的参数y;</p>

        <svg id="svg2" width="800" height="200"></svg>
        <p>svgdr 绘制代码:</p>
        <div id="div3"><pre id="pre3">
var strAr = ['蜀魄关关花雨深,', '送师冲雨到江浔。', '不能更折江头柳,', '自有青青松柏心。'];
dr.text().style('fill: blue; font-size: 30px');
strAr.forEach( (s,k) => dr.tspan(strAr, 20, k * 40 + 40) );
        </pre></div>
        <p>对应的SVG XML代码:</p>
        <div id="div4"><pre id="pre4"></pre></div>
        <p><strong>三、textPath 文本路径</strong></p>
        <p>指令:<mark>textPath()</mark>
        <p>参数:<mark>pathId, </mark>
        <p>语法:<mark>textPath(pathId, )</mark>
        <p>svg制作的是矢量图形,对文本的处理不能只限于非横即竖的布局,textPath元素就是用于帮助text标签完成文本按路径排列的功能。svgdr的 <span class="tRed">textPath() </span>指令收纳两个参数:</p>
        <blockquote>
                ① pathId - 必须参数,textPath标签的id标识符,字符型<br>
                ② offset - 可选参数,设置文本偏离路径起点的距离,数值<br>
                * svgdr未收入的其他参数可以通过set()、style() 等指令补充<br>
                * <span class="tRed">textPath()</span> 指令可以链式使用在 <span class="tRed">text()</span> 指令之后,也可以写完 text() 指令后另起一行用 dr.textPath() 完成自己的工作。
        </blockquote>
        <p>下面的示例,演示text文本沿弧线路径的布局效果:</p>
        <svg id="svg3" width="800" height="300"></svg>
        <p>svgdr绘制代码:</p>
        <div id="div5"><pre id="pre5">
//声明待输出字串
var tstr = '邻邑谷不登,我土丰粢盛。禾稼美如云,实系我使君。';
//创建一个可见路径,给它加个id便于引用
dr.path('M60 60 A280 200, 0 0 0, 760 60', 'none', 'lightblue').id('path1');
//创建text标签,用 style() 指令设置样式,text-anchor: middle 配合文本路径的 offset 50% 可以确保文本在路径上水平居中,dominant-baseline: middle 使得文本在路径上垂直居中
dr.text(tstr).style('fill: darkred; font-size: 30px; font-weight: bold; text-anchor: middle; dominant-baseline: middle;').textPath('path1','50%');
        </pre></div>
        <p>svgdr生成的SVG代码:</p>
        <div id="div6"><pre id="pre6"></pre></div>
        <p>本节介绍了text文本、tspan子文本、textPath路径文本在 svgdr 中的简单使用,它们涉及到的SVG文本知识与技巧只是冰山一角,要全面了解SVG文本,需要自己充电。</p>
        <p><a href="/forum.php?mod=viewthread&tid=79137&extra=page%3D1" targete="_blank">返回目录</a></p>
</div>

<script type="module">
import hl from 'https://638183.freep.cn/638183/web/mod/helight.js';
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';

var dr1 = draw.dr('svg1');
dr1.text('天时地利与人和', 20, 30);
dr1.text('天时地利与人和', 20, 120, 'purple').set('font-size', 60);
dr1.text('天时地利与人和', 20, 220).style('font-size: 60; fill: purple; stroke: red;');
dr1.text('天时地利与人和', 20, 320).style('font-size: 60; fill: none; stroke: red; stroke-width: 2; stroke-dasharray: 2;').set('dx','100');
dr1.text('天时地利与人和', 650, 20).set('font-size', 50).style('writing-mode: tb');
pre2.textContent = dr1.code(svg1);

var dr2 = draw.dr('svg2');
var strAr = ['蜀魄关关花雨深,', '送师冲雨到江浔。', '不能更折江头柳,', '自有青青松柏心。'];
dr2.text().style('fill: blue; font-size: 30px');
strAr.forEach( (s,k) => dr2.tspan(strAr, 20, k * 40 + 40) );
pre4.textContent = dr2.code('svg2');

var dr3 = draw.dr('svg3');
var tstr = '邻邑谷不登,我土丰粢盛。禾稼美如云,实系我使君。';
dr3.path('M60 60 A280 160, 0 0 0, 760 60', 'none', 'lightblue').id('path1');
dr3.text(tstr).style('fill: darkred; font-size: 30px; font-weight: bold; text-anchor: middle; dominant-baseline: middle;').textPath('path1','50%');
pre6.textContent = dr3.code(svg3);

hl.hl(div1, pre1);
hl.hl(div2, pre2);
hl.hl(div3, pre3);
hl.hl(div4, pre4);
hl.hl(div5, pre5);
hl.hl(div6, pre6);

</script>

梦江南 发表于 2024-11-10 09:37

谢谢老师详细讲解svgdr教程·text文本。辛苦了!{:4_190:}

泡沫 发表于 2024-11-10 09:44

前两部分对比,感觉tspan子文本比text文本更灵活更高级呢,反而叫子文本。。
不过这个换行,把y值改一下,看代码跟前面text文本换行做法一样呗。。
还要研究一下区别到底在哪里。

泡沫 发表于 2024-11-10 09:46

路径文本中的水平居中和垂直居中很新奇,试了一下效果
有了它们,文字在路径上的排列方式更灵活,更美观。。{:4_190:}

红影 发表于 2024-11-10 09:53

这个文字竖排有点陌生,记得是vertical-rl或者vertical-lr的,这里是tb。去搜了一下,两个都行,tb是垂直文本的意思,默认从右到左。

红影 发表于 2024-11-10 10:00

set('font-size', 60)和style('font-size: 60;)这两个的写法不同,也需要记一下。

红影 发表于 2024-11-10 10:02

“svgdr 展示了如何在text标签内使用tspan子标签实现一首小诗的分行输出,里面的技巧只是改变一下span()指令的参数y;”
到文字的环节了,是玩诗词的人最想要看到的内容,@樵歌 记得师兄对这些特别感兴趣,赶紧来学习啊{:4_173:}

红影 发表于 2024-11-10 10:13

在路径文本中的text-anchor: middle 和dominant-baseline: middle 挺重要,可以分别让文字在水平和垂直方向居中呢。在水平居中里,还要再设置offset 50% 啊,这个没想到。而且在svgdr 代码中直接textPath('path1','50%')在svg中startOffset="50%",嗯,这个要记记。

红影 发表于 2024-11-10 10:13

感谢黑黑的详细讲解,学习了{:4_187:}

醉美水芙蓉 发表于 2024-11-10 11:34

马黑黑 发表于 2024-11-10 11:38

红影 发表于 2024-11-10 10:13
在路径文本中的text-anchor: middle 和dominant-baseline: middle 挺重要,可以分别让文字在水平和垂直方向 ...

textPath 路径的 offset 属性是文本在路径上什么地方开始,默认是在 0% 即路径起始的地方

马黑黑 发表于 2024-11-10 11:38

梦江南 发表于 2024-11-10 09:37
谢谢老师详细讲解svgdr教程·text文本。辛苦了!

{:4_190:}

马黑黑 发表于 2024-11-10 11:39

泡沫 发表于 2024-11-10 09:44
前两部分对比,感觉tspan子文本比text文本更灵活更高级呢,反而叫子文本。。
不过这个换行,把y值改一下, ...

区别就是一父一子,这是定性好的,不可逆转

马黑黑 发表于 2024-11-10 11:41

红影 发表于 2024-11-10 10:00
set('font-size', 60)和style('font-size: 60;)这两个的写法不同,也需要记一下。

指令 set() 是设置单个属性,需要两个参数:属性名称、属性值

指令 style() 是按照 CSS 的 style 方式设置多个属性,注意,是按照 CSS 的方式书写键值对代码;

红影 发表于 2024-11-10 13:43

马黑黑 发表于 2024-11-10 11:38
textPath 路径的 offset 属性是文本在路径上什么地方开始,默认是在 0% 即路径起始的地方

嗯嗯,所以要想在路径上居中,还要再设置一下{:4_187:}

红影 发表于 2024-11-10 13:43

马黑黑 发表于 2024-11-10 11:41
指令 set() 是设置单个属性,需要两个参数:属性名称、属性值

指令 style() 是按照 CSS 的 style 方式 ...

在这个帖子的对比中,看得更清楚了。

马黑黑 发表于 2024-11-10 16:16

红影 发表于 2024-11-10 13:43
在这个帖子的对比中,看得更清楚了。

有些东东看一眼便知

马黑黑 发表于 2024-11-10 16:17

红影 发表于 2024-11-10 13:43
嗯嗯,所以要想在路径上居中,还要再设置一下

是这么回事

泡沫 发表于 2024-11-10 19:13

马黑黑 发表于 2024-11-10 11:39
区别就是一父一子,这是定性好的,不可逆转

青出于蓝而胜于蓝的节奏{:4_173:}

马黑黑 发表于 2024-11-10 21:03

泡沫 发表于 2024-11-10 19:13
青出于蓝而胜于蓝的节奏

没有呀,tspan是辅助作用的,这和 span 标签一样
页: [1] 2
查看完整版本: svgdr教程·text文本