如何使所有绘制(矩形,圆形,线条,多边形)可拖动?纯JS

时间:2015-04-03 21:46:08

标签: javascript html5 canvas draggable shapes

我有一个简单的画布html5。它可以通过选择选项绘制一些形状,如线条,圆形,矩形,多边形,但现在我想让所有绘图可拖动,如果可能的可调整大小,没有3部分库只有纯JS。

    var canvas,
    context,
    dragStartLocation,
    snapshot;
    dragdrop = false;
    isDrag = false;




function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;


}

function getCanvasCoordinates(event) {
    var x = event.clientX - canvas.getBoundingClientRect().left;
        y = event.clientY - canvas.getBoundingClientRect().top;

    return {x: x, y: y};
}



function takeSnapshot() {
    snapshot = context.getImageData(0, 0, canvas.width, canvas.height);

}

function restoreSnapshot() {
    context.putImageData(snapshot, 0, 0);
}

function drawLine(position) {

    context.beginPath();
    context.moveTo(dragStartLocation.x, dragStartLocation.y);
    context.lineTo(position.x, position.y );
    context.stroke();

    }

function drawRect(position) {

    context.beginPath();
    //context.moveTo(dragStartLocation.x, dragStartLocation.y);
    context.fillRect(position.x, position.y, dragStartLocation.x - position.x, dragStartLocation.y - position.y);
    //context.stroke();

}

function drawCircle(position) {
    var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
    context.beginPath();
    context.arc(dragStartLocation.x, dragStartLocation.y, radius, 0, 2 * Math.PI, false);

}

/*
function drawPolygon(position, sides, angle) {
    var coordinates = [],
        radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2)),
        index = 0;

    for (index = 0; index < sides; index++) {
        coordinates.push({x: dragStartLocation.x + radius * Math.cos(angle), y: dragStartLocation.y - radius * Math.sin(angle)});
        angle += (2 * Math.PI) / sides;
    }

    context.beginPath();
    context.moveTo(coordinates[0].x, coordinates[0].y);
    for (index = 1; index < sides; index++) {
        context.lineTo(coordinates[index].x, coordinates[index].y);
    }

    context.closePath();
}*/


function draw(position) {

    var fillBox = document.getElementById("fillBox"),
        shape = document.querySelector('#tools option:checked').value,
        /*polygonSides = document.getElementById("polygonSides").value,
        polygonAngle = document.getElementById("polygonAngle").value,*/
        lineCap = document.querySelector('input[type="radio"][name="lineCap"]:checked').value;
        /*composition = document.querySelector('input[type="radio"][name="composition"]:checked').value;*/

    context.lineCap = lineCap;
    /*context.globalCompositeOperation = composition;*/

    if (shape === "circle") {
        drawCircle(position);

    }
    if (shape === "line") {
        drawLine(position);
    }

    if (shape === "rect") {
        drawRect(position);
    }

    if (shape === "polygon") {
        drawPolygon(position, polygonSides, polygonAngle * (Math.PI / 180));
    }

    if (shape !== "line") {
        if (fillBox.checked) {
            context.fill();
        } else {
            context.stroke();
        }
    }
}

function dragStart(event) {
    dragging = true;
    dragStartLocation = getCanvasCoordinates(event);
    takeSnapshot();
}

function drag(event) {
    var position;
    if (dragging === true) {
        restoreSnapshot();
        position = getCanvasCoordinates(event);
        draw(position);
    }
}

function dragStop(event) {
    dragging = false;
    restoreSnapshot();
    var position = getCanvasCoordinates(event);
    draw(position);
}

function changeLineWidth() {
    context.lineWidth = this.value;
    event.stopPropagation();
}

function changeFillStyle() {
    context.fillStyle = this.value;
    event.stopPropagation();
}

function changeStrokeStyle() {
    context.strokeStyle = this.value;
    event.stopPropagation();
}

function changeBackgroundColor() {
    context.save();
    context.fillStyle = document.getElementById("backgroundColor").value;
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.restore();
}

function eraseCanvas() {
    context.clearRect(0, 0, canvas.width, canvas.height);
}


function init() {
    canvas = document.getElementById("canvas");
    context = canvas.getContext('2d');
    var lineWidth = document.getElementById("lineWidth"),
        fillColor = document.getElementById("fillColor"),
        strokeColor = document.getElementById("strokeColor"),
        //canvasColor = document.getElementById("backgroundColor"),
        clearCanvas = document.getElementById("clearCanvas");
        //saveCanvas = document.getElementById("saveCanvas");

    context.strokeStyle = strokeColor.value;
    context.fillStyle = fillColor.value;
    context.lineWidth = lineWidth.value;

    /*window.addEventListener('resize', resizeCanvas, false);
    window.addEventListener('orientationchange', resizeCanvas, false);
    resizeCanvas();*/


    canvas.addEventListener('mousedown', dragStart, false);
    canvas.addEventListener('mousemove', drag, false);
    canvas.addEventListener('mouseup', dragStop, false);
    lineWidth.addEventListener("input", changeLineWidth, false);
    fillColor.addEventListener("input", changeFillStyle, false);
    strokeColor.addEventListener("input", changeStrokeStyle, false);
    //canvasColor.addEventListener("input", changeBackgroundColor, false);
    clearCanvas.addEventListener("click", eraseCanvas, false);
    //saveCanvas.addEventListener("click", salvaCanvas, false);

}

window.addEventListener('load', init, false);

1 个答案:

答案 0 :(得分:1)

画布的一个基本特征是它只存储由于所有绘制操作而形成的光栅图像。这就是为什么画布速度快且内存效率高。

缺点是您必须擦除画布上受影响的矩形(或最坏情况下的整个画布)并重绘所有需要调整大小,移动等的形状。画布不会将它们存储为对象,因此您的JS代码必须负责在画布上存储,修改和重新绘制它们。除非您使用某些第三方库,否则这项工作非常重要。

另一种方法是使用HTML5的类似SVG的功能而不是画布:<line><path><rect>等。它们由浏览器保存为对象,可通过DOM访问。但是,这是一种完全不同的方法,需要完全重写代码。