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

查看:21
本文介绍了在 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.

这是我目前尝试过的:

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

此示例代码的问题在于,后续绘制的像素使不透明度变得越来越不可见.我认为这是因为线宽 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).

我该如何解决这个问题?

How can I solve this issue?

谢谢!

推荐答案

问题是你一次又一次地绘制整个路径:

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/).然后……您的线条宽度有 15px 的问题.

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 数组.它包含是的,路径 :-) 路径是存储在 mouseDownmouseMove 函数中的点数组.在 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() 函数清除整个画布,再次绘制猫并绘制每条路径.

The refresh() function clears the whole canvas, draws the cat again and draws every path.

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天全站免登陆