马黑黑 发表于 2024-11-8 08:03

svgdr教程·装饰标签

<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>

<h2>装饰标签·pattern 和 marker</h2>
<div class="art">
        <p><strong>一、pattern 图案</strong></p>
        <p>指令:<mark>pattern()</mark></p>
        <p>参数:<mark>id, x, y, width, height</mark></p>
        <p>语法:<mark>pattern(id, x, y, width, height)</mark></p>
        <p>其中:</p>
        <blockquote>
                ① id - <span class="tRed">&lt;pattern&gt;</span> 标签id标识符,实体元素引用它的依据,字符型<br>
                ② x - pattern图案 x 坐标值,缺省值0,可用长度数值表示,也可以百分比或对应浮点数表示<br>
                ③ y - pattern图案 y 坐标值,缺省值0,可用长度数值表示,也可以百分比或对应浮点数表示<br>
                ④ width - pattern图案宽度,可用长度数值表示,也可以百分比或对应浮点数表示<br>
                ⑤ height - pattern图案高度,可用长度数值表示,也可以百分比或对应浮点数表示<br>
                * <span class="tRed">patternUnits</span> - 用于定义x,y,宽度和高度属性,取值 <span class="tRed">objectBoundingBox</span>(默认)时表示 pattern 的 x、y、width和height的值都是占外框(包裹 pattern 的元素)的百分比,取值 <span class="tRed">userSpaceOnUse</span> 时表示 pattern 的 x、y、width和height表示的值都是当前用户坐标系统的值,这些值没有缩放,都是绝对值。<span class="tRed">patternUnits</span> 属性svgdr没有纳入 pattern() 指令参数,使用时可用 set('patternUnits', 'objectBoundingBox | userSpaceOnUse') 实现。<br>
                * pattern 可以拥有自己的 <span class="tRed">viewBox</span>,默认为 none
        </blockquote>
        <p>pattern 标签的创建,建议的做法是要加入 <span class="tRed">defs</span> 标签以防止其自己呈现,<span class="tRed">svgdr 的 pattern() 指令会自动将其置于defs内</span>。</p>
        <p>下面给出一个实例:创建 pattern 图案然后将图案通过 circle 的 fill 属性应用于一个圆:</p>
        <svg id="msvg1" width="800" height="400"></svg>
        <p>以上图案的 svgdr 绘制代码:</p>
        <div id="div1"><pre id="pre1">
//创建 id="pat" 的pattern标签,宽高各设为5%(将以此尺寸呈现在目标对象,行列各20个图案)
dr.pattern('pat', 0, 0, .05, .05);
//画个矩形充当图案,作为pattern的子元素
dr.polygon('10 0,20 10,10 20,0 10', 'plum').addTo('pat');
dr.circle(400, 200, 180, 'url(#pat)'); //用 fill 填充圆
        </pre></div>
        <p>上面绘制指令生成的SVG代码如下:</p>
        <div id="div2"><pre id="pre2"></pre></div>

        <p><strong>二、marker 标记</strong></p>
        <p>指令:<mark>marker()</mark></p>
        <p>参数:<mark>id, width, height, refX, refY, orient, viewBox, markerUnits</mark></p>
        <p>语法:<mark>marker(id, width, height, refX, refY, orient, viewBox, markerUnits)</mark></p>
        <blockquote>
                ① id - <span class="tRed">&lt;marker&gt;</span> 标签id标识符,字符型<br>
                ② width - marker标记的宽度,数值<br>
                ③ height - marker标记的高度,数值<br>
                ④ refX - marker标记在线头(段)上的x坐标,数值<br>
                ⑤ refY - marker标记在线头(段)上的y坐标,数值<br>
                ⑥ orient - marker标记的旋转方式,关键字值有 auto、auto-start-reverse(字符值),支持角度值(字符值或数值)<br>
                ⑦ viewBox - 定义maker标记视口,字符型<br>
                ⑧ markerUnits - 设置marker标记坐标系,字符型,值有 userSpaceOnUse 和 strokeWidth(缺省默认)
        </blockquote>

        <p>以下实例,先创建两个marker标记,然后分别应用于路径和折线:</p>
       
        <svg id="msvg2" width="800" height="400"></svg>
       
        <p>svgdr绘制代码:</p>
       
       
        <div id="div3"><pre id="pre3">
