我设置了一个画布并应用 setTransform 来针对特定设备将其缩小。在一台 chromium 55 设备上,该画布首先可以正常工作,但在进行一些绘制之后,它首先突然从视图中消失,返回后它会继续绘制而不进行缩放。可能是什么原因?
绘图时我使用drawImage。我发现问题出在将数据从图像绘制到画布的步骤中,但我没有任何好主意如何调试或克服该问题。
所以步骤是
我设置了不同的检查来处理异步进程和可能的错误,但我没有收到任何错误。我试图弄清楚这是否可能是由于内存问题,但当我在开发上运行它时似乎没有重大问题。如果我绘制得更频繁,错误就会发生得更快,所以如果我在错误发生之前更快地绘制,我就可以减少绘制次数。令人惊奇的是,这个问题很早就存在了,本以为可以修正,但在重构时又出现了。上次它刚刚停止发生。我比较了这些变化,没有发现重大逻辑变化。在重构中我不得不改变大小,并将代码分成不同的代码块,但我回溯了步骤,逻辑是一样的。
我有什么可以尝试的想法吗?
这不是最低限度的可重现性,因为常规 PC 浏览器上不会出现错误:
const scaleFactor = 1280/1920
const ctx = element.getContext('2d')
ctx.setTransform(
scaleFactor,
0,
0,
scaleFactor,
0,
0
)
ctx.save()
//Here we do some other stuff e.g. fetch data. Then we call this function
drawImage(
ctx,
centerX,
centerY,
imgWidth,
imgHeight,
source,
imageElement,
checksum
) {
return new Promise((resolve) => {
let broken = false
try {
if (
imageElement &&
imageElement.getAttribute('data-loaded') === 'true'
) {
ctx.drawImage(
imageElement, centerX, centerY, imgWidth, imgHeight
)
if (checksum)
imageElement.setAttribute('data-checksum', checksum)
return resolve(imageElement)
}
} catch (e) {
// The image element might be in a "broken" state and the draw fails
broken = true
}
const img = this.cacheImage(
source,
imgWidth,
imgHeight,
checksum,
(image) => {
if (
!checksum ||
image.getAttribute('data-checksum') ===
this.renderChecksum.toString()
) {
ctx.drawImage(image, centerX, centerY, img.width, img.height)
resolve(image)
}
},
broken
)
})
},
//Before redrawing we call
ctx.clearRect()
我想通了。问题是画布本身没有相应地缩放,因此这个旧浏览器在尝试在其上绘制转换后的数据时开始出现故障。通过在设置变换之前使用scaleFactor缩放画布的宽度和高度来解决该问题。
问题很难解决,因为我们测试过的所有其他设备在大画布元素的角落绘制数据时没有任何问题。