我正在尝试在此网址中找到的一些绘制技巧:
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>
答案 0 :(得分:1)
您需要将鼠标事件的坐标转换为相对于画布的坐标。
由于此处您无法触及比例或旋转,因此这只是一个简单的canvasX = mouseX - canvas.offsetLeft
和canvasY = mouseY - canvas.offsetTop
。
这些offsetXXX
属性在画布上可用,但您也可以使用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();
&#13;
body {
margin: 0;
padding: 0;
}
#container {
border: 1px solid #ccc;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#canvas {}
&#13;
<div id="container">
<canvas id="canvas" width="400" height="400"></canvas>
</div>
&#13;