在画布上绘制矩形 [英] Drawing a rectangle on Canvas

查看:97
本文介绍了在画布上绘制矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个简单的画布程序,用户可以一致地创建新的形状。这一个只是一个基本的矩形创建者(我希望将其更多地扩展为圆,线,甚至其他东西)。现在虽然我创造了一个工作在一个奇怪的方式。

I am trying to create a simple canvas program where the user can consistently create new shapes. This one is just a basic rectangle creator (I am hoping to expand it more to circles, lines, and maybe even other stuff). Right now though I have created something that is working in a really weird way.

 <html>
    <head>
    <meta chartset="utf-8">
    <title>Dragging a square</title>
    <script type="text/javascript">
        var canvas, context, startX, endX, startY, endY;
        var mouseIsDown = 0;

        function init() {
            canvas = document.getElementById("canvas");
            context = canvas.getContext("2d");

            canvas.addEventListener("mousedown", mouseDown, false);
            canvas.addEventListener("mousemove", mouseXY, false);

            document.body.addEventListener("mouseup", mouseUp, false);
        }

        function mouseUp() {
            mouseIsDown = 0;
            //mouseXY();
        }

        function mouseDown() {
            mouseIsDown = 1;
            startX = event.clientX;
            startY = event.clientY;
            mouseXY();
        }

        function mouseXY(eve) {
            if (!eve) {
                var eve = event;
            }
            endX = event.pageX - canvas.offsetLeft;
            endY = event.pageY - canvas.offsetTop;

            drawSquare();
        }

        function drawSquare() {
            // creating a square
            var width = Math.abs(startX - endX);
            var height = Math.abs(startY - endY);

            context.beginPath();
            context.rect(startX, startY, width, height);
            context.fillStyle = "yellow";
            context.fill();
            context.lineWidth = 7;
            context.strokeStyle = 'black';
            context.stroke();

        }
    </script>
</head>
<body onload="init()">
    <canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas>
</body>
    </html>

当我复制和粘贴我的代码时,我认为问题是我的mouseXY函数。我想要的是用户点击画布上的某处拖动鼠标创建一个矩形,当用户放手,那是该操作的结束,他们可以立即创建一个全新的矩形。在这一点上,程序种类只是让我点击并创建一个新的矩形,但如果我放开鼠标按钮,它不会停止,实际上,我必须再次点击使它停止,然后创建一个新的矩形。我还是很新的这个,我有很多麻烦这个,我会继续工作,如果我弄清楚,我会让网站知道。

Sorry about the slightly weird formatting when I copy and pasted my code. I think the problem is my mouseXY function. What I want is the user to click somewhere on the canvas a drag the mouse to create a rectangle, when the user lets go that is the end of that operation and they can create a whole new rectangle right after. At this point the program kind of just lets me click and create a new rectangle but if I let go of the mouse button it doesn't stop, in fact I have to click again to make it stop which then creates a new rectangle. I am still very new to this and I am having a lot of trouble with this, I will continue to work on this and if I figure it out I will let the site know. Thank you and have a great day!

我得到这个工作(感谢@Ken),但现在我试图解决一个新的问题。我想能够在画布上放置多个矩形。我创建了一个代表Rectangle的函数,然后在矩形函数内创建一个绘制函数来绘制一个矩形。我创建了一个名为addShape()的新函数,理想地创建矩形对象并推入一个名为square和drawShapes()的数组,该数组应该擦除画布上的所有内容并重绘所有内容。这是我到目前为止:

