在画布上绘制一个区域

时间:2013-03-24 09:58:26

标签: javascript jquery html5 canvas html5-canvas

我需要在绘图时用光标悬挂绘图线。我试过mousemove事件,但没有得到它的工作。以下就是我现在所拥有的。

http://jsfiddle.net/m1erickson/qwd2a/

var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        var canvasMouseX;
        var canvasMouseY;
        var canvasOffset = $("#canvas").offset();
        var offsetX = canvasOffset.left;
        var offsetY = canvasOffset.top;
        var storedLines = [];

        ctx.strokeStyle = "orange";
        ctx.font = '12px Arial';

        $("#canvas").mousedown(function (e) {
            handleMouseDown(e);
        });

        function handleMouseDown(e) {
            canvasMouseX = parseInt(e.clientX - offsetX);
            canvasMouseY = parseInt(e.clientY - offsetY);

            // Put your mousedown stuff here
            storedLines.push({
                x: canvasMouseX,
                y: canvasMouseY
            });
            var count = storedLines.length;
            var X = canvasMouseX - (count < 10 ? 4 : 7);
            ctx.strokeStyle = "orange";
            ctx.fillStyle = "black";
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.arc(canvasMouseX, canvasMouseY, 8, 0, 2 * Math.PI, false);
            ctx.fillText(storedLines.length, X, canvasMouseY + 4);
            ctx.stroke();
        }

        $("#draw").click(function () {
            ctx.strokeStyle = "red";
            ctx.fillStyle = "blue";
            ctx.lineWidth = 3;
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.beginPath();
            ctx.moveTo(storedLines[0].x, storedLines[0].y);
            for (var i = 0; i < storedLines.length; i++) {
                ctx.lineTo(storedLines[i].x, storedLines[i].y);
            }
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
            storedLines = [];
        });

        $("#clear").click(function () {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            storedLines = [];
        });

2 个答案:

答案 0 :(得分:2)

使用画布,您负责在每次需要时重绘整个内容。这意味着当鼠标光标移动时,您需要清除画布,然后重绘所有当前线段。根据您的代码,我提出了以下示例,了解如何完成:

<html>
<head>
    <title>Canvas</title>
</head>
<body>

<p>Click to draw lines</p>
<p>Click back in the green circle to close+fill</p>
<br/>
<canvas id="canvas" width=300 height=300></canvas>
<br/>
<button id="clear">Clear Canvas</button>

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function () {
        var canvas = document.getElementById("canvas"),
            ctx = canvas.getContext("2d"),
            offset = $("#canvas").offset(),
            storedLines = [],
            polyLines = [],
            start = {x: 0, y: 0},
            radius = 7;

        function canvasPosition(e) {
            return {
                x: parseInt(e.clientX - offset.left),
                y: parseInt(e.clientY - offset.top)
            };
        }

        $("#canvas").mousedown(function (e) {
            var pos = canvasPosition(e);
            if (hitStartCircle(pos)) {
                polyLines.push(storedLines);
                storedLines = [];
                draw();
            }
            else
            {
                storedLines.push(pos);
                update(pos);
            }
        })
        .mousemove(function (e) {
            update(canvasPosition(e));
        });

        // Draw completed polylines
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            $.each(polyLines, function (idx, polyLine) {
                fillPolyline(polyLine);
            });
        }

        // Update shape currently being drawn
        function update(position) {
            var len = storedLines.length;
            if(len==0) return;

            draw();
            ctx.fillStyle = "green";
            ctx.beginPath();
            ctx.arc(storedLines[0].x, storedLines[0].y, radius, 0, 2 * Math.PI, false);
            ctx.fill();

            ctx.strokeStyle = "orange";
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(storedLines[0].x, storedLines[0].y);
            for(var i=1; i<len; ++i) {
                ctx.lineTo(storedLines[i].x, storedLines[i].y)
            }
            ctx.lineTo(position.x, position.y);
            ctx.stroke();
        };

        function hitStartCircle(pos) {
            var start = storedLines[0] || {x:0, y:0},
                dx = pos.x - start.x,
                dy = pos.y - start.y;
            return (dx * dx + dy * dy < radius * radius)
        }

        function fillPolyline(lines) {
            ctx.strokeStyle = "red";
            ctx.fillStyle = "blue";
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(lines[0].x, lines[0].y);
            for (var i = 0; i < lines.length; i++) {
                ctx.lineTo(lines[i].x, lines[i].y);
            }
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        }

        $("#clear").click(function () {
            polyLines = [];
            draw();
        });
});
</script>
</body>
</html>

当用户移动鼠标光标时,这将正确更新最后一段。

答案 1 :(得分:0)

通过查看你的jsfiddle,绘制一条新线时会有一个偏移量。 这是因为你的css中的身体填充物。

只需替换它:

body {
    background-color: ivory;
    padding:10px;
}

用这个:

body {
    background-color: ivory;
}