HTML画布中光标未对齐。

4

我有以下的Javascript、HTML和CSS代码

function distanceBetween(point1, point2) {
    return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
}

function angleBetween(point1, point2) {
    return Math.atan2(point2.x - point1.x, point2.y - point1.y);
}

function draw() {
    var img = new Image();
    img.src = 'http://www.tricedesigns.com/wp-content/uploads/2012/01/brush2.png';

    var el = document.getElementById('DrawingPattern');
    var ctx = el.getContext('2d');
    ctx.lineJoin = ctx.lineCap = 'round';

    var isDrawing, lastPoint;

    el.onmousedown = function (e) {
        isDrawing = true;
        lastPoint = {x: e.clientX, y: e.clientY};
    };

    el.onmousemove = function (e) {
        if (!isDrawing) return;

        var currentPoint = {x: e.clientX, y: e.clientY};
        var dist = distanceBetween(lastPoint, currentPoint);
        var angle = angleBetween(lastPoint, currentPoint);

        for (var i = 0; i < dist; i++) {
            x = lastPoint.x + (Math.sin(angle) * i) - 25;
            y = lastPoint.y + (Math.cos(angle) * i) - 25;
            ctx.drawImage(img, x, y);
        }

        lastPoint = currentPoint;
    };

    el.onmouseup = function () {
        isDrawing = false;
    };
}
html, body {
    color: #fff;
    background: #000;
    font-family: "Lucida Grande";
}

canvas{
    position: static;
    cursor: move;
    margin: auto;
    width: 70%;
    border: 3px solid #73AD21;
    background: white;
    overflow: visible;
}
<body onload=draw()>
<canvas width="1024" height="649" id="DrawingPattern">
<!-- add fallback content-->
</canvas>
</body>

整个代码都可以正常运行,唯一的问题是当我在画布上绘制时,光标与实际位置不对齐。因此,当我绘制时,线条会出现在光标实际位置上方或下方的另一个位置。我已经尝试了不同的方法,但我想这可能是一种缩放问题,但我不知道怎么解决。
2个回答

2
这是一个缩放问题。即使通过设置CSS宽度百分比来缩放画布元素,绘图区域的大小也不会改变。您在屏幕空间中获得鼠标坐标,但在绘制时需要将其转换为画布空间。
为此,请计算考虑“el.width”(画布宽度)和“el.offsetWidth”(元素宽度)之间差异的比例尺。由于画布通过保持纵横比例按比例缩放,因此可以对X和Y坐标使用相同的缩放。
我添加了一个“elementScale()”函数,并更新了代码以将“clientX”和“clientY”的值与返回值相乘。

function distanceBetween(point1, point2) {
    return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
}

function angleBetween(point1, point2) {
    return Math.atan2(point2.x - point1.x, point2.y - point1.y);
}

function elementScale(el) {
    return el.offsetWidth === 0 ? 0 : (el.width / el.offsetWidth);
}

function draw() {
    var img = new Image();
    img.src = 'http://www.tricedesigns.com/wp-content/uploads/2012/01/brush2.png';

    var el = document.getElementById('DrawingPattern');
    var ctx = el.getContext('2d');
    ctx.lineJoin = ctx.lineCap = 'round';

    var isDrawing, lastPoint;

    el.onmousedown = function (e) {
        var scale = elementScale(el);
        isDrawing = true;
        lastPoint = {x: e.clientX * scale, y: e.clientY * scale};
    };

    el.onmousemove = function (e) {
        if (!isDrawing) return;

        var scale = elementScale(el);
        var currentPoint = {x: e.clientX * scale, y: e.clientY * scale};
        var dist = distanceBetween(lastPoint, currentPoint);
        var angle = angleBetween(lastPoint, currentPoint);

        for (var i = 0; i < dist; i++) {
            x = lastPoint.x + (Math.sin(angle) * i) - 25;
            y = lastPoint.y + (Math.cos(angle) * i) - 25;
            ctx.drawImage(img, x, y);
        }

        lastPoint = currentPoint;
    };

    el.onmouseup = function () {
        isDrawing = false;
    };
}
html, body {
    color: #fff;
    background: #000;
    font-family: "Lucida Grande";
}

canvas{
    position: static;
    cursor: move;
    margin: auto;
    width: 70%;
    border: 3px solid #73AD21;
    background: white;
    overflow: visible;
}
<body onload=draw()>
<canvas width="1024" height="649" id="DrawingPattern">
<!-- add fallback content-->
</canvas>
</body>


1

就像DarthJDG所说的那样,这是你的CSS缩放问题。

你可以通过删除canvas上的CSS width:70%,并像往常一样进行调整来解决问题。

CSS代码

    html, body {
        color: #fff;
        background: #000;
        font-family: "Lucida Grande";
    }

    canvas{
        position: static;
        cursor: move;
        margin: auto;
        //width:70%; //REMOVED
        border: 3px solid #73AD21;
        background: white;
        overflow: visible;
    }

JavaScript 代码
for (var i = 0; i < dist; i++) {
    x = lastPoint.x + (Math.sin(angle) * i) - 25; //CHANGED
    y = lastPoint.y + (Math.cos(angle) * i) - 25; //CHANGED
    ctx.drawImage(img, x, y);
}

只需移除CSS的宽度,你的缩放就会恢复正常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接