2

我有一个显示一组路径和矩形的画布标签。

我使用 ctx.scale(2,2) 函数放大这些路径和矩形,然后用新的比例重新绘制它们,使它们清晰。

我想为一些矩形设置一个简单的纹理背景,即一个像素黑色一个白色,但是当我将纹理作为填充应用到缩放的矩形时,画布也会缩放背景图案。我希望背景图案保持在一个像素黑色,一个像素白色的原始比例。但似乎无法弄清楚如何在它看起来模糊的情况下做到这一点。我在这里有一个例子:http: //jsfiddle.net/4UxWg/

var patternCanvas = document.createElement('canvas');
var pattern_ctx = patternCanvas.getContext("2d");
patternCanvas.width = 1;
patternCanvas.height = 2;

pattern_ctx.fillRect(0,0,1,1);


var mainCanvas = document.createElement('canvas');
var ctx = mainCanvas.getContext("2d");
mainCanvas.height = 500;
mainCanvas.width = 400;

document.getElementsByTagName("body")[0].appendChild(mainCanvas);

//scale function - remove this line to see how the pattern should look like
ctx.scale(5,5); 

var pattern = ctx.createPattern(patternCanvas, "repeat");
ctx.fillStyle= pattern;

ctx.fillRect(2,2,40,40); //fillRect looks wierd and pattern is no longer 1px by 1px

谢谢你的帮助!

4

2 回答 2

1

更新我将背景读作所有形状背后的全局背景。但如果我现在正确理解它似乎是形状的填充- 在这种情况下,你需要做一些稍微不同的事情:

为了使填充图案不受形状缩放尺寸的影响,您需要手动缩放形状 -

任何一个:

var scale = 5;

ctx.fillRect(x * scale, y * scale, w * scale, h * scale);

或使用包装函数:

function fillRectS(x, y, w, h) {
    ctx.fillRect(x * scale, y * scale, w * scale, h * scale);
}

fillRectS(x, y, w, h);

对于中风,您只需执行相同操作:

function lineWidthS(w) {
    ctx.lineWidth = w * scale;
}

等等(线条、移动到、弧线)。这将允许您缩放所有形状,但将图案填充保持在 1:1 的比例。开销将是最小的。

旧答案-

解决这个问题至少有两种方法:

1)您可以在填充模式时重置翻译,然后立即重新应用转换。

/// reset
ctx.transform(1, 0, 0, 1, 0, 0);

ctx.fillStyle = pattern;
ctx.fillRect(x, y, w, h);

ctx.scale(sx, sy);

2)将画布分层,以便在一个画布上单独绘制背景,并使用顶部画布绘制需要按比例绘制的任何其他内容。

同时使用不同的比例和变换是使用分层画布的一个很好的案例场景。

HTML:

<div id="container">
    <canvas id="bg" ... ></canvas>
    <canvas id="main" ... ></canvas>
</div>

CSS:

#container {
    position:relative;
    }
#container > canvas {
    position:absolute;
    left:0;
    top:0;
    }

然后获取每个上下文并根据需要绘制(伪ish):

var bgCtx = bg.getContext('2d');
var ctx = main.getContext('2d');

... other setup code here ...

/// will only affect foreground canvas
ctx.scale(5, 5);

/// will only fill background canvas
bgCtx.fillStyle = pattern;
bgCtx.fillRect(x, y, w, h);

现在这些不会相互影响。

于 2013-11-02T19:04:36.677 回答
0

为了后代,我编写了一个 Context2D 包装器,它会自动执行此操作并添加一些跟踪/调试功能来帮助您绘制。它实际上并没有牺牲任何性能!

你可以在这里找到它:https ://github.com/LemonPi/Context2DTracked

或者,如果您使用的是 npm(使用 webpack 或其他东西)npm install context-2d-tracked

于 2019-03-02T06:27:46.090 回答