将图像拖放到画布(FabricJS)

时间:2015-08-13 23:04:58

标签: javascript fabricjs

问题
我想用图像而不是canvas对象来做这件事。这意味着您必须先添加要添加到画布的TO AND作为画布的一部分,然后才能添加它。这些图像实际上是网站的一部分,因此它不需要做一些复杂的事情。我在这里找到的代码只适用于它不是实际元素的对象。顺便说一句,我使用FabricJS只是为了让您知道我没有使用默认的HTML5画布。

对于任何可能在不使用我当前代码的情况下工作的替代方案。请在评论或答案中将其发布在下方。我真的很想看看你们的想法。

摘要
基本上我希望能够在保留鼠标光标位置的同时通过画布拖放图像。例如,如果我拖动图像并且光标位于x:50 y:75,则会将图像拖放到该确切位置。就像我发现的代码一样。但是就像所说的问题一样,CODE使用一个对象将它拖动到画布然后它克隆它。我希望这个功能只使用普通的旧元素。例如:<img>


代码 - JsFiddle

window.canvas = new fabric.Canvas('fabriccanvas');
var edgedetection = 8; //pixels to snap
canvas.selection = false;

window.addEventListener('resize', resizeCanvas, false);

function resizeCanvas() {
    canvas.setHeight(window.innerHeight);
    canvas.setWidth(window.innerWidth);
    canvas.renderAll();
}

// resize on init
resizeCanvas();

//Initialize Everything
init();

function init(top, left, width, height, fill) {

    var bg = new fabric.Rect({
        left: 0,
        top: 0,
        fill:  "#eee",
        width: window.innerWidth,
        height: 75,    
        lockRotation: true,
        maxHeight: document.getElementById("fabriccanvas").height,
        maxWidth: document.getElementById("fabriccanvas").width,
        selectable: false,
    });

    var squareBtn = new fabric.Rect({
        top: 10,
        left: 18,
        width: 40,
        height: 40,
        fill: '#af3',
        lockRotation: true,
        originX: 'left',
        originY: 'top',
        cornerSize: 15,
        hasRotatingPoint: false,
        perPixelTargetFind: true,
    });

    var circleBtn = new fabric.Circle({
        radius: 20,
        fill: '#f55',
        top: 10,
        left: 105,
    });

    var triangleBtn = new fabric.Triangle({
        width: 40, 
        height: 35, 
        fill: 'blue', 
        top: 15,
        left: 190,
    });

    var sqrText = new fabric.IText("Add Square", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 6,
        top: 50,
        selectable: false,
    });

    var cirText = new fabric.IText("Add Circle", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 95,
        top: 50,
        selectable: false,
    });

    var triText = new fabric.IText("Add Triangle", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 175,
        top: 50,
        selectable: false,
    });

    var shadow = {
        color: 'rgba(0,0,0,0.6)',
        blur: 3,    
        offsetX: 0,
        offsetY: 2,
        opacity: 0.6,
        fillShadow: true, 
        strokeShadow: true 
    };

    window.canvas.add(bg);
    bg.setShadow(shadow);
    window.canvas.add(squareBtn);
    window.canvas.add(circleBtn);
    window.canvas.add(triangleBtn);
    window.canvas.add(sqrText);
    window.canvas.add(cirText);
    window.canvas.add(triText);

    canvas.forEachObject(function (e) {
        e.hasControls = e.hasBorders = false; //remove borders/controls
    });

    function draggable(object) {
        object.on('mousedown', function() {
            var temp = this.clone();
            temp.set({
                hasControls: false,
                hasBorders: false,
            });
            canvas.add(temp);
            draggable(temp);
        });
        object.on('mouseup', function() {
            // Remove an event handler
            this.off('mousedown');

            // Comment this will let the clone object able to be removed by drag it to menu bar
            // this.off('mouseup');

            // Remove the object if its position is in menu bar
            if(this.top<=75) {
                canvas.remove(this);
            }
        });
    }

    draggable(squareBtn);
    draggable(circleBtn);
    draggable(triangleBtn);

    this.canvas.on('object:moving', function (e) {
        var obj = e.target;
        obj.setCoords(); //Sets corner position coordinates based on current angle, width and height
        canvas.forEachObject(function (targ) {
            activeObject = canvas.getActiveObject();


            if (targ === activeObject) return;


            if (Math.abs(activeObject.oCoords.tr.x - targ.oCoords.tl.x) < edgedetection) {
                activeObject.left = targ.left - activeObject.currentWidth;

            }
            if (Math.abs(activeObject.oCoords.tl.x - targ.oCoords.tr.x) < edgedetection) {
                activeObject.left = targ.left + targ.currentWidth;

            }
            if (Math.abs(activeObject.oCoords.br.y - targ.oCoords.tr.y) < edgedetection) {
                activeObject.top = targ.top - activeObject.currentHeight;
            }
            if (Math.abs(targ.oCoords.br.y - activeObject.oCoords.tr.y) < edgedetection) {
                activeObject.top = targ.top + targ.currentHeight;
            }
            if (activeObject.intersectsWithObject(targ) && targ.intersectsWithObject(activeObject)) {

            } else {
                targ.strokeWidth = 0;
                targ.stroke = false;


            }
            if (!activeObject.intersectsWithObject(targ)) {
                activeObject.strokeWidth = 0;
                activeObject.stroke = false;
                activeObject === targ
            }
        });
    });
}

我发现了更多代码,但没有回答我的问题:

var canvas = new fabric.Canvas('c');

canvas.on("after:render", function(){canvas.calcOffset();});

var started = false;
var x = 0;
var y = 0;
var width = 0;
var height = 0;

canvas.on('mouse:down', function(options) {
  //console.log(options.e.clientX, options.e.clientY);

  x = options.e.clientX;
  y = options.e.clientY;

  canvas.on('mouse:up', function(options) {

    width = options.e.clientX - x;
    height = options.e.clientY - y;   

    var square = new fabric.Rect({

        width: width, 
        height: height, 
        left: x + width/2 - canvas._offset.left, 
        top: y + height/2 - canvas._offset.top, 
        fill: 'red',
        opacity: .2
    });
    canvas.add(square);
    canvas.off('mouse:up');
    $('#list').append('<p>Test</p>');

  });

});

此代码向画布添加一个矩形。但问题是这并没有达到我想要的水平,基本上如前所述,我希望能够拖动img元素,然后无论你在画布上拖动那个图像,它都会掉落它恰好在那个地方。

CREDITS
Fabric JS: Copy/paste object on mouse down
fabric.js Offset Solution

1 个答案:

答案 0 :(得分:0)

  

它不需要做一些复杂的事情。

实现图像拖动的逻辑框架可能是使用事件侦听器监视鼠标事件。

在鼠标按下页面内的Image元素但不在画布上方时,记录图像中的图像元素和鼠标位置。在任何地方向上鼠标时,将此记录设置为空。

将鼠标悬停在具有非空图像记录的画布上时,从Image元素创建Fabric图像元素(根据文档),计算它从记录的图像位置和当前鼠标位置的位置,将其粘贴到鼠标下,使其可拖动并模拟鼠标单击的效果继续拖动它。

我已经把这个问题放在了程序开发的设计和可行性阶段。