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"><pattern></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"><marker></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">
<svg id="mysvg" width="400" height="400"></svg>
<script type="module">
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');
</script>
</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> 那个标记好像黑黑之前刚讲过,还好点,对pattern 图案比较陌生。
“pattern标签,宽高各设为5%(将以此尺寸呈现在目标对象,行列各20个图案”
这句没懂,为什么这个尺寸呈现有20个图案,看那个菱形多边形长宽各20,在180半径的圆内应该有18个啊。 其实黑黑也讲解过pattern,回去看了看,pattern的长宽或者百分比,本身就决定了占外框的份额,也就是横向纵向的5%应该就是20个,然后把它里面画好的菱形通过 id 引用来对圆进行填充。{:4_187:} 最后这个实例也有趣,把pattern和marker里讲到的都用上了{:4_187:} 红影 发表于 2024-11-8 15:06
最后这个实例也有趣,把pattern和marker里讲到的都用上了
{:4_190:} 这个教程跟前面的比起来啃得有点费劲。。花了不少时间慢慢看,综合知识啊。。。 红影 发表于 2024-11-8 15:02
其实黑黑也讲解过pattern,回去看了看,pattern的长宽或者百分比,本身就决定了占外框的份额,也就是横向纵 ...
pattern是很令人困惑的。
patter标签里的 x,y,width,height 属性,当以百分比或浮点数表示时,是说它以什么样的比例去呈现。0.5 就是 5%,它是平铺的,那么,实际占位方向上,在目标对象上的最大宽度上它会绘制 20 个长度单位,在最大高度上也会绘制 20 个长度单位。 红影 发表于 2024-11-8 14:10
那个标记好像黑黑之前刚讲过,还好点,对pattern 图案比较陌生。
“pattern标签,宽高各设为5%(将以此尺寸 ...
看7#的解释 花飞飞 发表于 2024-11-8 19:48
这个教程跟前面的比起来啃得有点费劲。。花了不少时间慢慢看,综合知识啊。。。
pattern 相对比较难,marker 也有点复杂 马黑黑 发表于 2024-11-8 19:52
pattern 相对比较难,marker 也有点复杂
感觉到了,所以今天的小播含金量特别高。。 花飞飞 发表于 2024-11-8 20:12
感觉到了,所以今天的小播含金量特别高。。
一样一样的,都是三克拉 马黑黑 发表于 2024-11-8 21:14
一样一样的,都是三克拉
超级金刚钻{:4_170:} 马黑黑 发表于 2024-11-8 18:10
谢大咖{:4_187:} 马黑黑 发表于 2024-11-8 19:50
pattern是很令人困惑的。
patter标签里的 x,y,width,height 属性,当以百分比或浮点数表示时,是说 ...
我纠结过后,倒是明白了,前面把它内部的图形的大小混一起,其实pattern的宽高只是它自己在容器里的占比,和内部东西无关。 马黑黑 发表于 2024-11-8 19:51
看7#的解释
嗯嗯,现在弄懂了{:4_173:} 红影 发表于 2024-11-8 23:59
嗯嗯,现在弄懂了
应该不是特难的问题 红影 发表于 2024-11-8 23:58
我纠结过后,倒是明白了,前面把它内部的图形的大小混一起,其实pattern的宽高只是它自己在容器里的占比 ...
{:4_181:} 花飞飞 发表于 2024-11-8 22:46
超级金刚钻
这是地地道道的金贵了 马黑黑 发表于 2024-11-9 07:06
这是地地道道的金贵了
突然看到你这么多钱发点红包呗。{:4_170:} 花飞飞 发表于 2024-11-9 10:51
突然看到你这么多钱发点红包呗。
{:4_194:}
页:
[1]
2