【问题标题】:Image clipTo Path with FabricJS使用 FabricJS 的图像剪辑到路径
【发布时间】:2014-10-12 00:40:19
【问题描述】:

我正在尝试使用路径剪辑图像,但似乎找不到任何帮助。

我找到了用矩形或圆形裁剪图像的示例,但似乎缺少路径示例。我还设法用路径剪辑了整个画布,但我想要的只是剪辑 1 张图像。任何帮助将不胜感激!

以下示例用于使用路径剪切画布。

var canvas = new fabric.Canvas('c');
    canvas.setDimensions({width:_winWidth,height:_winHeight});

    var path = new fabric.Path('M2.9,245h-5.8c-35.3,0-69.3-14.4-93.3-39.4c-23.3-24.3-35.2-56.4-33.7-90.4c1.8-40.1,21-68.9,39.6-91.8l2.2-2.8\
    c10.6-13,22.6-27.8,23.6-43.4c0.9-14.6-7.1-27.8-15-38.9c-14.5-20.3-31-43.3-31-74.5c-0.1-28,11.5-55.1,32.4-76.1\
    C-57.2-233.1-29.8-245-2.9-245h5.8c27,0,54.3,11.9,75.1,32.7c21,21,32.5,48,32.4,76C110.4-105,93.9-82,79.4-61.7\
    c-7.9,11.1-15.9,24.4-15,38.9c1,15.6,13,30.4,23.6,43.4l2.2,2.8c18.6,22.9,37.8,51.7,39.6,91.8c1.5,34-10.4,66.2-33.7,90.4\
    C72.2,230.6,38.2,245,2.9,245z');

    path.centeredScaling = true;
    path.scale(1);

    //path.selectable = true;
    path.originX = 'center';
    path.originY = 'center';
    path.set({ left: (_winWidth/2), top: (_winHeight/2)});


    fabric.Image.fromURL('../images/home/2.jpg', function(img) {
        img.selectable = false;
        img.scale(1.2);
        canvas.centerObject(img);
        canvas.add(img);
        canvas.clipTo = function (ctx) {
            path.render(ctx);
        }
        canvas.renderAll();
      });

【问题讨论】:

    标签: javascript canvas svg path fabricjs


    【解决方案1】:
    canvas = new fabric.Canvas('fabric', { selection: false });
    var path = new fabric.Path('M 272.70141,238.71731 \
        C 206.46141,238.71731 152.70146,292.4773 152.70146,358.71731  \
        C 152.70146,493.47282 288.63461,528.80461 381.26391,662.02535 \
        C 468.83815,529.62199 609.82641,489.17075 609.82641,358.71731 \
        C 609.82641,292.47731 556.06651,238.7173 489.82641,238.71731  \
        C 441.77851,238.71731 400.42481,267.08774 381.26391,307.90481 \
        C 362.10311,267.08773 320.74941,238.7173 272.70141,238.71731  \
        z ');    
    var scale = 100 / path.width;
    path.set({ left: 20, top: 0, scaleX: scale, scaleY: scale,  fill: 'red', });
    canvas.add(path);
    addPattern(path);
    canvas.renderAll();
    
    function addPattern(obj){
      fabric.util.loadImage('http://fabricjs.com/assets/pug_small.jpg', function (img) {
    
                    obj.fill = new fabric.Pattern({
                        source: img,
                        repeat: 'no-repeat'
                    }); 
                    canvas.renderAll();
        });
    }
    

    【讨论】:

    • 经过测试。按照 Edwin Toh 的要求完美运行。
    • 您应该在代码中添加一些解释、错误是什么以及您更正了什么
    • 感谢您提供此代码 sn-p,它可能会提供一些即时帮助。一个正确的解释would greatly improve 其教育价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有类似但不相同的问题的读者更有用。请edit您的答案添加解释,并说明适用的限制和假设。
    【解决方案2】:

    要剪辑单个图像,试试这个:-

    fabric.Image.fromURL('http://fabricjs.com/assets/pug_small.jpg', function(img) {
        img.scale(0.5).set({
          left: 100,
          top: 100,
          angle: -15,
          clipTo: function (ctx) {
              path.render(ctx);
          }
        });
        canvas.add(img).setActiveObject(img);
      });
    

    注意:我会改用var myPath = xxxx,因为“路径”太接近 SVG 的 path

    【讨论】:

    • 这是正确答案。我建议使用 path._render(ctx) 而不是 path.render() 以避免描边、填充和路径自己的 clipTo 函数出现问题。