javascript - Canvas 绘图边距校正

标签 javascript css canvas

我正在尝试在此 URL 中找到的一些绘图技术:

http://perfectionkills.com/exploring-canvas-drawing-techniques/

我刚刚注意到更高级别的 css 属性未应用于 canvas 元素鼠标事件。有解决此问题的简单方法吗?

<head>

    <meta charset="utf-8">
    <title>Spray Can</title>

    <style>

    body {
        margin: 0;
        padding: 0;
    }

    #container {
        border: 1px solid #ccc;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    #canvas {
    }

    </style>

    <script>

        document.addEventListener('DOMContentLoaded', function () {

            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');
            var isDrawing;

            canvas.onmousedown = function(e) {
                isDrawing = true;
                context.moveTo(e.clientX, e.clientY);
            };

            canvas.onmousemove = function(e) {

                if (isDrawing) {

                    var k = 4;

                    var radgrad = context.createRadialGradient(e.clientX, e.clientY, k, e.clientX, e.clientY, k * 2);

                    radgrad.addColorStop(0, 'rgba(0,0,0,1)');
                    radgrad.addColorStop(0.5, 'rgba(0,0,0,0.5)');
                    radgrad.addColorStop(1, 'rgba(0,0,0,0)');
                    context.fillStyle = radgrad;

                    context.fillRect(e.clientX - k * 2, e.clientY - k * 2, k * 2 * 2, k * 2 * 2);

                }

            };

            canvas.onmouseup = function() {
                isDrawing = false;
            };

        });

    </script>

</head>

<body>

    <div id="container">
        <canvas id="canvas" width="400" height="400"></canvas>
    </div>

</body>

https://jsfiddle.net/crpq8t5q/1/

最佳答案

您需要将鼠标事件的坐标转换为相对于 Canvas 的坐标。

因为在这里你没有触及比例或旋转,所以这只是一个简单的 canvasX = mouseX - canvas.offsetLeftcanvasY = mouseY - canvas.offsetTop

这些 offsetXXX 属性在 Canvas 上可用,但您也可以使用 getBoundingClientRect() 如果您的 css 更复杂(例如嵌套元素不同的可滚动区域)。

但由于每次滚动或调整页面大小时此偏移量都会发生变化,因此您需要更新这些值。

另外,在鼠标事件中创建一个 readialGradient 是一个非常糟糕的主意。此事件可以以非常高的速率触发,并且创建渐变会占用内存。
然后最好创建一个渐变,并修改整个上下文的矩阵,以便将渐变放置在鼠标坐标处:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var isDrawing;

var k = 4;
// create the gradient only once
var radgrad = context.createRadialGradient(0, 0, k, 0, 0, k * 2);
radgrad.addColorStop(0, 'rgba(0,0,0,1)');
radgrad.addColorStop(0.5, 'rgba(0,0,0,0.5)');
radgrad.addColorStop(1, 'rgba(0,0,0,0)');
// get our canvas margins;
var rect;

function getRect() {
  rect = canvas.getBoundingClientRect();
}

canvas.onmousedown = function(e) {
  isDrawing = true;
  context.moveTo(e.clientX, e.clientY);
};

canvas.onmousemove = function(e) {

  if (isDrawing) {
    // normalize our mouse event's coordinates
    var x = e.clientX - rect.left;
    var y = e.clientY - rect.top;
    // change the canvas matrix coordinates so we draw at mouse positions
    context.setTransform(1, 0, 0, 1, x, y)
    context.fillStyle = radgrad;
    context.fillRect(-k * 2, -k * 2, k * 2 * 2, k * 2 * 2);
  }
};

canvas.onmouseup = function() {
  isDrawing = false;
};
var debouncing = false;

function resizeHandler() {
  debouncing = false;
  getRect();
}
window.onscroll = window.onresize = function() {
  // debounce the events
  if (!debouncing) {
    requestAnimationFrame(resizeHandler);
  }
  debouncing = true;
}

getRect();
body {
  margin: 0;
  padding: 0;
}
#container {
  border: 1px solid #ccc;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
#canvas {}
<div id="container">
  <canvas id="canvas" width="400" height="400"></canvas>
</div>

关于javascript - Canvas 绘图边距校正,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41204169/

相关文章:

javascript - 对象字面量/初始化器中的自引用

css - 为 SVG 渐变条设置动画,使其看起来像填充了停止色

javascript - Konva.js 带文本的 Img 元素周围的虚线描边

html - 如何在单个 div 元素中绘制四个圆圈?

javascript - 在javascript中下载文件

javascript - 使用 setTimeout 在 Canvas 上绘制图像

javascript - 在这种情况下,为什么我必须单击两次才能加载图像?

javascript - 在 Nodejs 中对集合项运行查询

javascript - google maps api v3 - javascript - 透视/倾斜(不是卫星!)?

javascript - 读取与 JavaScript 文件相同目录中的文件