Fabric.js动态剪切区域影响图像和SVG /形状的不同
问题描述:
我有一个Fabric.js画布,允许基于对象占据的区域进行动态剪裁。但是,裁剪区域对待SVG /形状的方式与图像不同,使它们略微偏移并“突破”裁剪区域。要重新创建:Fabric.js动态剪切区域影响图像和SVG /形状的不同
- 转到https://jsfiddle.net/mikewagz/hncqbhah/
- 拖动徽标剪切区域的边界 - 这正确剪辑,被修剪到任何地区的中心,占地不打破边界。
- 现在抓住一个形状并将其拖到剪辑区域。您可以在边界下方看到一小部分。
- 放大形状会加剧问题,显示裁剪区域下面的像素数量不断增加。请注意,它也会使顶部和左侧的剪辑区域向相同的方向偏移。
这又如何纠正?任何帮助非常感谢,谢谢!
代码裁剪功能:
var clipByName = function (ctx) {
this.setCoords();
var clipObj = findByClipName(this.clipName);
var scaleXTo1 = (1/this.scaleX);
var scaleYTo1 = (1/this.scaleY);
ctx.save();
var ctxLeft = -(this.width/2) + clipObj.strokeWidth;
var ctxTop = -(this.height/2) + clipObj.strokeWidth;
var ctxWidth = clipObj.width - clipObj.strokeWidth;
var ctxHeight = clipObj.height - clipObj.strokeWidth;
ctx.translate(ctxLeft, ctxTop);
ctx.scale(scaleXTo1, scaleYTo1);
ctx.rotate(degToRad(this.angle * -1));
ctx.beginPath();
var isPolygon = clipObj instanceof fabric.Polygon;
// polygon cliping area
if(isPolygon)
{
// prepare points of polygon
var points = [];
for(i in clipObj.points)
points.push({
x: (clipObj.left + clipObj.width/2) + clipObj.points[i].x - this.oCoords.tl.x,
y: (clipObj.top + clipObj.height/2) + clipObj.points[i].y - this.oCoords.tl.y
});
ctx.moveTo(points[0].x, points[0].y);
for(i=1; i<points.length; ++i)
{
ctx.lineTo(points[i].x, points[i].y);
}
ctx.lineTo(points[0].x, points[0].y);
}
// rectangle cliping area
else
{
ctx.rect(
clipObj.left - this.oCoords.tl.x,
clipObj.top - this.oCoords.tl.y,
clipObj.width,
clipObj.height
);
}
ctx.closePath();
ctx.restore();
}
答
应指定,出现这种情况时,路径缩放。 偏移来自使用strokeWidth计算ctxLeft和ctxTop。
这是不需要做大量的数学来绘制裁剪区域,并删除调用.setCoords()
和使用.oCoords
https://jsfiddle.net/hncqbhah/2/
var clipByName = function (ctx) {
var clipObj = findByClipName(this.clipName);
ctx.save();
ctx.setTransform(1,0,0,1,0,0);
ctx.beginPath();
var isPolygon = clipObj instanceof fabric.Polygon;
// polygon cliping area
if(isPolygon)
{
// prepare points of polygon
var points = [];
for(i in clipObj.points)
points.push({
x: (clipObj.left + clipObj.width/2) + clipObj.points[i].x ,
y: (clipObj.top + clipObj.height/2) + clipObj.points[i].y
});
ctx.moveTo(points[0].x, points[0].y);
for(i=1; i<points.length; ++i)
{
ctx.lineTo(points[i].x, points[i].y);
}
ctx.lineTo(points[0].x, points[0].y);
}
// rectangle cliping area
else
{
ctx.rect(
clipObj.left,
clipObj.top,
clipObj.width,
clipObj.height
);
}
ctx.closePath();
ctx.restore();
}
的需要一个简单的clipByName功能也绑定clipTo函数没有必要loDash:
obj.set({
clipName: 'clip2',
clipTo: clipByName
}
这就够了。
非常棒,非常感谢!应该注意到那些实现这一点的人,如果你正在做一个裁剪区域缩放的响应式画布,你应该在ctx.rect中使用“clipObj.width * clipObj.scaleX”和“clipObj.height * clipObj.scaleY” ()调用结束。 – mikewagz