在HTML5画布中的鼠标移动上绘制半透明线 [英] Drawing semi-transparent lines on mouse movement in HTML5 canvas

查看:128
本文介绍了在HTML5画布中的鼠标移动上绘制半透明线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让用户通过使用绘画工具在区域上绘画来指定区域,该工具在画布上绘制半透明线。它的目的是为要在画布上绘制的图像指定一个蒙版。

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
    };
}

  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