Я настроил холст и применил setTransform, чтобы уменьшить его масштаб для конкретных устройств. На одном устройстве chromium 55 этот холст сначала работает корректно, но после некоторых рисунков он внезапно сначала пропадает из поля зрения и после возвращения продолжает рисовать без масштабирования. Что может быть причиной?
Во время рисования я использую drawImage. Мне удалось выяснить, что проблема возникает на этапе рисования данных из изображений на холст, но у меня нет хороших идей, как отладить или решить эту проблему.
Итак, шаги
Я установил различные проверки для обработки асинхронных процессов и возможных ошибок, но ошибок не получаю. Я пытался выяснить, может ли это быть связано с проблемами с памятью, но, похоже, при запуске на dev не возникло серьезных проблем. Ошибка возникает раньше, если я рисую чаще, поэтому я смогу рисовать меньше, если буду делать это быстрее до появления ошибки. Удивительно то, что эта проблема существовала и раньше и считалась исправленной, но в ходе рефакторинга она появилась вновь. В прошлый раз это просто перестало происходить. Я сравнил изменения, и никакой существенной логики не изменилось. При рефакторинге мне пришлось изменить размеры и разделить код на разные блоки кода, но я проследил шаги, и логика та же.
Есть идеи, которые я мог бы попробовать?
Это не является минимально воспроизводимым, поскольку ошибка не возникает в обычных браузерах ПК:
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()
Я действительно не могу привести пример, который бы гарантированно воспроизвел проблему, поскольку она возникает только на устройстве. У меня даже есть другие устройства с таким же браузером, которые ведут себя иначе. Поэтому минимальный воспроизводимый пример создать невозможно. Мне нужны были идеи, чтобы попытаться найти решение этой проблемы.
Теперь я попробовал изменить значения, которые привели бы к рисованию половины пикселя. Это не устранило проблему.
Хром 55? Это как... много лет назад, не так ли? Разве вы не можете попросить его обновить? Одной из возможных причин может быть изменение размера элемента холста или, возможно, потеря контекста, но на самом деле обе эти причины будут выглядеть как ошибки.
К сожалению, я не могу. Среды устройств заблокированы и не могут быть обновлены.
Я понял. Проблема заключалась в том, что сам холст не был масштабирован соответствующим образом, поэтому один старый браузер начал работать со сбоями при попытке нарисовать на нем преобразованные данные. Проблема решается путем масштабирования ширины и высоты холста с помощью ScaleFactor перед установкой преобразования.
Проблему было трудно решить, поскольку все другие протестированные нами устройства не имели проблем с отрисовкой данных в углу большого элемента холста.
Трудно сказать, не видя кода. Пожалуйста, прочитайте Как спросить . Затем отредактируйте с помощью минимально воспроизводимого примера.