马黑黑 发表于 2024-11-18 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>

<div class="art">
        <h2>遮罩</h2>
        <p>指令:<mark>mask()</p>
        <p>参数:<mark>id, </mark></p>
        <p>语法:<mark>mask(id, )</mark></p>
        <p>参数说明</p>
        <blockquote>
                ① id - 必须,mask标签id标识符,字符型<br>
                ② x - 可选,mask遮罩层左上角X坐标,缺省默认 -10% 或 -0.1<br>
                ② y - 可选,mask遮罩层左上角Y坐标,缺省默认 -10% 或 -0.1<br>
                ③ width - 可选,mask遮罩层宽度,缺省默认 120% 或 1.2<br>
                ④ height - 可选,mask遮罩层高度,缺省默认 120% 或 1.2<br>
                * 值使用百分比表示时 svgdr 视之为字符型,例如,<mark>'120%'</mark><br>
                * mask位置、宽高缺省值应该是为了确保遮罩效果能够全覆盖被遮罩对象
        </blockquote>
        <p>mask是遮罩的载体,自身不具备遮罩能力,道理和 filter 元素只充当 fe* 滤镜的载体一样。欲要遮罩目标对象,需要一个实体元素作为遮罩层,比如圆、矩形、路径或图片等,在mask的规范下作用于目标对象。mask自身的位置、尺寸和其子元素即实体遮罩层的位置、尺寸需要彼此配合才能实现预设的遮罩效果。以下例子,灰色矩形是参照矩形,它上面有一个位置、尺寸规格完全一样但被遮罩的绿色矩形,而遮罩层也是一个矩形:</p>
        <div id="div1"><pre id="pre1">
dr.rect(20,20,200,100,'gray');
dr.mask('mask1');
dr.rect(20, 20, 100, 50, 'white').addTo('mask1');
dr.rect(20,20,200,100,'green').set('mask', 'url(#mask1)');
        </pre></div>
        <svg id="svg1" width="760" height="140"></svg>
        <p>本例,mask遮罩载体位置与尺寸默认,充当遮罩层的矩形位置和被遮罩矩形一样、宽高则是各为一半,结果,200*100的绿色矩形只呈现出 100*50 的效果,其尺寸其实就是宽高设为 100*50 的遮罩层矩形的尺寸。mask默认宽高都是120%,但前面提到过,它自身不具备遮罩能力,而是依靠子实体元素去具体实现遮罩,这个实体元素的形状、位置、尺寸和颜色都会具体作用于目标对象,当然也受限于mask自身的位置与尺寸,这一点将在以下例子展示:</p>
        <div id="div2"><pre id="pre2">
dr.rect(20,20,200,100,'gray');
dr.mask('mask3', 0.1, 0.1, 1, 1);
dr.rect(20, 20, 200, 100, 'white').addTo('mask3');
dr.rect(20,20,200,100,'green').set('mask', 'url(#mask3)');
        </pre></div>
        <svg id="svg2" width="760" height="140"></svg>
        <p>上例,遮罩层矩形位置、尺寸和被遮罩矩形的完全一致,但是,遮罩层载体 mask 标签设置了自己的位置和宽高:xy各是10%、宽高各为100%,它的设置要优先执行,子元素遮罩矩形只能按它的规范、再根据自己的实际设置去实现遮罩。可以设置修改遮罩矩形的xy位置、宽高看看更多的遮罩效果以便加深对 mask 载体与其子元素遮罩实体的位置、尺寸间的关系)。最终效果如演示所示,左、上都被裁掉了各10%。</p>
        <p>很多官方资料都鲜有详细介绍用作遮罩层的实体元素的用色问题。事实上,这是一个重要课题:当遮罩层遮罩实体元素设置为黑色或透明色,则它所遮罩的目标区域将完全不可见,反之,如果是白色,则它所遮罩的目标区域以原形态可见。就是说,在SVG遮罩理念里头,<span class="tRed">黑色=完全透明</span>,<span class="tRed">白色=完全不透明</span>。下面的实例,我们使用全覆盖的方式遮罩目标对象,遮罩层矩形的颜色使用了粉色 pink,同时为了便于观察,底层参照用的矩形和前两例相比往右边挪了100个单位:</p>
        <div id="div3"><pre id="pre3">
dr.rect(120,20,200,100,'gray');
dr.mask('mask');
dr.rect(20, 20, 200, 100, 'pink').addTo('mask');
dr.rect(20,20,200,100,'green').set('mask', 'url(#mask)');
        </pre></div>
        <svg id="svg3" width="760" height="140"></svg>
        <p>现在我们可以看到,遮罩矩形的粉色作用于原本绿色的矩形后,绿色矩形呈现出来的完整区域不再是纯绿,而是带有一定透明度的绿色,所以其底下图层的颜色可以对它产生作用。原理就是,遮罩层的颜色不是纯黑也不是纯白,纯黑则完全透明、目标对象被遮罩的区域完全不可见,纯白则完全不透明、目标对象被遮罩的区域完全以原始形态展现。</p>
        <p>本节更多的篇幅用于揭示SVG遮罩,主要原因是SVG遮罩的特殊性极其明显并且异于CSS的相关规范。至于 mask() 指令,需要注意的是,① 参数的表达方式,使用浮点数表示 width、height 时是数值型,使用百分比时是字符型、需要使用引号;② 用作遮罩实体的元素需要使用 addTo() 指令将其纳入 mask 标签之内。</p>
        <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';

