- 快速入门
- Fabric.js 介绍
- Part 1:Objects 对象、Canvas 画布、Images 图像、Paths 形状
- Part 2:Animation 动画、Image filters 图像滤镜、Colors 颜色、Gradients 渐变、Text 文本、Events 事件
- Part 3:Groups 组合、Serialization 序列化、Deserialization、SVG parser 反序列化、SVG 解析器、Subclassing
- Part 4:Free drawing 自由绘画、Customization 可定制化、Fabric on Node.js
- Part 5:Zoom and panning 缩放和平移
- Part 6:Using transformations 使用转换
- Part 7:对 Text 类进行子分类以生成位图文本
- Part 8:裁切 和 ClipPath 裁切路径
- 自定义控件 API
- FabricJS 的缺陷
- Fabric.js 对象缓存
- Fabric.js 示例:自定义控件、多边形
- Fabric.js 示例:与画布外的对象交互
- API
- BaseBrush
- Canvas
- Circle
- CircleBrush
- Color
- Ellipse
- Gradient
- Group
- Image
- Intersection
- IText
- Line
- Object
- Observable
- Path
- PathGroup
- Pattern
- PatternBrush
- PencilBrush
- Point
- Polygon
- Polyline
- Rect
- Shadow
- SprayBrush
- StaticCanvas
- Text
- Triangle
Part 8:裁切 和 ClipPath 裁切路径
ClipPaths basics
The new clipPath property 新的 clipPath 属性
在 2.4.0 中,我们为所有对象引入了 clipPath 属性。 ClipPath 将替换 clipTo:funcion(){}
,以实现相同的灵活性,但具有更好的兼容性。
ClipPath 需要对象缓存。
How to use it 如何使用
将您自己的 clipPath 创建为普通的 Fabric 对象,并将其分配给您要裁剪的对象的 clipPath 属性。 根据 SVG 规范中的定义,clipPath 没有 stroke,并用黑色填充,与黑色像素重叠的对象的像素将是可见的,而其他像素则不可见。
让我们从一些基本示例开始,然后看看它的外观。 在此第一个示例中,红色的 rect 被一个圆圈夹住,只有圆形内的部分可见。虽然不是很有用,但是基本功能是这样的。
请注意:clipPath 从对象的中心开始定位,对象 originX 和 originY 不起任何作用,而 clipPath originX 和 originY 起作用。定位逻辑与 fabric.Group 相同。
<template>
<div class="groups">
<canvas id="canvas"></canvas>
</div>
</template>
<script>
import { fabric } from "fabric";
export default {
data() {
return {
canvas: "",
};
},
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 400,
height: 400,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Circle({
radius:40,
left:-40,
top:-40
})
var rect = new fabric.Rect({
width:200,
height:100,
fill:"red"
})
rect.clipPath = clipPath;
this.canvas.add(rect)
},
};
</script>
<style>
</style>
我们可以剪辑一个组:
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Circle({
radius:100,
top:-100,
left:-100
})
var group = new fabric.Group([
new fabric.Rect({width :100,height:100,fill:"red"}),
new fabric.Rect({width :100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width :100,height:100,fill:"blue",top:100}),
new fabric.Rect({width :100,height:100,fill:"green",left:100,top:100}),
]);
group.clipPath = clipPath;
this.canvas.add(group)
},
或者我们可以使用组进行剪辑。如果是组,请记住组中的每个对象在逻辑上或与其他对象成对,否则就不会有非零或奇数的裁剪规则。
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Group([
new fabric.Circle({radius:70,top:-70,left:-70}),
new fabric.Circle({radius:40,top:-95,left:-95}),
new fabric.Circle({radius:40,top:15,left:15}),
],{left:-95,top:-95})
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
group.clipPath = clipPath;
this.canvas.add(group);
},
More advanced use cases 更多高级用法
Nesting clipPaths 折叠 clipPaths
clipTo 和 canvas.clip()用法的一个问题是您一次最多只能有一个 clipPath。
通过此实现,clippaths 可以具有自己的剪切路径。尽管手动编程不太直观,但它允许将 clipPaths 与 gheter 相交。
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Circle({radius:70,top:-50,left:-50});
var innerClipPath = new fabric.Circle({radius:70,top:-90,left:-90});
clipPath.clipPath = innerClipPath;
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
group.clipPath = clipPath;
this.canvas.add(group)
},
组内对象中的 ClipPath 应与组本身的 clipPath 隔离:
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Circle({radius:100,top:-100,left:-100});
var small = new fabric.Circle({radius:50,top:-50,left:-50})
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red",clipPath:small}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
group.clipPath = clipPath;
this.canvas.add(group)
},
Clipping with Text
同样,使用 clipTo 也无法进行文本剪切,因此开发人员通常不得不依靠这种模式。
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Text(
'Hi I\'m the \nnew ClipPath!\nI hope we\'ll\nbe friends',
{top:-100,left:-100}
);
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
group.clipPath = clipPath;
this.canvas.add(group)
},
Clipping the canvas 剪裁画布
我们可以像对对象一样将 clipPath 应用于 StaticCanvas。在这种情况下,clipPath 受缩放和平移的影响,与 Object.clipPath 相反,它位于左上角。
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
var clipPath = new fabric.Circle({radius:100,top:0,left:50})
this.canvas.clipPath = clipPath;
this.canvas.add(group)
},
与旧的 clipTo 函数一样,除非您将 canvas.controlsAboveOverlay 设置为 true,否则 clipPath 也是剪辑控件。
mounted() {
this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
this.canvas.controlsAboveOverlay = true;
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
])
var clipPath = new fabric.Circle({radius:100,top:0,left:50})
this.canvas.clipPath = clipPath;
this.canvas.add(group)
},
Animating the clipPaths
ClipPath 可以像其他任何对象一样设置动画。画布 clipPath 动画非常有效,而为 Object 动画时,每次都会使对象缓存无效。
mounted() {
var canvas = this.canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Rect({width:100,height:100,top:0,left:0})
this.canvas.controlsAboveOverlay = true;
function animateLeft(){
clipPath.animate({
left:200,
},{
duration:900,
onChange: canvas.requestRenderAll.bind(canvas),
onComplete:animateRight,
})
}
function animateRight(){
clipPath.animate({
left:0,
},{
duration:1200,
onChange:canvas.requestRenderAll.bind(canvas),
onComplete:animateLeft,
})
}
function animateDown(){
clipPath.animate({
top:100,
},{
duration:500,
onChange:canvas.requestRenderAll.bind(canvas),
onComplete:animateUp,
})
}
function animateUp(){
clipPath.animate({
top:0,
},{
duration:400,
onChange:canvas.requestRenderAll.bind(canvas),
onComplete:animateDown
})
}
var group = new fabric.Group([
new fabric.Rect({width:100,height:100,fill:"red"}),
new fabric.Rect({width:100,height:100,fill:"yellow",left:100}),
new fabric.Rect({width:100,height:100,fill:"blue",top:100}),
new fabric.Rect({width:100,height:100,fill:"green",left:100,top:100}),
],{
scale:1.5
})
animateLeft();
animateDown();
this.canvas.clipPath = clipPath;
this.canvas.add(group)
},
Clipping the objects with absolute clipPaths 使用绝对定位的 clipPaths 剪切对象
我们可以对一个对象应用 clipPath,指定它应该是绝对定位的。这意味着 clipPath 不是相对于对象的中心,而是仅仅定位在画布上。 物体将不会移动,而 clipPath 将保持稳定。效果是 clipPath 在画布上创建了一个形状,并且只允许它自己的对象出现在画布中。
mounted() {
var canvas = this.canvas = new fabric.Canvas("canvas", {
width: 500,
height: 500,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Rect({width:500,height:250,top:0,left:0,absolutePositioned:true})
var clipPath2 = new fabric.Rect({width:500,height:250,top:250,left:0,absolutePositioned:true})
fabric.Image.fromURL("http://fabricjs.com/assets/dragon.jpg",function(img){
img.clipPath = clipPath;
img.scaleToWidth(500);
canvas.add(img);
})
fabric.Image.fromURL("http://fabricjs.com/assets/dragon2.jpg",function(img){
img.clipPath =clipPath2;
img.scaleToWidth(500);
img.top = 250;
canvas.add(img)
})
},
Inverted clipPaths 颠倒的 clipPaths
我们还可以裁剪具有从 clipPath 定义的倒置形状的对象。 警告:如果创建一个组,则必须反转该组。反转组中用作 clipPath 的单个对象不会产生任何效果,因此不受支持。
您也可以使用单个对象的 globalCompositeOperation 获得很酷的效果,但是也不支持。
mounted() {
var canvas = this.canvas = new fabric.Canvas("canvas", {
width: 500,
height: 500,
backgroundColor: "#ddd",
});
var clipPath = new fabric.Circle({radius:100,top:-200,left:-200});
var clipPath2 = new fabric.Circle({radius:100,top:0,left:0})
var clipPath3 = new fabric.Circle({radius:100,top:0,left:-200})
var clipPath4 = new fabric.Circle({radius:100,top:-200,left:0})
var g = new fabric.Group([clipPath,clipPath2,clipPath3,clipPath4])
g.inverted = true;
fabric.Image.fromURL("http://fabricjs.com/assets/dragon.jpg",function(img){
img.clipPath = g;
img.scaleToWidth(500);
canvas.add(img);
})
},
不颠倒的效果 g.inverted = false
如下:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论