【问题标题】:Fabric JS 2.4.1 ClipPath Crop Not Working with a Dynamically Created rect MaskFabric JS 2.4.1 ClipPath Crop 不适用于动态创建的矩形蒙版
【发布时间】:2019-03-07 18:54:23
【问题描述】:

我正在使用fabric js 2.4.1 制作一个编辑器,并且已经完成了除动态图像裁剪之外的所有功能。该功能包括用鼠标在图像上创建一个矩形并单击裁剪按钮。

我已经成功完成了一个矩形的概念验证,该矩形是静态创建的,但无法让它在我的动态代码中呈现。我认为问题与动态创建的矩形无关,但我似乎无法隔离问题。它必须是我忽略的一些简单的东西,我认为问题可能出在我的裁剪按钮代码中。

    document.getElementById("crop").addEventListener("click", function() {
        if (target !== null && mask !== null) {
            mask.setCoords();
            target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
            //target.selectable = true;
            target.setCoords();
            console.log(target);
            canvas.renderAll();
            //canvas.remove(mask);
        }
    });

这是有问题的动态代码的一个小提琴: https://jsfiddle.net/Larry_Robertson/mqrv5fnt/

这是我从中获得概念证明的静态代码的一个小技巧: https://jsfiddle.net/Larry_Robertson/f34q67op/

动态版源码:

HTML

<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
<button id="crop">Crop</button>

JS

    var canvas = new fabric.Canvas('c', {
        selection: true
    });

    var rect, isDown, origX, origY, done, object, mask, target;

    var src = "http://fabricjs.com/lib/pug.jpg";
    fabric.Image.fromURL(src, function(img) {
        img.selectable = false;
        img.id = 'image';
        object = img;
        canvas.add(img);
    });

    canvas.on('object:added', function(e) {
        target = null;
        mask = null;
        canvas.forEachObject(function(obj) {
            //alert(obj.get('id'));
            var id = obj.get('id');
            if (id === 'image') {
                target = obj;
            }
            if (id === 'mask') {
                //alert('mask');
                mask = obj;
            }
        });
    });

    document.getElementById("crop").addEventListener("click", function() {
        if (target !== null && mask !== null) {
            mask.setCoords();
            target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
            //target.selectable = true;
            target.setCoords();
            console.log(target);
            canvas.renderAll();
            //canvas.remove(mask);
        }
    });

    canvas.on('mouse:down', function(o) {
        if (done) {
            canvas.renderAll();
            return;
        }
        isDown = true;
        var pointer = canvas.getPointer(o.e);
        origX = pointer.x;
        origY = pointer.y;
        rect = new fabric.Rect({
            left: origX,
            top: origY,
            //originX: 'left',
            //originY: 'top',
            width: pointer.x - origX,
            height: pointer.y - origY,
            //angle: 0,
            fill: 'rgba(255,0,0,0.3)',
            transparentCorners: false,
            //selectable: true,
            id: 'mask'
        });
        canvas.add(rect);
        canvas.renderAll();
    });

    canvas.on('mouse:move', function(o) {
        if (done) {
            canvas.renderAll();
            return;
        }
        if (!isDown) return;
        var pointer = canvas.getPointer(o.e);

        if (origX > pointer.x) {
            rect.set({
                left: Math.abs(pointer.x)
            });
        }
        if (origY > pointer.y) {
            rect.set({
                top: Math.abs(pointer.y)
            });
        }

        rect.set({
            width: Math.abs(origX - pointer.x)
        });
        rect.set({
            height: Math.abs(origY - pointer.y)
        });


        canvas.renderAll();
    });

    canvas.on('mouse:up', function(o) {
        if (done) {
            canvas.renderAll();
            return;
        }
        isDown = false;

        //rect.selectable = true;
        rect.set({
            selectable: true
        });
        rect.setCoords();
        canvas.setActiveObject(rect);
        canvas.bringToFront(rect);
        canvas.renderAll();
        //alert(rect);
        rect.setCoords();
        object.clipPath = rect;
        object.selectable = true;
        object.setCoords();
        canvas.renderAll();
        //canvas.remove(rect);
        done = true;
    });