//marker的宽高依据其内装饰物尺寸设定,以下两个marker,其内元素宽高占位均为20,故宽高=20*20
//refX 和 refY 是装饰物与目标线段衔接数据,取值建议是宽高的一半
dr1.marker('m1', 20, 20, 10, 10); //m1
dr1.circle(10, 10, 10,'red').addTo('m1'); //圆做加入m1做标记装饰物
dr1.marker('m2', 20, 20, 10, 10, 'auto'); //m2 : orient保证三角顺着路径方向转向
dr1.polygon('0 0, 0 20 20 10', 'red').addTo('m2'); //三角形加入m2做标记装饰物
//二次贝塞尔曲线线头和线尾加标记
dr1.path('M20 20 Q200 300,400 20', 'none', 'green').style('marker-start: url(#m1); marker-end: url(#m2');
//加 T 的二次贝塞尔曲线加头尾、中间标记
dr1.path('M20 320 Q100 180,200 320 T400 320', 'none', 'green').style('marker-start: url(#m1); marker-mid: url(#m2); marker-end: url(#m2');
//折线应用标记 : 标记会根据线宽缩放
var pts = '300 200,500 200,600 30,700 120,700 370,600 370,380 280',
        style = 'marker-start: url(#m1); marker-mid: url(#m1); marker-end: url(#m2);';
dr1.polyline(pts, 'none', 'green', 2).style(style);
        </pre></div>
        <p>svgdr生成的XML代码:</p>
        <div id="div4"><pre id="pre4"></pre></div>
        <p>最后安利一个实例代码以结束本节。该实例创建一个pattern图案和一个maker标记,这两个装饰物最后都用到一个较大的多边形之上:</p>
        <div id="div5"><pre id="pre5">
&lt;svg id="mysvg" width="400" height="400"&gt;&lt;/svg&gt;

&lt;script type="module"&gt;
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';

var dr = _dr('mysvg');

dr.pattern('p1', 0, 0, 0.1, 0.1);
dr.circle(20, 20, 10,'thistle').addTo('p1');
dr.marker('m1', 10, 10, 5, 5).addTo('defs');
dr.circle(5, 5, 2.5, 'red').addTo('m1');

var tt = 8, r = 180, rad = 360 / tt * Math.PI / 180, dstr = '';

Array(tt).fill('').forEach((_, key) => {
        var x = 200 + r * Math.cos(rad * key), y = 200 + r * Math.sin(rad * key);
        dstr += key === tt - 1 ? `${x} ${y}` : `${x} ${y},`;
});
dr.polygon(dstr, 'url(#p1)', 'fuchsia', 8).style('marker-mid: url(#m1); marker-end: url(#m1); stroke-dasharray: 8');
&lt;/script&gt;
        </pre></div>
        <p>上面代码可以存为本地 .html 文档并使用浏览器打开,或将代码拿到 <a href="http://mhh.52qingyin.cn/api/pcode/">pencil code</a> 运行。</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 dr = draw.dr('msvg1');

dr.pattern('pat', 0, 0, .05, .05);
dr.polygon('10 0,20 10,10 20,0 10', 'plum').addTo('pat');
dr.circle(400, 200, 180, 'url(#pat)');
pre2.textContent = dr.code(msvg1);

var dr1 = draw.dr('msvg2');

dr1.marker('m1', 20, 20, 10, 10);
dr1.circle(10, 10, 10,'red').addTo('m1');
dr1.marker('m2', 20, 20, 10, 10, 'auto');
dr1.polygon('0 0, 0 20 20 10', 'red').addTo('m2');
dr1.path('M20 20 Q200 300,400 20', 'none', 'green').style('marker-start: url(#m1); marker-end: url(#m2');
dr1.path('M20 320 Q100 180,200 320 T400 320', 'none', 'green').style('marker-start: url(#m1); marker-mid: url(#m2); marker-end: url(#m2');
var pts = '300 200,500 200,600 30,700 120,700 370,600 370,380 280', style = 'marker-start: url(#m1); marker-mid: url(#m1); marker-end: url(#m2);';
dr1.polyline(pts, 'none', 'green', 2).style(style);
pre4.textContent = dr1.code(msvg2)

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

</script>

红影 发表于 2024-11-8 14:10

