Javascript 在html5画布标记中缩放背景模式填充

Javascript 在html5画布标记中缩放背景模式填充,javascript,canvas,graphics,html5-canvas,scaling,Javascript,Canvas,Graphics,Html5 Canvas,Scaling,我有一个画布标签,显示一组路径和矩形 我使用ctx.scale(2,2)函数放大这些路径和矩形,然后用新的比例重新绘制它们,使它们清晰 我希望一些矩形有一个简单的纹理背景,即一个像素黑一个白,但是当我将纹理作为填充应用到缩放矩形时,画布也会缩放背景图案。我想背景图案保持在原来的一个像素黑色,一个像素白色的比例。但似乎不知道如何做到这一点,它看起来模糊。我举了一个例子: 谢谢你的帮助 更新我将背景理解为所有形状背后的全局背景。但如果我现在理解正确的话,这似乎是形状的填充——在这种情况下,你需要做一

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

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

我希望一些矩形有一个简单的纹理背景,即一个像素黑一个白,但是当我将纹理作为填充应用到缩放矩形时,画布也会缩放背景图案。我想背景图案保持在原来的一个像素黑色,一个像素白色的比例。但似乎不知道如何做到这一点,它看起来模糊。我举了一个例子:


谢谢你的帮助

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

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

要么:

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>
#container {
    position:relative;
    }
#container > canvas {
    position:absolute;
    left:0;
    top:0;
    }
然后获取每个项目的上下文并根据需要绘制(伪ish):


现在,这些不会相互影响。

为了子孙后代,我编写了一个Context2D包装器,自动完成这项工作,并添加了一些跟踪/调试功能来帮助您绘制。它实际上并没有牺牲任何性能

你可以在这里找到它:


或者如果您正在使用npm(带有网页包或其他东西)
npm安装context-2d-tracked

谢谢您的选择!你能详细说明一下第一点吗?如果我理解正确-我应该在fillRect之后进行缩放-但是在这种情况下矩形不会缩放?我更新了JSFIDLE,但看不出如何使它工作?@SimonKenyonShepard啊,我的错。我把背景理解为全球背景。如果需要使用不受缩放影响的背景填充矩形,则需要手动缩放元素,即
fillRect(x*scale、y*scale、width*scale、height*scale)
等,并且仅对其他形状使用.scale()(或手动缩放)。你可以很容易地为你做包装函数。嗨,对不起,我不确定我是否理解-这不就是像示例中那样缩放背景吗?
#container {
    position:relative;
    }
#container > canvas {
    position:absolute;
    left:0;
    top:0;
    }
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);