svg : clipPath 裁剪
<style>.art { margin: auto; font-size: 20px; position: relative; }
.art > p { margin: 10px 0; }
</style>
<div class="art">
<p>SVG 的 <clipPath> 标签定义剪裁形状,其内包含svg实体元素或path路径,目标元素即被裁剪对象则通过 clip-path 属性以 url(#id) 的方式调用剪裁标签、达成剪裁效果。语句结构举例如下:</p>
<div id="dd"><pre id="pp">
<defs>
<clipPath id="clip">
<circle cx="150" cy="100" r="90" />
</clilpPath>
</defs>
<rect x="10" y="10" width="180" height="180" fill="lightblue" clip-path="url(#clip)" />
</pre></div>
<p>解释:clipPath标签一般放在defs标签内,也可以独立存在。上面的代码示例,clipPath内的实体元素是一个圆形图案,它的位置和尺寸和将被裁剪的对象息息相关,设计裁剪形状时要注意这一点;同时,用做裁剪形状的元素,可以不着色,着色也没有意义。后面的矩形,从尺寸上分析,中心与圆重合,宽高尺寸和圆的直径一致,这样,矩形通过 clip-path 属性调用了clipPath标签,矩形裁剪出来的将是一个圆。</p>
<p>下面我们通过实例来进一步理解 clipPath 标签的用法:我们用一个path路径图案——它实际上是一个竖状椭圆——做剪裁形状,去裁剪中心点重合、尺寸相符的图片——</p>
<p><svg id="svg1" width="400" height="400" style="outline: 1px solid gray;"></svg></p>
<p>代码:</p>
<div id="d1"><pre id="p1"></pre></div>
<p>svg的外边框包裹的本是图片的整体呈现,现在,由于 image 标签使用了 clip-path="url(#clip1)",图片只能按 clipPath 标签的路径(或形状)去呈现自己。</p>
<p>最后我们再来看一个例子,我们将在 clipPath 元素运行动画。以下效果,左边是裁剪后的最终样式,动画隶属于裁剪形状,即动画是 clipPath 元素的子元素运行的,换言之,这是一个动画形式的裁剪作品;右边是静态形式下裁剪形状(菱形)和被裁剪对象(圆)的同心圆叠加。</p>
<p><svg id="svg2" width="800" height="400"></svg></p>
<p>代码:</p>
<div id="d2"><pre id="p2"></pre></div>
<p>clipPath 还有一个 clipPathUnits 属性,用于定义坐标系,值有 userSpaceOnUse 和 objectBoundingBox,缺省值是 userSpaceOnUse,这里不做演示。</p>
</div>
<script type="module">
let sc = document.createElement('script');
sc.src = 'https://638183.freep.cn/638183/web/js/svgdr.js';
document.body.appendChild(sc);
import hlight from 'https://638183.freep.cn/638183/web/mod/helight.js';
sc.onload = () => {
hlight.hl(dd,pp);
var dr1 = _dr(svg1);
dr1.defs('defs1');
dr1.clipPath('clip1').addTo('defs1');
dr1.path('M50 200 A150 180 0 1 1 350 200 A150 180 0 1 1 50 200').addTo('clip1');
dr1.image('https://638183.freep.cn/638183/Pic/38/nb7.jpg', 0, 0, 400, 400).set('clip-path', 'url(#clip1)');
p1.textContent = dr1.code(dr1.svg);
hlight.hl(d1,p1);
var dr2 = _dr(svg2);
dr2.clipPath('rbus');
var points = '200 0, 400 200, 200 400, 0 200';
dr2.polygon(points).addTo('rbus');
dr2.animate('animateTransform', {
attributeName: 'transform',
type: 'rotate',
dur: '4s',
from: '0 200 200',
to: '360 200 200',
repeatCount: 'indefinite',
});
dr2.circle(200, 200, 160, 'lightblue').style('clip-path: url(#rbus)');
dr2.polygon(points, 'pink').transform('translate(400)');
dr2.circle(200, 200, 160, 'lightblue').transform('translate(400)');
p2.textContent = dr2.code(dr2.svg);
hlight.hl(d2,p2);
};
</script>
前面的两个都好理解,最后这个很奇特,裁掉超出圆的部分,剩下的是被圆覆盖的其他部分。 第一个例子里的<circle cx="150" cy="100" r="90" />要想矩形中心与圆重合,应该是cx="100"吧。 看最后的例子,裁剪形状可以超出部分被裁剪形状,剩下的形状很奇特。
如果全部超出,就只剩下被裁剪的形状加上裁剪颜色了{:4_173:} <svg id="svg11" width="400" height="400" style="outline: 1px solid gray;">
<defs id="hongying">
<clipPath id="clip11">
<path d="M100 200 A100 180 0 1 1 300 200 A120 180 0 1 1 100 200"></path>
</clipPath>
</defs>
<image href="https://638183.freep.cn/638183/Pic/38/nb7.jpg" x="0" y="0" width="400" height="400" clip-path="url(#clip11)"></image>
</svg>
好好玩啊,我想把那张图图裁得窄点,前面都弄对了,后面一次忘记改第二个A的rx值,结果成了葫芦{:4_173:} 红影 发表于 2024-10-30 22:22
您的裁剪图片我看到了,黑黑老师的截图没看到。不知是咋回事? 梦江南 发表于 2024-10-31 10:01
您的裁剪图片我看到了,黑黑老师的截图没看到。不知是咋回事?
我这里都能看到啊。我自己跟在帖子里的代码都很小心地改过名称,应该不会冲突主帖的啊{:4_203:} 这个今天看了一下,与PS里的剪贴蒙板作用相似~~
又更高级,因为它是活的,可以动。。{:4_173:} 花飞飞 发表于 2024-10-31 20:54
这个今天看了一下,与PS里的剪贴蒙板作用相似~~
又更高级,因为它是活的,可以动。。
嗯呐,clipPath内部成员因为是实体元素,所以支持动画 马黑黑 发表于 2024-10-31 21:12
嗯呐,clipPath内部成员因为是实体元素,所以支持动画
代码PS总之是要超过PS的。。{:4_173:}PS要加动态蒙板不知道要到哪个版本了。 花飞飞 发表于 2024-10-31 21:15
代码PS总之是要超过PS的。。PS要加动态蒙板不知道要到哪个版本了。
PS主攻方向不是酱紫,它无需这么处理问题。做动画,GIF是可以的 马黑黑 发表于 2024-10-31 21:16
PS主攻方向不是酱紫,它无需这么处理问题。做动画,GIF是可以的
你这么一说,感觉就是这个道理。。。的确主攻方向不一样。。虽然它也可能做到,但它估计不会去做 GIF并不能整出动态蒙板。。
保持裁剪形状,又能保持被剪图形的完整 南无月 发表于 2024-11-1 21:29
GIF并不能整出动态蒙板。。
保持裁剪形状,又能保持被剪图形的完整
各有各的实现机制 马黑黑 发表于 2024-11-1 22:10
各有各的实现机制
{:4_173:}各有所长,还是让专业的软件做专业的事 花飞飞 发表于 2024-11-2 19:30
各有所长,还是让专业的软件做专业的事
对对对
页:
[1]