Well I got this to work (thanks to @Ken) but now I am trying to solve a new problem. I want to be able to put multiple rectangles on the canvas. I created a function that represents the Rectangle and then created a draw function within the rectangle function to draw out a rectangle. I created a new function called addShape() that ideally creates the rectangle object and pushes into an array called square and drawShapes() that is supposed to erase everything on the canvas and redraws everything. Here is what I have so far:

    <html>
    <head>
    <meta chartset="utf-8">
    <title>Dragging a square</title>
    <script type="text/javascript">
        function Rectangle(canvas, x, y, width, height,color) {
            //this.context = canvas.getContext("2d");

            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.color = color;

            this.draw = function() {

                this.context.globalAlpha = 0.85;
                this.context.beginPath();
                this.context.rect(this.x, this.y, this.width, this.height);
                this.context.fillStyle = this.color;
                this.context.strokeStyle = "black";
                this.context.lineWidth = 1;

                this.context.fill();
                this.context.stroke();
            };

        };

        // hold the canvas and context variable, as well as the 
        // starting point of X and Y and the end ones
        var canvas, context, startX, endX, startY, endY;
        var mouseIsDown = 0;

        // An array that holds all the squares
        var squares = [];

        window.onload = function() {
            canvas = document.getElementById("canvas");
            context = canvas.getContext("2d");

            canvas.addEventListener("mousedown", mouseDown, false);
            canvas.addEventListener("mousemove", mouseXY, false);
            canvas.addEventListener("mouseup", mouseUp, false);
        }

        function mouseUp(eve) {
            if (mouseIsDown !== 0) {
                mouseIsDown = 0;
                var pos = getMousePos(canvas, eve);
                endX = pos.x;
                endY = pos.y;

                //Square(); //update on mouse-up
                addShape(); // Update on mouse-up
            }
        }

        function mouseDown(eve) {
            mouseIsDown = 1;
            var pos = getMousePos(canvas, eve);
            startX = endX = pos.x;
            startY = endY = pos.y;
            // Square(); //update
            addShape();
        }

        function mouseXY(eve) {

            if (mouseIsDown !== 0) {
                var pos = getMousePos(canvas, eve);
                endX = pos.x;
                endY = pos.y;

                //Square();
                addShape();
            }
        }

        function getMousePos(canvas, evt) {
            var rect = canvas.getBoundingClientRect();
            return {
                x: evt.clientX - rect.left,
                y: evt.clientY - rect.top
            };
        }

        function addShape() {
            var w = endX - startX;
            var h = endY - startY;
            var offsetX = (w < 0) ? w : 0;
            var offsetY = (h < 0) ? h : 0;
            var width = Math.abs(w);
            var height = Math.abs(h);

            var s = new Rectangle(startX + offsetX, startY + offsetY, width, height, "yellow");

            squares.push(s);

            // Update the display
            drawShapes();
        }

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

            for (var i = 0; i < squares.length; i++) {
                var shape = squares[i];
                shape.draw();
            };
        }

        function clearCanvas() {
            squares = [];

            drawShapes();
        }

    </script>
</head>
<body onload="addShape()">
    <canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas><br>
    <button onclick="clearCanvas()">Clear Canvas</button>
</body>
    </html>

我很肯定我打破了原来的代码...谢谢任何帮助!

I am pretty sure I broke the original code... thank you for any help!

推荐答案

您需要修改代码中的一些东西:(编辑:这个代码有很多问题,如果你把它放在一个小提琴更容易我们检查)..

You need to modify a couple of things in the code: (edit: there are many issues with this code. I went through some of them inline here, but haven't tested. If you put it in a fiddle it's easier for us to check)..

更新:工作小提琴:

http://jsfiddle.net/AbdiasSoftware/kqW4X/

当鼠标按下时,初始化起始点和结束点。调用不依赖于事件本身的公共绘制函数:

When mouse down occur initialize both start and end points. Call a common draw function that is not dependent on the event itself:

function mouseDown(eve) {
    mouseIsDown = 1;
    var pos = getMousePos(canvas, eve);
    startX = endX = pos.x;
    startY = endY = pos.y;
    drawSquare(); //update
}

鼠标向上时,只有当isMouseDown为true时才会注册,否则函数将处理所有接收到的上传事件(因为你已经将它调入文档,这是正确的 - 窗口也可以使用):

At mouse up, only register if isMouseDown is true, else this function will handle all incoming up-events (as you have attatched it to document, which is correct - window could have been used too):

function mouseUp(eve) {
    if (mouseIsDown !== 0) {
        mouseIsDown = 0;
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;
        drawSquare(); //update on mouse-up
    }
}

是真的:

function mouseXY(eve) {

    if (mouseIsDown !== 0) {
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;

        drawSquare();
    }
}

此外,您需要清除上一个区域

In addition you will need to clear the previous area of the rectangle before drawing a new or else it won't show when you draw a bigger rectangle and then move the mouse back to draw a smaller one.

为了简单起见,你可以在绘制一个新的矩形之前绘制一个新的矩形,否则它不会显示。 do:

For simplicity you can do:

function drawSquare() {
    // creating a square
    var width = Math.abs(startX - endX);
    var height = Math.abs(startY - endY);

    context.clearRect(0, 0, context.width, context.height);
    //or use fillRect if you use a bg color

    context.beginPath();
    context.rect(startX, startY, width, height);
    context.fillStyle = "yellow";
    context.fill();
    context.lineWidth = 7;
    context.strokeStyle = 'black';
    context.stroke();
}

使用鼠标位置:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

这篇关于在画布上绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