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

Posted

技术标签:

【中文标题】Fabric.js 动态裁剪区域对图像和 SVG/形状的影响不同【英文标题】:Fabric.js dynamic clipping regions affecting images and SVG/shapes differently 【发布时间】:2016-05-03 21:15:15 【问题描述】:

我有一个 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();

【问题讨论】:

【参考方案1】:

您应该指定在缩放路径时发生这种情况。 偏移量来自于在计算 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
  

这就够了。

【讨论】:

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

以上是关于Fabric.js 动态裁剪区域对图像和 SVG/形状的影响不同的主要内容,如果未能解决你的问题,请参考以下文章

如何使用fabric js仅通过覆盖矩形打孔?

Fabric.js:裁剪图像后的选择框

使用fabric.js加载SVG中的错误图像大小

Fabric JS 2.4.1 ClipPath Crop 不适用于动态创建的矩形蒙版

裁剪 Sprite 与单个图像的 Fabric.js 效率

动态 svg 图标?