在HTML5画布中的鼠标移动上绘制半透明线 [英] Drawing semi-transparent lines on mouse movement in HTML5 canvas
问题描述
我正在尝试让用户通过使用绘画工具在区域上绘画来指定区域,该工具在画布上绘制半透明线。它的目的是为要在画布上绘制的图像指定一个蒙版。
I'm trying to let users specify an area by painting over it with a "paint" tool that draws semi-transparent lines on a canvas. Its purpose is specifying a "mask" for an image that will be drawn below on the canvas.
这是我到目前为止尝试过的:
This is what I tried so far:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var canvasPos = canvas.getBoundingClientRect();
var dragging = false;
drawImage();
$(canvas).mousedown(mouseDown);
$(canvas).mouseup(mouseUp);
$(canvas).mousemove(mouseMove);
function drawImage() {
var img = new Image();
img.src = 'http://img2.timeinc.net/health/img/web/2013/03/slides/cat-allergies-400x400.jpg';
img.onload = function () {
ctx.drawImage(img, 0, 0);
};
}
function mouseDown(e) {
var pos = getCursorPosition(e);
dragging = true;
ctx.strokeStyle = 'rgba(0, 100, 0, 0.25)';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 15;
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
}
function mouseUp(e) {
dragging = false;
}
function mouseMove(e) {
var pos, i;
if (!dragging) {
return;
}
pos = getCursorPosition(e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
}
function getCursorPosition(e) {
return {
x: e.clientX - canvasPos.left,
y: e.clientY - canvasPos.top
};
}
- 链接到上述代码的jsfiddle: http://jsfiddle.net/s34PL/2 /
- Link to a jsfiddle of the above code: http://jsfiddle.net/s34PL/2/
此示例代码的问题在于,随后绘制的像素使不透明性越来越少。我认为这是因为该行的宽度为15像素(但是我希望该宽度如此)。
The issue with this example code is that subsequent pixels that are drawn are making the opacity becomes less and less visible. I think it's because the line is 15 pixels wide (but I want it that wide though).
如何解决此问题?
谢谢!
推荐答案
问题是您一次又一次地绘制了整个路径:
The problem is that you are drawing the whole path again and again:
function mouseMove(e) {
...
ctx.stroke(); // Draws whole path which begins where mouseDown happened.
}
您只需要绘制路径的新部分( http://jsfiddle.net/jF9a6/ )。然后...您遇到了15像素的线宽问题。
You have to draw only the new segment of the path (http://jsfiddle.net/jF9a6/). And then ... you have the problem with the 15px width of the line.
那么如何解决这个问题?我们必须像您一样立即绘制线条,但要避免在现有线条的上方绘画。这是代码: http://jsfiddle.net/yfDdC/
So how to solve this? We have to draw the line at once as you did, but avoid painting on top of existing lines. Here is the code: http://jsfiddle.net/yfDdC/
最大的变化是 paths
数组。它包含路径,是的:-)路径是存储在 mouseDown
和 mouseMove
函数中的点的数组。在mouseDown函数中创建新路径:
The biggest change is the paths
array. It contains yeah, paths :-) A path is an array of points stored in mouseDown
and mouseMove
functions. New path is created in mouseDown function:
paths.push([pos]); // Add new path, the first point is current pos.
在mouseMove中,将当前鼠标位置添加到 paths
数组并刷新图像。
In the mouseMove you add current mouse position to the last path in paths
array and refreshs the image.
paths[paths.length-1].push(pos); // Append point tu current path.
refresh();
refresh()
函数清除全部内容
function refresh() {
// Clear canvas and draw the cat.
ctx.clearRect(0, 0, ctx.width, ctx.height);
if (globImg)
ctx.drawImage(globImg, 0, 0);
for (var i=0; i<paths.length; ++i) {
var path = paths[i];
if (path.length<1)
continue; // Need at least two points to draw a line.
ctx.beginPath();
ctx.moveTo(path[0].x, path[0].y);
...
for (var j=1; j<path.length; ++j)
ctx.lineTo(path[j].x, path[j].y);
ctx.stroke();
}
}
这篇关于在HTML5画布中的鼠标移动上绘制半透明线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!