svgdr教程·滤镜
本帖最后由 马黑黑 于 2024-11-16 20:44 编辑 <br /><br /><style>.art > p { margin: 12px 0; font: normal 18px/24px sans-serif; }
.art mark { padding: 2px 6px; background: lightblue; }
.art svg { outline: none; }
.tRed { color: red; }
</style>
<div class="art">
<h2>滤镜</h2>
<p><strong>一、滤镜指令 filter</strong></p>
<p>指令:<mark>filter()</mark>
<p>参数:<mark>(fId, fecode)</mark>
<p>语法:<mark>filter(fId, fecode)</mark> 或简写成 <mark>f(fId, fecode)</mark></p>
<p>参数解释:</p>
<blockquote>
① fId - 必须,所创建滤镜 filter 元素的id标识符,字符型<br>
② fecode - 必须,字符型,具体滤镜 <span class="tRed">HTML代码</span>,例如 :<mark><feOffset in="SourceGraphic" dx="5" dy="5" /></mark><br>
* 具体滤镜代码建议使用反引号<mark>``</mark>包裹,这样代码可以分行书写、代码内的小角引号可以正常使用,详见后面的示例代码
</blockquote>
<p><strong>二、使用滤镜指令 filterTo</strong></p>
<p>指令:<mark>filterTo()</mark></p>
<p>参数:<mark>id</mark></p>
<p>语法:<mark>filterTo(fId)</mark> 或简写为 <mark>f2(fId)</mark></p>
<p>参数解释:</p>
<blockquote>
fId 参数为事先使用 filter() 或 f() 指令创建的 filter 元素的id,必须,字符型<br>
* filterTo() 或 f2() 意为为当前所创建的实体元素(例如rect、circle)等添加前面所创建的 id="fId" 的 filter 滤镜
</blockquote>
<p>下面举例说明:代码示例中,先创建 id="f1" 的 filter 滤镜,具体滤镜是 feColorMatrix,接着绘制两张图片来源一致的图片,第一张图片原始输出,第二张图片使用 f1 滤镜修饰,代码和效果如下——</p>
<div id="div1"><pre id="pre1">
//f('f1', `...`); //简写也可以
dr.filter('f1', `
<feColorMatrix type="hueRotate" values="180" in="SourceGraphic" />
`);
dr.image('https://638183.freep.cn/638183/small/sunbirds.jpg')
dr.image('https://638183.freep.cn/638183/small/sunbirds.jpg', 160).filterTo('f1');
</pre></div>
<svg id="svg1" width="400" height="150"></svg>
<p>svgdr绘制指令生成的SVG代码:</p>
<div id="div2"><pre id="pre2"></pre></div>
<p><span class="tRed">feColorMatrix</span> 滤镜使用矩阵原理对目标对象进行颜色转换,<span class="tRed">type</span> 属性为转换类型,示例使用了业已存在的矩阵封装 hueRotate 即色相转换,可选值还有诸多个封装好的类型,另有一个自由度极高的 matrix 类型交由用户自己封装 4*5 的矩阵转换机制;<span class="tRed">values</span> 属性指转换类型的值,示例中设为180,即将图像颜色体系每一个像素的色相通过矩阵运算都加上180度;<span class="tRed">in</span> 属性是滤镜的作用对象,一般而言,常用到的值是 SourceGraphic(图像)或 SourceAlpha(alpha通道),示例使用前者,表示直接作用于目标图像即后面用 image() 指令绘制的第二张图片。更多的 feColorMatrix 滤镜知识可自行查阅。</p>
<p>svg滤镜数量并不太多,可用的滤镜加起来也就是二、三十个,常用的十来个。不过svg滤镜有一定的学习难度,掌握他们需要较多的学习成本,感兴趣的朋友可以量体裁衣,通过 <a href="https://www.runoob.com/svg/svg-filters-intro.html" target="_blank">简单教程·svg滤镜</a> 或其他资源逐一了解学习。以下是较为常见的20个svg滤镜:</p>
<blockquote>
feBlend - 混合滤镜<br>
feColorMatrix - 色彩矩阵变换滤镜<br>
feComponentTransfer 颜色通道转换函数滤镜 ?<br>
feComposite - 图像像素智能组合滤镜<br>
feConvolveMatrix - 矩阵卷积滤镜<br>
feDiffuseLighting - 光滤镜 :漫反射滤镜<br>
feDisplacementMap - 映射置换滤镜<br>
feDropShadow - 投影滤镜<br>
feFlood - 纯色填充滤镜<br>
feGaussianBlur - 高斯模糊滤镜<br>
feImage - 图像滤镜(获取外部图像作为滤镜源)<br>
feMerge - 叠加滤镜(将多个滤镜进行叠加)<br>
feMorphology - 生态学滤镜<br>
feOffset - 偏移滤镜<br>
feSpecularLighting 光滤镜 :镜面反射滤镜<br>
feTile - 填充矩形滤镜(类似于pattern)<br>
feTurbulence - 湍流滤镜<br>
feDistantLight - 光源滤镜 :距离光源<br>
fePointLight 光源滤镜 :点滤镜<br>
feSpotLight - 光源滤镜 :聚光灯光源
</blockquote>
<p>svgdr 没有封装创建具体滤镜 fe* 的指令,但可以使用 draw() 指令先创建 filter,再创建 fe* 滤镜并添加到 filter 中。下面以创建文本阴影为例加以说明:/p>
<div id="div3"><pre id="pre3">
dr.draw('filter', {id: 'f2'}); //创建 id="f2" 的filter标签
//创建 feDropShadow 滤镜
dr.draw('feDropShadow', {
dx: 2,
dy: 2,
stdDeviation: 4,
'flood-color': '#000',
'flood-opacity': .75
}).addTo('f2');
//绘制文本并应用 id="f2" 的滤镜
dr.text('Hello', 50, 120, 'red').style('font: bold 100px Arial, sans-serif').f2('f2');
</pre></div>
<p>效果如下:</p>
<svg id="svg2"></svg>
<p>上述效果的SVG代码:</p>
<div id="div4"><pre id="pre4"></pre></div>
<p><a href="/forum.php?mod=viewthread&tid=79137&extra=page%3D1" targete="_blank">返回目录</a></p>
<!--p><a href="/art/bshow.php?st=7&sd=7&art=mahei_1730435960" 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?v=0.54';
var dr1 = draw.dr('svg1');
dr1.f('f1', `
<feColorMatrix type="hueRotate" values="180" in="SourceGraphic" />
`);
dr1.image('https://638183.freep.cn/638183/small/sunbirds.jpg')
dr1.image('https://638183.freep.cn/638183/small/sunbirds.jpg', 160).f2('f1');
pre2.textContent = dr1.code(svg1);
var dr2 = draw.dr('svg2');
dr2.draw('filter', {id: 'f2'});
dr2.draw('feDropShadow', {
dx: 2,
dy: 2,
stdDeviation: 4,
'flood-color': '#000',
'flood-opacity': .75
}).addTo('f2');
dr2.text('Hello', 50, 120, 'red').style('font: bold 100px Arial, sans-serif').f2('f2');
pre4.textContent = dr2.code(svg2);
hl.hl(div1, pre1);
hl.hl(div2, pre2);
hl.hl(div3, pre3);
hl.hl(div4, pre4);
</script>
先创建 id="f1" 的 filter 滤镜,再filterTo('f1')添加到相应实体元素。。这个结构先理解再说。。
至于滤镜二、三十个常用滤镜样式,看单词结尾部分,能想起个大概。。
比如阴影,模糊,亮度对比度,颜色等,好象每一部分里又有更多种小项,需要慢慢熟悉。{:4_173:}
这个滤镜看着篇幅不大,内容很不少 文本添加阴影滤镜跟图片添加滤镜绘制代码有点区别。。SVG代码结构无二。{:4_173:} feBlend
feColorMatrix
feComponentTransfer
feComposite
feConvolveMatrix
feDiffuseLighting
feDisplacementMap
feDropShadow
feFlood
feGaussianBlur
feImage
feMerge
feMorphology
feOffset
feSpecularLighting
feTile
feTurbulence
feDistantLight
fePointLight
feSpotLight
认出来几个,多数不认得,
刚看到老师昨天的美女贴,里面介绍 ” feMorphology 滤镜被称为生态学滤镜“
小白申请中文对应翻译。。{:4_173:} 先知道一下svgdr的滤镜的简写,否则以后会迷糊:
也就是 滤镜指令中可以把filter('名称', `...`)简写为 f('名称', `...`)
滤镜使用中可以把filterTo('名称')简写为 f2('名称')
当然不简写也可以,这样理一下防止看到简写时迷糊{:4_173:}{:4_187:} “svg滤镜数量并不太多,可用的滤镜加起来也就是二、三十个,常用的十来个。”
这还不多啊,每一个里面还有分类呢。去搜了一下例子中用到的feColorMatrix,type也分hueRotate、saturate、luminanceToAlpha、matrix等,能弄明白一个都不容易呢,何况那么多个{:4_173:} 红影 发表于 2024-11-16 12:24
“svg滤镜数量并不太多,可用的滤镜加起来也就是二、三十个,常用的十来个。”
这还不多啊,每一个里面还 ...
滤镜是svg高级应用之一,对滤镜不熟悉的可能感觉很难,熟悉的瞧一眼就能在代码 中用上 红影 发表于 2024-11-16 12:16
先知道一下svgdr的滤镜的简写,否则以后会迷糊:
也就是 滤镜指令中可以把filter('名称', `...`)简写为 f( ...
svgdr 里有不少简写的指令,多数简写指令不带全写的,比如 w() 、h() 就没有对应的 width()、height() 泡沫 发表于 2024-11-16 11:47
先创建 id="f1" 的 filter 滤镜,再filterTo('f1')添加到相应实体元素。。这个结构先理解再说。。
这个不难理解吧? 泡沫 发表于 2024-11-16 11:50
至于滤镜二、三十个常用滤镜样式,看单词结尾部分,能想起个大概。。
比如阴影,模糊,亮度对比度,颜色等 ...
每一个滤镜作用不一样,所以,除了共通的属性,还有私有属性 泡沫 发表于 2024-11-16 12:15
feBlend
feColorMatrix
feComponentTransfer
这个需要整理一下:目前对应的中文滤镜名称没有多少个,老的w3c官网和简单教程里,也就给了一小半不到的名称 泡沫 发表于 2024-11-16 11:55
文本添加阴影滤镜跟图片添加滤镜绘制代码有点区别。。SVG代码结构无二。
其实这是通用的,例子中滤镜都可以用于图形和文本。
在svg,实现阴影的方法有很多种 来把分分加起{:4_199:} 樵歌 发表于 2024-11-16 13:15
来把分分加起
{:4_180:} 来听老师讲代码。辛苦了!{:4_190:} 这些还真的要记笔记才会记住的 小辣椒 发表于 2024-11-16 15:08
这些还真的要记笔记才会记住的
关键是滤镜比较难以理解 马黑黑 发表于 2024-11-16 12:38
这个不难理解吧?
嗯哪,毕竟先打了两个地基了都{:4_173:} 马黑黑 发表于 2024-11-16 12:39
每一个滤镜作用不一样,所以,除了共通的属性,还有私有属性
且私有属性也挺多,跟子分类一样