var dr1 = draw.dr('svg1');
dr1.rect(20,20,200,100,'gray');
dr1.mask('mask1');
dr1.rect(20, 20, 100, 50, 'white').addTo('mask1');
dr1.rect(20,20,200,100,'green').set('mask', 'url(#mask1)');

var dr2 = draw.dr('svg2');
dr2.rect(20,20,200,100,'gray');
dr2.mask('mask2', 0.1, 0.1, 1, 1);
dr2.rect(20, 20, 200, 100, 'white').addTo('mask2');
dr2.rect(20,20,200,100,'green').set('mask', 'url(#mask2)');

var dr3 = draw.dr('svg3');
dr3.rect(120,20,200,100,'gray');
dr3.mask('mask3');
dr3.rect(20, 20, 200, 100, 'pink').addTo('mask3');
dr3.rect(20,20,200,100,'green').set('mask', 'url(#mask3)');

hl.hl(div1, pre1);
hl.hl(div2, pre2);
hl.hl(div3, pre3);

</script>

梦江南 发表于 2024-11-18 09:01

谢谢老师辛苦,早上好!{:4_190:}

马黑黑 发表于 2024-11-18 12:54

mask应用实例:


Breath and Life - 音乐沙龙 - 花潮论坛 - Powered by Discuz!

小辣椒 发表于 2024-11-18 13:17

黑黑辛苦,教程 实例齐并,学习应该更容易理解了

红影 发表于 2024-11-18 17:52

设置遮罩两种方法,一种直接设置id标识符dr.mask('mask1');然后设置遮罩层载体尺寸dr.rect(20, 20, 200, 100, 'white').addTo('mask3');,这个用了白色,也就是完全不透明,最后做遮罩,这时的尺寸没用了,跟着前面设置的遮罩层载体跑。
还一种设置id标识符的同时设置位置和尺寸dr.mask('mask3', 0.1, 0.1, 1, 1);,接下来设置的载体尺寸和遮罩尺寸都没用了,全都跟着最前面这个跑。
谁先设置的谁有理呗,这个需要理解透呢{:4_173:}

红影 发表于 2024-11-18 17:55

最后那个例子没看懂,超出被遮罩的矩形的部分的绿色应该没有了,怎么还在?
这样的话使用默认的-0.1和1.2不是要大出来了么?

红影 发表于 2024-11-18 17:58

黑色或透明=完全透明,白色=完全不透明。
这个记得黑黑之前讲过的,其他颜色按照明暗变成半透明的。

红影 发表于 2024-11-18 17:58

黑黑辛苦了,学习了{:4_187:}

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

红影 发表于 2024-11-18 17:58
黑色或透明=完全透明,白色=完全不透明。
这个记得黑黑之前讲过的,其他颜色按照明暗变成半透明的。

理解正确

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

梦江南 发表于 2024-11-18 09:01
谢谢老师辛苦,早上好!

{:4_190:}

花飞飞 发表于 2024-11-18 19:54

这个跟滤镜一样看不着摸不到的遮罩还是很神奇的~~
显示图片的位置和透明度都由遮罩说了算,
图片加了它跟加了隐形药水一样。。
可以任意裁成形状。。

花飞飞 发表于 2024-11-18 19:57

马黑黑 发表于 2024-11-18 12:54
mask应用实例:




实例更高级啊。。透明度会变化,它会动。。{:4_173:}

马黑黑 发表于 2024-11-18 20:32

花飞飞 发表于 2024-11-18 19:57
实例更高级啊。。透明度会变化,它会动。。

{:4_181:}

马黑黑 发表于 2024-11-18 20:32

花飞飞 发表于 2024-11-18 19:54
这个跟滤镜一样看不着摸不到的遮罩还是很神奇的~~
显示图片的位置和透明度都由遮罩说了算,
图片加了它跟 ...

{:4_173:}

花飞飞 发表于 2024-11-19 18:55

马黑黑 发表于 2024-11-18 20:32


一天更比一天新,今天的实例线条也会动了。。厉害

花飞飞 发表于 2024-11-19 18:56

马黑黑 发表于 2024-11-18 20:32


秀秀气气的笑得好看

绿叶清舟 发表于 2024-11-19 20:30

这里的代码实例里都没找到啊

马黑黑 发表于 2024-11-19 20:41

绿叶清舟 发表于 2024-11-19 20:30
这里的代码实例里都没找到啊

你要找什么

绿叶清舟 发表于 2024-11-19 20:44

马黑黑 发表于 2024-11-19 20:41
你要找什么

找相同的语句{:4_173:},是不是因为形状不同

红影 发表于 2024-11-19 21:48

马黑黑 发表于 2024-11-18 18:03
理解正确

这个封装好,可以连带着前面的东西复习一下了{:4_187:}
页: [1] 2
查看完整版本: svgdr教程·遮罩