2

マウスが動くたびに円が ax と y の位置に配置される単純な HTML5 Canvas 描画アプリを作成しています。(非常に一般的ですが解決されていない) 問題は、マウスが非常に速く動かされると (マウス移動イベントがトリガーされるよりも速く移動するなど)、円の間にスペースができてしまうことです。

Bresenham の直線アルゴリズムを使用して、隙間の間に円を描くことに成功しました。ただし、別の問題が発生しました。色が半透明の場合、意図しないフェード トゥ ダーク エフェクトが発生します。

次に例を示します。

http://i.stack.imgur.com/wY4BM.png

なぜこれが起こっているのかわかりません。Bresenham のライン アルゴリズムを使用して、2 点間を適切に補間するにはどうすればよいでしょうか? それとも他のアルゴリズム?

ここに私のコードがあります: http://jsfiddle.net/E5NBs/

var x = null;
var y = null;
var prevX = null;
var prevY = null;
var spacing = 3;
var drawing = false;
var size = 5;
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

function createFlow(x1, y1, x2, y2, callback) {
    var dx = x2 - x1;
    var sx = 1;
    var dy = y2 - y1;
    var sy = 1;
    var space = 0;

    if (dx < 0) {
        sx = -1;
        dx = -dx;
    }

    if (dy < 0) {
        sy = -1;
        dy = -dy;
    }

    dx = dx << 1;
    dy = dy << 1;

    if (dy < dx) {
        var fraction = dy - (dx >> 1);

        while (x1 != x2) {
            if (fraction >= 0) {
                y1 += sy;
                fraction -= dx;
            }

            fraction += dy;
            x1 += sx;

            if (space == spacing) {
                callback(x1, y1);
                space = 0;
            } else {
                space += 1;
            }
        }
    } else {
        var fraction = dx - (dy >> 1);

        while (y1 != y2) {
            if (fraction >= 0) {
                x1 += sx;
                fraction -= dy;
            }

            fraction += dx;
            y1 += sy;

            if (space == spacing) {
                callback(x1, y1);
                space = 0;
            } else {
                space += 1;
            }
        }
    }

    callback(x1, y1);
}

context.fillStyle = '#FFFFFF';
context.fillRect(0, 0, 500, 400);

canvas.onmousemove = function(event) {
    x = parseInt(this.offsetLeft);
    y = parseInt(this.offsetTop);

    if (this.offsetParent != null) {
        x += parseInt(this.offsetParent.offsetLeft);
        y += parseInt(this.offsetParent.offsetTop);
    }

    if (navigator.appVersion.indexOf('MSIE') != -1) {
        x = (event.clientX + document.body.scrollLeft) - x;
        y = (event.clientY + document.body.scrollTop) - y;
    } else {
        x = event.pageX - x;
        y = event.pageY - y;
    }

    context.beginPath();
    if (drawing == true) {
        if (((x - prevX) >= spacing || (y - prevY) >= spacing) || (prevX - x) >= spacing || (prevY - y) >= spacing) {
            createFlow(x, y, prevX, prevY, function(x, y) {
                context.fillStyle = 'rgba(0, 0, 0, 0.1)';
                context.arc(x, y, size, 0, 2 * Math.PI, false);
                context.fill();
            });

            prevX = x, prevY = y;
        }
    } else {
        prevX = x, prevY = y;
    }
};

canvas.onmousedown = function() {
    drawing = true;
};

canvas.onmouseup = function() {
    drawing = false;
};
4

3 に答える 3