那个标记好像黑黑之前刚讲过,还好点,对pattern 图案比较陌生。
“pattern标签,宽高各设为5%(将以此尺寸呈现在目标对象,行列各20个图案”
这句没懂,为什么这个尺寸呈现有20个图案,看那个菱形多边形长宽各20,在180半径的圆内应该有18个啊。

红影 发表于 2024-11-8 15:02

其实黑黑也讲解过pattern,回去看了看,pattern的长宽或者百分比,本身就决定了占外框的份额,也就是横向纵向的5%应该就是20个,然后把它里面画好的菱形通过 id 引用来对圆进行填充。{:4_187:}

红影 发表于 2024-11-8 15:06

最后这个实例也有趣,把pattern和marker里讲到的都用上了{:4_187:}

马黑黑 发表于 2024-11-8 18:10

红影 发表于 2024-11-8 15:06
最后这个实例也有趣,把pattern和marker里讲到的都用上了

{:4_190:}

花飞飞 发表于 2024-11-8 19:48

这个教程跟前面的比起来啃得有点费劲。。花了不少时间慢慢看,综合知识啊。。。

马黑黑 发表于 2024-11-8 19:50

红影 发表于 2024-11-8 15:02
其实黑黑也讲解过pattern,回去看了看,pattern的长宽或者百分比,本身就决定了占外框的份额,也就是横向纵 ...

pattern是很令人困惑的。

patter标签里的 x,y,width,height 属性,当以百分比或浮点数表示时,是说它以什么样的比例去呈现。0.5 就是 5%,它是平铺的,那么,实际占位方向上,在目标对象上的最大宽度上它会绘制 20 个长度单位,在最大高度上也会绘制 20 个长度单位。

马黑黑 发表于 2024-11-8 19:51

红影 发表于 2024-11-8 14:10
那个标记好像黑黑之前刚讲过,还好点,对pattern 图案比较陌生。
“pattern标签,宽高各设为5%(将以此尺寸 ...

看7#的解释

马黑黑 发表于 2024-11-8 19:52

花飞飞 发表于 2024-11-8 19:48
这个教程跟前面的比起来啃得有点费劲。。花了不少时间慢慢看,综合知识啊。。。

pattern 相对比较难,marker 也有点复杂

花飞飞 发表于 2024-11-8 20:12

马黑黑 发表于 2024-11-8 19:52
pattern 相对比较难,marker 也有点复杂

感觉到了,所以今天的小播含金量特别高。。

马黑黑 发表于 2024-11-8 21:14

花飞飞 发表于 2024-11-8 20:12
感觉到了,所以今天的小播含金量特别高。。

一样一样的,都是三克拉

花飞飞 发表于 2024-11-8 22:46

马黑黑 发表于 2024-11-8 21:14
一样一样的,都是三克拉

超级金刚钻{:4_170:}

红影 发表于 2024-11-8 23:54

马黑黑 发表于 2024-11-8 18:10


谢大咖{:4_187:}

红影 发表于 2024-11-8 23:58

马黑黑 发表于 2024-11-8 19:50
pattern是很令人困惑的。

patter标签里的 x,y,width,height 属性,当以百分比或浮点数表示时,是说 ...

我纠结过后,倒是明白了,前面把它内部的图形的大小混一起,其实pattern的宽高只是它自己在容器里的占比,和内部东西无关。

红影 发表于 2024-11-8 23:59

马黑黑 发表于 2024-11-8 19:51
看7#的解释

嗯嗯,现在弄懂了{:4_173:}

马黑黑 发表于 2024-11-9 06:56

红影 发表于 2024-11-8 23:59
嗯嗯,现在弄懂了

应该不是特难的问题

马黑黑 发表于 2024-11-9 06:57

红影 发表于 2024-11-8 23:58
我纠结过后,倒是明白了,前面把它内部的图形的大小混一起,其实pattern的宽高只是它自己在容器里的占比 ...

{:4_181:}

马黑黑 发表于 2024-11-9 07:06

花飞飞 发表于 2024-11-8 22:46
超级金刚钻

这是地地道道的金贵了

花飞飞 发表于 2024-11-9 10:51

马黑黑 发表于 2024-11-9 07:06
这是地地道道的金贵了

突然看到你这么多钱发点红包呗。{:4_170:}

马黑黑 发表于 2024-11-9 11:03

花飞飞 发表于 2024-11-9 10:51
突然看到你这么多钱发点红包呗。

{:4_194:}
页: [1] 2
查看完整版本: svgdr教程·装饰标签