【问题讨论】:

    标签: dynamic fabricjs crop mask


    【解决方案1】:

    您需要将图像上的脏参数设置为true,以便在下次渲染调用时重新渲染对象的缓存。 这是小提琴: https://jsfiddle.net/mqrv5fnt/115/

     var canvas = new fabric.Canvas('c', {
      selection: true
    });
    
    var rect, isDown, origX, origY, done, object, mask, target;
    
    var src = "http://fabricjs.com/lib/pug.jpg";
    fabric.Image.fromURL(src, function(img) {
      img.selectable = false;
      img.id = 'image';
      object = img;
      canvas.add(img);
    });
    
    canvas.on('object:added', function(e) {
      target = null;
      mask = null;
      canvas.forEachObject(function(obj) {
        //alert(obj.get('id'));
        var id = obj.get('id');
        if (id === 'image') {
          target = obj;
        }
        if (id === 'mask') {
          //alert('mask');
          mask = obj;
        }
      });
    });
    
    document.getElementById("crop").addEventListener("click", function() {
      if (target !== null && mask !== null) {
    
        mask.setCoords();
        target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
        target.dirty=true;
        //target.selectable = true;
        target.setCoords();
        canvas.remove(mask);
        canvas.renderAll();
        //canvas.remove(mask);
      }
    });
    
    canvas.on('mouse:down', function(o) {
      if (done) {
        canvas.renderAll();
        return;
      }
      isDown = true;
      var pointer = canvas.getPointer(o.e);
      origX = pointer.x;
      origY = pointer.y;
      rect = new fabric.Rect({
        left: origX,
        top: origY,
        //originX: 'left',
        //originY: 'top',
        width: pointer.x - origX,
        height: pointer.y - origY,
        //angle: 0,
        fill: 'rgba(255,0,0,0.3)',
        transparentCorners: false,
        //selectable: true,
        id: 'mask'
      });
      canvas.add(rect);
      canvas.renderAll();
    });
    
    canvas.on('mouse:move', function(o) {
      if (done) {
        canvas.renderAll();
        return;
      }
      if (!isDown) return;
      var pointer = canvas.getPointer(o.e);
    
      if (origX > pointer.x) {
        rect.set({
          left: Math.abs(pointer.x)
        });
      }
      if (origY > pointer.y) {
        rect.set({
          top: Math.abs(pointer.y)
        });
      }
    
      rect.set({
        width: Math.abs(origX - pointer.x)
      });
      rect.set({
        height: Math.abs(origY - pointer.y)
      });
    
    
      canvas.renderAll();
    });
    
    canvas.on('mouse:up', function(o) {
      if (done) {
        canvas.renderAll();
        return;
      }
      isDown = false;
    
      //rect.selectable = true;
      rect.set({
        selectable: true
      });
      rect.setCoords();
      canvas.setActiveObject(rect);
      canvas.bringToFront(rect);
      canvas.renderAll();
      //alert(rect);
      rect.setCoords();
      object.clipPath = rect;
      object.selectable = true;
      object.setCoords();
      canvas.renderAll();
      //canvas.remove(rect);
      done = true;
    });
    

    【讨论】:

    • 非常感谢马吕斯!这对我行得通。我仍然有一些定位问题,但我很确定我能解决这个问题。
    • 这是我的小提琴,它也解决了定位问题。谢谢大家。 jsfiddle.net/Larry_Robertson/vocufy2q
    • 我不确定这是否应该作为第二个问题提交,如果应该,请告诉我,我将删除它。尽管修复效果很好,但我注意到最终剪辑的图像仍然保留了原始图像的高度和宽度。有没有办法在不改变纵横比的情况下修剪剩余的空白或调整大小?
    • 这与基本问题无关。需要查看官方文档。fabricjs.com/docs/fabric.Image.html。你需要使用cropX、cropY、width和height。
    猜你喜欢
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    相关资源
    最近更新 更多