【问题标题】:Rotate, skew, scale and resize mask together with object与对象一起旋转、倾斜、缩放和调整蒙版
【发布时间】:2018-10-06 12:25:54
【问题描述】:

fabric.js 2.3.6

我正在尝试将应用于对象的任何转换复制到其上方的蒙版。

我已经能够随着对象移动蒙版,但应用于蒙版的任何转换都不起作用,例如mask.set({ angle: object.angle }).setCoords();

https://jsfiddle.net/30hj5xk2

谢谢。

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    请看这里:https://jsfiddle.net/o91rv38q/41/

        // canvas
    
    let canvas = new fabric.Canvas("canvas", {
      backgroundColor: "lightgray",
      width: 1280,
      height: 720,
      preserveObjectStacking: true,
      selection: false,
      stateful: true
    });
    
    canvas.isDrawingMode = true;
    canvas.freeDrawingBrush.color = "black";
    canvas.freeDrawingBrush.width = 2;
    
    canvas.on("path:created", function(options) {
       clip(options.path);
    });
    
    function clip(path) {
    
      canvas.isDrawingMode = false;
      canvas.remove(path);
    
      let mask = new fabric.Path(path.path, {
        top: object.top,
        left: object.left,
        objectCaching: false,
        strokeWidth:0,
        pathOffset: {
          x: 0,
          y: 0
        }
      });
    
      object.set({
        clipTo: function(ctx) {
    
            mask.set({ 
                            left: -object.width/2-mask.width/2, 
                            top: -object.height/2-mask.height/2,
                            objectCaching: false
                        });
                mask.render(ctx);
    
        }
      });
    
      this.canvas.requestRenderAll();
    
    }
    
    // image
    
    let image = new Image();
    let object;
    
    image.onload = function() {
    
      object = new fabric.Image(image, {
        width: 500,
        height: 500,
        top: 0,
        left: 0
      });
    
      canvas.add(object);
    
    };
    
    image.src = "http://i.imgur.com/8rmMZI3.jpg";
    

    更新 问题不在于画布的缩放。问题是您需要考虑object.leftobject.top,然后再将掩码放在object 上。我在您将mask 放在object 上之前保存,并用于减少mask.leftmask.top 在这里查看:http://jsfiddle.net/mariusturcu93/30hj5xk2/10/

    JS

    // canvas
    
    let canvas = new fabric.Canvas("canvas", {
      backgroundColor: "lightgray",
      width: 1280,
      height: 720,
      preserveObjectStacking: true,
      selection: false,
      stateful: true
    });
    
    canvas.isDrawingMode = true;
    canvas.freeDrawingBrush.color = "black";
    canvas.freeDrawingBrush.width = 2;
    
    window.addEventListener("resize", () => {
      resize();
    });
    
    canvas.on("path:created", function(options) {
       clip(options.path);
    });
    
    function resize() {
      let canvasWrapper = document.querySelector(".canvas__wrapper");
    
      let canvasWrapperWidth = canvasWrapper.offsetWidth;
      let canvasWrapperHeight = canvasWrapper.offsetHeight;
      let canvasWrapperRatio = canvasWrapperWidth / canvasWrapperHeight;
    
      let canvasZoom = canvas.getZoom();
      let canvasRatio = canvas.getWidth() / canvas.getHeight();
    
      let scale;
    
      if (canvasWrapperRatio < canvasRatio) {
        scale = canvasWrapperWidth / canvas.getWidth();
        canvasWrapperHeight = canvasWrapperWidth / canvasRatio;
      } else {
        scale = canvasWrapperHeight / canvas.getHeight();
        canvasWrapperWidth = canvasWrapperHeight * canvasRatio;
      }
    
      scale *= canvasZoom;
    
      canvas.setDimensions({
        width: canvasWrapperWidth,
        height: canvasWrapperHeight
      });
    
      canvas.setViewportTransform([scale, 0, 0, scale, 0, 0]);
      console.log(canvas.viewportTransform);
    }
    
    resize();
    
    function clip(path) {
    
      canvas.isDrawingMode = false;
      canvas.remove(path);
    
      let scale = canvas.getZoom();
    
      console.log(scale)
    
      let mask = new fabric.Path(path.path, {
        top: object.top,
        left: object.left,
        objectCaching: false,
        strokeWidth:0,
        pathOffset: {
          x: 0,
          y: 0
        }
      });
        var originalObjLeft = object.left,
      originalObjTop  = object.top;
      object.set({
        clipTo: function(ctx) {
    
            mask.set({ 
                            left: -object.width/2-mask.width/2-originalObjLeft, 
                            top: -object.height/2-mask.height/2-originalObjTop,
                            objectCaching: false
                        });
                mask.render(ctx);
    
        }
      });
    
      canvas.requestRenderAll();
    
    }
    
    // image
    
    let image = new Image();
    let object;
    
    image.onload = function() {
    
      object = new fabric.Image(image, {
        width: 500,
        height: 500,
        top: 20,
        left: 20
      });
    
      canvas.add(object);
    
    };
    
    image.src = "http://i.imgur.com/8rmMZI3.jpg";
    

    【讨论】:

    • 这可以正常工作,但我的画布包含一些缩放。我怎么能把它放回去?
    • 确定你想要什么。我在画布上放了 1.5 倍缩放,它仍然可以工作。在这里查看:jsfiddle.net/mariusturcu93/o91rv38q/46
    • @Marius Turcu,请为您的答案添加一些解释。出了什么问题,你解决了什么问题。
    • @MariusTurcu jsfiddle.net/30hj5xk2 看看这里。画布包含 viewportTransform,因此遮罩位置错误。
    • @MariusTurcu 问题实际上是包含任何转换的对象。如果对象被缩放,遮罩将被设置在错误的位置。我正在尝试修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2014-01-09
    • 2021-03-25
    • 1970-01-01
    相关资源
    最近更新 更多