为什么在HTML画布中两个形状之间会出现白色?

bqucvtff  于 2023-01-07  发布在  其他
关注(0)|答案(1)|浏览(161)

为什么JS画布上两个图形之间会出现白色?
我正在做一个游戏与JS / TS(我用的是MacBook Pro),与HTML5画布,并有一个意想不到的白色出现在Safari浏览器中的两个形状之间:

但我在chrome中运行完全相同的代码,一切都很好:

为什么会这样?我该怎么补救?
我用来渲染的代码

CONTEXT.drawImage(
    CACHES.get(this.materialURL),
    (this.rect.x - camera.location.x) * GRID_W,
    (this.rect.y - camera.location.y) * GRID_H,
    GRID_W,
    GRID_H,
);
e4yzc0pl

e4yzc0pl1#

渲染伪影

更多信息?

发生这种情况的原因有很多。大多数是舍入错误的结果。有时错误发生在JavaScript中,其他时候则发生在渲染中。
JS引擎之间存在细微的差异(由硬件、操作系统、驱动程序和/或引擎实现导致),这可能会导致设备之间呈现的工件不同。
即使在相同的浏览器、相同的操作系统和使用相同的硬件上,渲染实现也存在重大差异,具体取决于设置(标志)。
如果没有更多的信息,我只能猜测你的工件是从哪里来的,甚至你是如何捕捉到示例图像的也会改变解决方案。

尝试的事情

1.尝试通过关闭2D上下文平滑来使用最近像素查找

ctx.imageSmoothingEnabled = false;

重新启用

ctx.imageSmoothingEnabled = true;

1.通过在获取上下文时设置willReadFrequently标志来使用软件渲染(CPU)。

const ctx = canvas.getContext("2d", {willReadFrequently: true});

注意这会大大降低速度

1.使用上下文选项alpha禁用画布Alpha(以阻止BG出现在接缝处)

const ctx = canvas.getContext("2d", {alpha: false});

1.确保源图像分辨率与渲染大小匹配。
换句话说

const img = CACHES.get(this.materialURL);
const isSameRes  = img.width === GRID_W && img.height === GRID_H;

isSameRes是否应等于true

注意如果imgImage的示例,则使用naturalWidthnaturalHeight

1.在源图像的每条边上扩展1像素,复制边缘像素,如下图所示。这将防止透明边缘像素渗入渲染结果。

然后渲染内部原始图像,如下所示

const img = CACHES.get(this.materialURL);
ctx.drawImage(
    img,
    1, 1, img.width - 2, img.height - 2,
    (this.rect.x - camera.location.x) * GRID_W,
    (this.rect.y - camera.location.y) * GRID_H,
    GRID_W,
    GRID_H,
);

注意这将增加少量开销。

1.通过地板坐标和强制常量为整数来确保整数坐标。

// When defining GRID_W and GRID_H (assuming positive integer values) 
// Force internal type to int32 by using bitwise operation on values
// Note this may not do anything
const GRID_W = 32 | 0;
const GRID_H = 32 | 0;

// Render using floored coordinates.
ctx.drawImage(
    CACHES.get(this.materialURL),
    Math.floor((this.rect.x - camera.location.x) * GRID_W),
    Math.floor((this.rect.y - camera.location.y) * GRID_H),
    GRID_W,
    GRID_H,
);

更多

还有更多的选择,但如果没有所需的信息,我会浪费你的时间。

相关问题