#javascript #node.js #canvas
#javascript #node.js #холст
Вопрос:
Я очень новичок в работе с node.js и такие пакеты, как express и canvas, поэтому я приношу извинения, если в моем коде есть какие-либо вопиюще очевидные ошибки и если мне потребуется немного времени, чтобы разобраться в каких-либо вопросах или решениях.
В настоящее время я работаю над настройкой версии — https://github.com/Nooshu/node-countdown-gif . Сгенерированный canvas таймер обратного отсчета для использования в электронных письмах. Мои настройки минимальны, все, что я сделал до сих пор, это загрузить шрифт и добавить еще немного из URL для запроса.
Проблема, с которой я сталкиваюсь, заключается в том, что вместо плоского цветного или градиентного фона я хотел бы, если возможно, загрузить внешнее изображение в качестве фонового изображения за таймером, похоже, это должно быть возможно, но я просто не могу заставить его работать.
Это блок кода, который генерирует визуальное изображение таймера с плоским цветным фоном.
if(typeof timeResult === 'object'){
for(let i = 0; i < this.frames; i ){
// extract the information we need from the duration
let days = Math.floor(timeResult.asDays());
let hours = Math.floor(timeResult.asHours() - (days * 24));
let minutes = Math.floor(timeResult.asMinutes()) - (days * 24 * 60) - (hours * 60);
let seconds = Math.floor(timeResult.asSeconds()) - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60);
// make sure we have at least 2 characters in the string
days = (days.toString().length == 1) ? '0' days : days;
hours = (hours.toString().length == 1) ? '0' hours : hours;
minutes = (minutes.toString().length == 1) ? '0' minutes : minutes;
seconds = (seconds.toString().length == 1) ? '0' seconds : seconds;
// build the date string
let string = [days, 'd ', hours, 'h ', minutes, 'm ', seconds, 's'].join('');
// paint BG
ctx.fillStyle = this.bg;
ctx.fillRect(0, 0, this.w, this.h);
// paint text
ctx.fillStyle = this.textColor;
ctx.fillText(string, this.halfWidth, this.halfHeight);
// add finalised frame to the gif
enc.addFrame(ctx);
// remove a second for the next loop
timeResult.subtract(1, 'seconds');
}
}
Мне нужно, чтобы это фоновое изображение создавалось во время каждого цикла, в противном случае таймер накладывается поверх каждого цикла. Я попробовал 2 разных метода, которые я видел для загрузки во внешнее изображение. Сначала я вообще не мог приступить к работе, изображение не отображалось. См. Метод :
let img = new Canvas(this.w, this.h);
img.src = 'https://via.placeholder.com/600x200.png';
img.onload = function(){
context.drawImage(img, 0, 0, this.w, this.h);
}
Я добился большего успеха со своим вторым методом, но все еще не могу заставить его работать. Если поместить его ранее в коде (до цикла for), он успешно загружает изображение, но таймер не отображается. Если поместить его в цикл for, он выдает следующую ошибку для каждой итерации цикла. Это блок кода, за которым следует ошибка. Примечание: Эта ошибка появляется только при размещении блока кода в цикле for .
let imgUrl = 'https://via.placeholder.com/'
loadImage(imgUrl image '.png').then(image => {
context.drawImage(image, 0, 0, 600, 200)
const buffer = canvas.toBuffer('image/png')
res.set({ 'Content-Type': 'image/png' });
res.send(buffer)
})
Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()
Кто-нибудь может поддержать меня в решении моей проблемы?
Спасибо
Ответ №1:
Я понял это.
Ранее в моем коде была функция инициализации, которая подготавливает мой таймер к сборке, перемещая функцию onload внутри этой функции, а затем передавая выходные данные функции encode, которой разрешено работать должным образом при размещении функции drawImage в цикле for, определенном выше —
if (imageBgSrc !== null) {
let img = new Canvas.Image;
img.src = imageBgSrc;
img.onload = function() {
$this.encode(timeResult, img, cb);
}
} else {
this.encode(timeResult, null, cb);
}
encode: function (timeResult, image, cb) {
// Other code
if (image !== null) {
ctx.drawImage(image, 0, 0, this.width, this.height)
}
// Other code
}