如何在画布html5中获取上下文X和Y位置

时间:2013-09-17 13:13:05

标签: javascript html5 html5-canvas

我有这个fiddle,我需要知道我的网格始终从哪里开始的位置;

我可以缩放甚至拖放网格。

<!DOCTYPE html>
<!-- saved from url=(0048)http://phrogz.net/tmp/canvas_zoom_to_cursor.html -->
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Zooming via HTML5 Canvas Context</title>
        <style type="text/css" media="screen">
            body { background:#eee; margin:1em; text-align:center; }
            canvas { display:block; margin:1em auto; background:#fff; border:1px solid #ccc }
        </style>
    </head>
    <body style="-webkit-user-select: none;">

        <canvas width="800" height="600"></canvas>

        <script type="text/javascript" charset="utf-8">

            var start_x = start_y = position_x = position_y = 50;

            var canvas = document.getElementsByTagName('canvas')[0];

            canvas.width = 800;

            canvas.height = 600;

            var gkhead = new Image;

            var ball = new Image;

            var square_size = 10;

            window.onload = function() {

                var ctx = canvas.getContext('2d');

                trackTransforms(ctx);

                function redraw() {
                    // Clear the entire canvas
                    var p1 = ctx.transformedPoint(0, 0);
                    var p2 = ctx.transformedPoint(canvas.width, canvas.height);
                    ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);

                    ctx.drawImage(gkhead, 50, 50);//punct stanga sus imagine cu marton
                    //console.log(ctx);
                    color = 'ff0000';
                    w = gkhead.width;
                    //console.log(w);
                    h = gkhead.height;
                    //console.log(h);
                    var i = 0;
                    i = i + 1;
                    if (i == 1)
                        color = 'ff0000';
                    if (i == 2)
                        color = '00ff00';
                    if (i == 3) {
                        color = '0000ff';
                        i = 0;
                    }

                    ctx.beginPath();
                    ctx.rect(50, 50, gkhead.width, gkhead.height);
                    ctx.lineWidth = 1;
                    ctx.strokeStyle = "#" + color;
                    ctx.stroke();

                    ctx.beginPath();
                    ctx.rect(51, 51, 8, 8);
                    ctx.lineWidth = 1;
                    ctx.fillStyle="#ffff00";
                    ctx.fill();
                    ctx.strokeStyle = "#ffff00";
                    ctx.stroke();

                    var ind = 0;
                    for (var j = 0; j < gkhead.width - square_size; j = j + square_size) {
                        ind++;
                        ctx.beginPath();
                        ctx.lineWidth = 1;
                        ctx.strokeStyle = 'black';
                        ctx.moveTo(50 + (ind * square_size), 50);
                        ctx.lineTo(50 + (ind * square_size), 50 + gkhead.height);
                        ctx.stroke();
                    }

                    var ind = 0;
                    for (var j = 0; j < gkhead.height - square_size; j = j + square_size) {
                        ind++;
                        ctx.beginPath();
                        ctx.lineWidth = 1;
                        ctx.strokeStyle = 'blue';
                        ctx.moveTo(50, 50 + (ind * square_size));
                        ctx.lineTo(50 + gkhead.width, 50 + (ind * square_size));
                        ctx.stroke();
                    }

                    ctx.save();
                    ctx.translate(438.5, 223);
                    ctx.strokeStyle = '#06c';
                    ctx.beginPath();
                    ctx.lineWidth = 0.05;

                    for (var i = 0; i < 60; ++i) {
                        ctx.rotate(6 * i * Math.PI / 180);
                        ctx.moveTo(9, 0);
                        ctx.lineTo(10, 0);
                        ctx.rotate(-6 * i * Math.PI / 180);
                    }
                    ctx.stroke();
                    ctx.restore();
                }
                redraw();

                var lastX = canvas.width / 2, lastY = canvas.height / 2;
                var dragStart, dragged;

                canvas.addEventListener('mousedown', function(evt) {
                    document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
                    lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
                    lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
                    console.log('mousedown' + ' ' + lastX + ' ' + lastY);
                    dragStart = ctx.transformedPoint(lastX, lastY);
                    dragged = false;
                }, false);

                canvas.addEventListener('mousemove', function(evt) {
                    lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
                    lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
                    dragged = true;
                    if (dragStart) {
                        var pt = ctx.transformedPoint(lastX, lastY);
                        ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
                        console.log('dragStart: ' + ' ' + dragStart.x + ' ' + dragStart.y);
                        console.log('mousemove dragStart' + ' ' + (lastX) + ' ' + (lastY));
                        if (lastX != start_x) {
                            if (lastX > start_x)
                                position_x = position_x + lastX - start_x;
                            else
                                position_x = position_x + start_x - lastX;
                        }
                        if (lastY != start_y) {
                            if (lastY > start_y)
                                position_y = position_y + lastY - start_y;
                            else
                                position_y = position_y + start_y - lastY;
                        }
                        console.log('position: ' + position_x + ' ' + position_y);
                        redraw();
                    }
                }, false);

                canvas.addEventListener('mouseup', function(evt) {
                    dragStart = null;
                    if (!dragged)
                        zoom(evt.shiftKey ? -1 : 1);
                }, false);

                var scaleFactor = 1.1;
                var zoom = function(clicks) {
                    var pt = ctx.transformedPoint(lastX, lastY);
                    ctx.translate(pt.x, pt.y);
                    var factor = Math.pow(scaleFactor, clicks);
                    ctx.scale(factor, factor);
                    ctx.translate(-pt.x, -pt.y);
                    redraw();
                }

                var handleScroll = function(evt) {
                    var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
           if (delta)
            zoom(delta);
                    return evt.preventDefault() && false;
                };
                canvas.addEventListener('DOMMouseScroll', handleScroll, false);
                canvas.addEventListener('mousewheel', handleScroll, false);
            };

            gkhead.src = 'http://www.william.ro/wp-content/uploads/2013/07/13.jpg';

            ball.src = 'http://phrogz.net/tmp/alphaball.png';

            // Adds ctx.getTransform() - returns an SVGMatrix
            // Adds ctx.transformedPoint(x,y) - returns an SVGPoint
            function trackTransforms(ctx) {
                var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
                var xform = svg.createSVGMatrix();
                ctx.getTransform = function() {
                    return xform;
                };

                var savedTransforms = [];
                var save = ctx.save;
                ctx.save = function() {
                    savedTransforms.push(xform.translate(0, 0));
                    return save.call(ctx);
                };
                var restore = ctx.restore;
                ctx.restore = function() {
                    xform = savedTransforms.pop();
                    return restore.call(ctx);
                };

                var scale = ctx.scale;
                ctx.scale = function(sx, sy) {
                    xform = xform.scaleNonUniform(sx, sy);
                    return scale.call(ctx, sx, sy);
                };
                var rotate = ctx.rotate;
                ctx.rotate = function(radians) {
                    xform = xform.rotate(radians * 180 / Math.PI);
                    return rotate.call(ctx, radians);
                };
                var translate = ctx.translate;
                ctx.translate = function(dx, dy) {
                    xform = xform.translate(dx, dy);
                    return translate.call(ctx, dx, dy);
                };
                var transform = ctx.transform;
                ctx.transform = function(a, b, c, d, e, f) {
                    var m2 = svg.createSVGMatrix();
                    m2.a = a;
                    m2.b = b;
                    m2.c = c;
                    m2.d = d;
                    m2.e = e;
                    m2.f = f;
                    xform = xform.multiply(m2);
                    return transform.call(ctx, a, b, c, d, e, f);
                };
                var setTransform = ctx.setTransform;
                ctx.setTransform = function(a, b, c, d, e, f) {
                    xform.a = a;
                    xform.b = b;
                    xform.c = c;
                    xform.d = d;
                    xform.e = e;
                    xform.f = f;
                    return setTransform.call(ctx, a, b, c, d, e, f);
                };
                var pt = svg.createSVGPoint();
                ctx.transformedPoint = function(x, y) {
                    pt.x = x;
                    pt.y = y;
                    return pt.matrixTransform(xform.inverse());
                }
            }
        </script>

    </body>

</html>

1 个答案:

答案 0 :(得分:6)

您可以通过这种方式获取相对于画布的鼠标坐标(与mousemove事件一起使用以检测鼠标是否在内部):

canvas.onmousemove = function(e) {

    var pos = getMousePos(this, e), /// provide this canvas and event
        x = pos.x,
        y = pos.y;

    /// check x and y against the grid
}

/// the main function
function getMousePos(canvas, e) {

    /// getBoundingClientRect is supported in most browsers and gives you
    /// the absolute geometry of an element
    var rect = canvas.getBoundingClientRect();

    /// as mouse event coords are relative to document you need to
    /// subtract the element's left and top position:
    return {x: e.clientX - rect.left, y: e.clientY - rect.top};
}

或者可选:

canvas.addEventListener('mousemove', function(e) {

    var pos = getMousePos(canvas, e), /// provide this canvas and event
        x = pos.x,
        y = pos.y;

    /// check x and y against the grid

}, false);

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