Fabric.js动态剪切区域影响图像和SVG /形状的不同

问题描述:

我有一个Fabric.js画布,允许基于对象占据的区域进行动态剪裁。但是,裁剪区域对待SVG /形状的方式与图像不同,使它们略微偏移并“突破”裁剪区域。要重新创建:Fabric.js动态剪切区域影响图像和SVG /形状的不同

  1. 转到https://jsfiddle.net/mikewagz/hncqbhah/
  2. 拖动徽标剪切区域的边界 - 这正确剪辑,被修剪到任何地区的中心,占地不打破边界。
  3. 现在抓住一个形状并将其拖到剪辑区域。您可以在边界下方看到一小部分。
  4. 放大形状会加剧问题,显示裁剪区域下面的像素数量不断增加。请注意,它也会使顶部和左侧的剪辑区域向相同的方向偏移。

enter image description here

这又如何纠正?任何帮助非常感谢,谢谢!

代码裁剪功能:

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 
    } 

这就够了。

+0

非常棒,非常感谢!应该注意到那些实现这一点的人,如果你正在做一个裁剪区域缩放的响应式画布,你应该在ctx.rect中使用“clipObj.width * clipObj.scaleX”和“clipObj.height * clipObj.scaleY” ()调用结束。 – mikewagz