Fabric.js 影响图像的动态剪切区域和 SVG/shapes 不同
Fabric.js dynamic clipping regions affecting images and SVG/shapes differently
我有一个 Fabric.js canvas 允许根据对象占据的区域进行动态裁剪。但是,裁剪区域处理 SVG/shapes 与图像不同,使它们略微偏移并且 "breaking through" 裁剪区域。重新创建:
- 转到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();
}
您应该指定在缩放路径时发生这种情况。
偏移量来自在计算 ctxLeft 和 ctxTop 时使用 strokeWidth。
这是一个更简单的 clipByName 函数,不需要做很多数学运算来绘制剪辑区域,也不需要调用 .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();
}
也绑定 clipTo 功能,无需 io loDash:
obj.set({
clipName: 'clip2',
clipTo: clipByName
}
这就够了。
我有一个 Fabric.js canvas 允许根据对象占据的区域进行动态裁剪。但是,裁剪区域处理 SVG/shapes 与图像不同,使它们略微偏移并且 "breaking through" 裁剪区域。重新创建:
- 转到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();
}
您应该指定在缩放路径时发生这种情况。 偏移量来自在计算 ctxLeft 和 ctxTop 时使用 strokeWidth。
这是一个更简单的 clipByName 函数,不需要做很多数学运算来绘制剪辑区域,也不需要调用 .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();
}
也绑定 clipTo 功能,无需 io loDash:
obj.set({
clipName: 'clip2',
clipTo: clipByName
}
这就够了。