javascript - 光标未使用 HTML Canvas 对齐

标签 javascript html canvas scaling cursor-position

我有以下 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>

整个代码都有效,我遇到的唯一问题是当我开始在 Canvas 上绘图时,光标与光标的有效位置不对齐。因此,当我绘制它时,线条会位于另一个位置,高于或低于光标的实际位置。我尝试了不同的方法,但我猜是某种缩放问题,但我无法解决它。

最佳答案

这是一个缩放问题。即使您通过按百分比设置 CSS 宽度来缩放 Canvas 元素,绘图区域的大小也不会改变。你在屏幕空间中获取鼠标坐标,但在绘制时需要转换到 Canvas 空间。

为此,通过考虑 el.width( Canvas 宽度)和 el.offsetWidth(元素宽度)之间的差异来计算比例。由于通过保持纵横比按比例缩放 Canvas ,因此可以对 X 和 Y 坐标使用相同的缩放比例。

我添加了一个 elementScale() 函数并更新了代码以将 clientXclientY 与返回值相乘。

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>

关于javascript - 光标未使用 HTML Canvas 对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50966385/

相关文章:

javascript - 如何在圆形 Canvas 上添加线条

javascript - jQuery: .click() 和 .on ("click"之间的区别)

php - jQuery 在 javascript 中序列化

html - 具有不透明背景的重叠 div

c# - 使用 MVVM 以编程方式创建 XAML Canvas

javascript - canvg 是未定义的错误

JavaScript 日期 ISO8601

javascript - 如何在只读输入字段上设置自定义有效性

javascript - 带有 JS 的自适应菜单

css - Div 图层应放置在 Flash 影片之上