【问题标题】:Clip object to path drawn using free drawing brush将对象剪辑到使用免费画笔绘制的路径
【发布时间】:2019-02-18 08:49:16
【问题描述】:

Fabric.js 2.3.6

我正在尝试将对象剪辑到使用免费绘图灌木绘制的路径上。代码无法在路径内显示图像,我不确定我做错了什么。

可以剪切多个对象,因此我无法将路径应用于画布本身。

let image = new Image();
let object;
let canvas;

// canvas

canvas = new fabric.Canvas("canvas", {
  backgroundColor: "lightgray",
  width: 1280,
  height: 720,
  preserveObjectStacking: true,
  selection: false
});

canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "black";
canvas.freeDrawingBrush.width = 2;

canvas.on("path:created", function(options) {
   clip(options.path);
});

// clip

function clip(path) {

  object.set({
    clipTo: function(ctx) {
      path.render(ctx);
    }
  });

  canvas.requestRenderAll();

}

// image

image.onload = function() {

  object = new fabric.Image(image, {
    width: 500,
    height: 500,
    top: 50,
    left: 50
  });

  canvas.add(object);

};

image.src = "http://i.imgur.com/8rmMZI3.jpg";

https://jsfiddle.net/o91rv38q/7/

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    为了在绘制路径时在同一位置进行剪辑,您需要将 pathOffset 重置为 SVG 路径,并将 setTransform 重置为 ctx。您的剪辑功能将如下所示:

    function clip(path) {
        path.set({pathOffset: {x: 0, y: 0}});
      object.set({
        clipTo: function(ctx) {
            ctx.save();    
          ctx.setTransform(1,0,0,1,0,0);
            ctx.beginPath();
            path._renderPathCommands(ctx);
            ctx.restore();
        }
      });
    
      canvas.requestRenderAll();
    
    }
    

    _renderPathCommands - 渲染路径。

    更新fiddle

    要剪辑多个对象,您需要有某种对象数组,然后组合成单个 path

    function combinePaths (paths) {
      if (!paths.length) {
        return null;
      }
        let singlePath = paths[0].path;
      for (let i = 1; i < paths.length; i++){
            singlePath = [...singlePath, ...paths[i].path];
      } 
      return new fabric.Path(singlePath, {
        top: 0,
        left: 0,
        pathOffset: {
            x: 0,
          y: 0
        }
      });
    }
    

    这是一个包含多个剪辑路径的示例:

    // canvas
    
    let canvas = new fabric.Canvas("canvas", {
        backgroundColor: "lightgray",
        width: 1280,
        height: 720,
        preserveObjectStacking: true,
        selection: false
    });
    
    let paths = [];
    
    canvas.isDrawingMode = true;
    canvas.freeDrawingBrush.color = "black";
    canvas.freeDrawingBrush.width = 2;
    
    canvas.on("path:created", function (options) {
        paths.push(options.path);
        clip(combinePaths(paths));
    });
    
    function combinePaths(paths) {
        if (!paths.length) {
            return null;
        }
        let singlePath = paths[0].path;
        for (let i = 1; i < paths.length; i++) {
            singlePath = [...singlePath, ...paths[i].path];
        }
        return new fabric.Path(singlePath, {
            top: 0,
            left: 0,
            pathOffset: {
                x: 0,
                y: 0
            }
        });
    }
    
    function clip(path) {
        if (!path) {
            return;
        }
        object.set({
            clipTo: function (ctx) {
                var retina = this.canvas.getRetinaScaling();
                ctx.save();
                ctx.setTransform(retina, 0, 0, retina, 0, 0);
                ctx.beginPath();
                path._renderPathCommands(ctx);
                ctx.restore();
            }
        });
    
        canvas.requestRenderAll();
    
    }
    
    // image
    
    let image = new Image();
    let object;
    
    image.onload = function () {
    
        object = new fabric.Image(image, {
            width: 500,
            height: 500,
            top: 50,
            left: 50
        });
        object.globalCompositeOperation = 'source-atop';
        canvas.add(object);
    
    };
    
    image.src = "http://i.imgur.com/8rmMZI3.jpg";
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.js"></script>
    <canvas id="canvas" width="1280" height="720"></canvas>

    【讨论】:

    • 在你的小提琴中你添加了options.path.set({top: 0});那是什么目的?
    • 这是我的测试。我忘了删除它。我更新了一个小提琴。
    • 它不工作。面罩未正确放置。你知道为什么吗?
    • 在您的原始代码中,它也位于不同的位置。
    • 没问题。这是一次很好的体验。
    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多