1

我想制作一个十字准线网格(每 10 像素)。我有很多问题。可以用比 3x For 循环更简单的方式完成吗? http://jsfiddle.net/TnnRp/1/

var canvas = document.getElementById('grid');
var context = canvas.getContext('2d');
// grid
var width = canvas.width;
var height = canvas.height;
var p = 10;
var h = 10;
for (var i = 10; i <= width - 5; i += 10) {
    for (var e = 10; e <= height - 5; e += 10) {
        context.moveTo(h + 0.5, e - 1);
        context.lineTo(h + 0.5, e + 2);
    }
    h += 10;
    for (var f = 10; f <= width - 5; f += 10) {
        context.moveTo(f - 1, p + 0.5);
        context.lineTo(f + 2, p + 0.5);
    }
    p += 10;
}
context.stroke();
4

2 回答 2

2

在肯的帮助下。 工作的jsFiddle

var canvas = document.getElementById('grid');
var context = canvas.getContext('2d');

var width = canvas.width,
    height = canvas.height;
context.moveTo(10.5, 10 - 1);
context.lineTo(10.5, 10 + 2);
context.moveTo(10.5 -1, 10.5);
context.lineTo(10.5 +2, 10.5);
context.stroke();
var h=10,
    p=10;

for (i = 0; i < width; i += p) {
    p *= 2;
    context.drawImage(canvas, p, 0);
}
for(i = 0; i < height; i+=h) {
    h *= 2;
    context.drawImage(canvas, 0, h);
}

十字准线网格决赛

于 2013-07-04T23:37:54.400 回答
2

您始终可以将其减少到两个循环,并且也有两种方法。但在此之前:我同意 markE - 您的代码就可以了。

我的版本是减少循环并展示一种优化其速度的方法:

//pre-translate to force anti-alias
context.translate(0.5, 0.5);

现在我们只画一个十字准线:

var cc = 1; //cross-hair size

context.moveTo(p / 2, h / 2 - cc);
context.lineTo(p / 2, h / 2 + cc);
context.moveTo(p / 2 - cc, h / 2);
context.lineTo(p / 2 + cc, h / 2);

context.stroke();

现在我们“blit”我们的心,首先是水平的:

//replicate drawn cross-hair = faast.
for (i = 0; i < width - p; i += p) {
    if (i > 0) p *= 2;
    context.drawImage(canvas, 0, 0, p, h, p, 0, p,h);
}

现在我们垂直复制这条线:

for(i = 0; i < height; i+=h) {
    if (i > 0) h *= 2;
    context.drawImage(canvas, 0, 0, width, h, 0, h, width, h);
}

请注意,我们不只是复制一行,而是当我们绘制一个副本时,我们复制这两个,然后我们跳过四个并复制四个等等。

这种方法非常快,并且是浏览器(或者更确切地说是浏览器使用的系统功能)也复制模式(但使用内部编译代码)的方式。您也可以使用第一个十字准线在屏幕外画布上设置图案,并用可能更快的缺口填充画布。

Updated fiddle

于 2013-07-04T23:03:38.483 回答