马黑黑 发表于 2024-10-30 21:22

svg : clipPath 裁剪

<style>
        .art { margin: auto; font-size: 20px; position: relative; }
        .art > p { margin: 10px 0; }
</style>

<div class="art">
        <p>SVG 的 &lt;clipPath&gt; 标签定义剪裁形状,其内包含svg实体元素或path路径,目标元素即被裁剪对象则通过 clip-path 属性以 url(#id) 的方式调用剪裁标签、达成剪裁效果。语句结构举例如下:</p>
        <div id="dd"><pre id="pp">
&lt;defs&gt;
        &lt;clipPath id="clip"&gt;
                &lt;circle cx="150" cy="100" r="90" /&gt;
        &lt;/clilpPath&gt;
&lt;/defs&gt;
&lt;rect x="10" y="10" width="180" height="180" fill="lightblue" clip-path="url(#clip)" /&gt;
        </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>

红影 发表于 2024-10-30 22:04

前面的两个都好理解,最后这个很奇特,裁掉超出圆的部分,剩下的是被圆覆盖的其他部分。

红影 发表于 2024-10-30 22:10

第一个例子里的<circle cx="150" cy="100" r="90" />要想矩形中心与圆重合,应该是cx="100"吧。

红影 发表于 2024-10-30 22:13

看最后的例子,裁剪形状可以超出部分被裁剪形状,剩下的形状很奇特。
如果全部超出,就只剩下被裁剪的形状加上裁剪颜色了{:4_173:}

红影 发表于 2024-10-30 22:22

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

红影 发表于 2024-10-30 22:24

好好玩啊,我想把那张图图裁得窄点,前面都弄对了,后面一次忘记改第二个A的rx值,结果成了葫芦{:4_173:}

梦江南 发表于 2024-10-31 10:01

红影 发表于 2024-10-30 22:22


您的裁剪图片我看到了,黑黑老师的截图没看到。不知是咋回事?

红影 发表于 2024-10-31 14:40

梦江南 发表于 2024-10-31 10:01
您的裁剪图片我看到了,黑黑老师的截图没看到。不知是咋回事?

我这里都能看到啊。我自己跟在帖子里的代码都很小心地改过名称,应该不会冲突主帖的啊{:4_203:}

花飞飞 发表于 2024-10-31 20:54

这个今天看了一下,与PS里的剪贴蒙板作用相似~~
又更高级,因为它是活的,可以动。。{:4_173:}

马黑黑 发表于 2024-10-31 21:12

花飞飞 发表于 2024-10-31 20:54
这个今天看了一下,与PS里的剪贴蒙板作用相似~~
又更高级,因为它是活的,可以动。。

嗯呐,clipPath内部成员因为是实体元素,所以支持动画

花飞飞 发表于 2024-10-31 21:15

马黑黑 发表于 2024-10-31 21:12
嗯呐,clipPath内部成员因为是实体元素,所以支持动画

代码PS总之是要超过PS的。。{:4_173:}PS要加动态蒙板不知道要到哪个版本了。

马黑黑 发表于 2024-10-31 21:16

花飞飞 发表于 2024-10-31 21:15
代码PS总之是要超过PS的。。PS要加动态蒙板不知道要到哪个版本了。

PS主攻方向不是酱紫,它无需这么处理问题。做动画,GIF是可以的

花飞飞 发表于 2024-10-31 22:43

马黑黑 发表于 2024-10-31 21:16
PS主攻方向不是酱紫,它无需这么处理问题。做动画,GIF是可以的

你这么一说,感觉就是这个道理。。。的确主攻方向不一样。。虽然它也可能做到,但它估计不会去做

南无月 发表于 2024-11-1 21:29

GIF并不能整出动态蒙板。。
保持裁剪形状,又能保持被剪图形的完整

马黑黑 发表于 2024-11-1 22:10

南无月 发表于 2024-11-1 21:29
GIF并不能整出动态蒙板。。
保持裁剪形状,又能保持被剪图形的完整

各有各的实现机制

花飞飞 发表于 2024-11-2 19:30

马黑黑 发表于 2024-11-1 22:10
各有各的实现机制
{:4_173:}各有所长,还是让专业的软件做专业的事

马黑黑 发表于 2024-11-2 21:03

花飞飞 发表于 2024-11-2 19:30
各有所长,还是让专业的软件做专业的事

对对对
页: [1]
查看完整版本: svg : clipPath 裁剪