Подскажите, почему при таком коде:
<html>
<body>
<canvas id = 'c01' style = "width: 800; border: 1px solid black;"></canvas>
<script>
var canvas = document.getElementById("c01");
var ctx = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
ctx.beginPath();
ctx.drawImage(image, 0, 0);
ctx.lineWidth = "6";
ctx.strokeStyle = "red";
ctx.rect(canvas.width / 4, canvas.height / 4, canvas.width / 2, canvas.height / 2);
ctx.stroke();
};
image.src = "https://icdn.lenta.ru/images/2019/03/31/13/20190331135912200/pic_5bfd003894e22bb0d70b775286b96a4f.jpg";
</script>
</body>
</html>
выводится изображение и поверх него прямоугольник - ВСЕ ок
А при таком:
<script>
var canvas = document.getElementById("c01");
var ctx = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
};
image.src = "https://icdn.lenta.ru/images/2019/03/31/13/20190331135912200/pic_5bfd003894e22bb0d70b775286b96a4f.jpg";
ctx.beginPath();
ctx.drawImage(image, 0, 0);
ctx.lineWidth = "6";
ctx.strokeStyle = "red";
ctx.rect(canvas.width / 4, canvas.height / 4, canvas.width / 2, canvas.height / 2);
ctx.stroke();
</script>
канвас строется нужного размера (с изображение), но само изображение не отрисовывается, а прямоугольник мигает на секунду и исчезает
это связано с тем, что изображение ещё не успевает загрузиться (асинхронный image.src)?
и как корректно все делать?
если несколько изображений, то вряд ли onload придется несколько делать
Можно дождаться, пока все загрузиться, и только потом рисовать:
let imagesCanvas = document.querySelector('canvas');
let imgCtx = imagesCanvas.getContext('2d');
let images = ['keyboard.jpg', 'star.jpg','leaves.jpg' ]
let loaded = [];
load();// загружаем картинки
function load() {
let name = images.shift();
let img = new Image();
img.crossOrigin = "anonymous";
// вызываем загрузку следующей картинки, пока они все не будут загружены,
// тут надо предусмотреть onerror, и отрисовку, когда они все загрузятся
img.onload = () => add() | images.length ? load() : requestAnimationFrame(draw);
img.src = `https://webglfundamentals.org/webgl/resources/${name}`
// добавляем инфо о картинке в массив
function add() {
loaded.push({
name: name, img: img,
x: 50+loaded.length*120,
y: 5+30*loaded.length,
w: img.width/2, h: img.height/2
});
}
}
function draw(){
loaded.forEach((img, i) => {
// рисуем картинки на канве
imgCtx.drawImage(img.img, img.x , img.y, img.w, img.h);
})}
body{margin:0}
<canvas width="600" height="170"></canvas>
А еще можно в каждом onload вызвать перерисовку всего кадра (draw()
), не оптимально, но код проще будет:
let imagesCanvas = document.querySelector('canvas');
let imgCtx = imagesCanvas.getContext('2d');
let images = ['keyboard.jpg', 'star.jpg','leaves.jpg' ]
let loaded = [];
images.forEach(name => {
let img = new Image();
img.crossOrigin = "anonymous";
img.src = `https://webglfundamentals.org/webgl/resources/${name}`
img.onload = () => {
loaded.push({
img: img,
x: 50 + loaded.length*120,
y: 5 + 30*loaded.length,
w: img.width/2,
h: img.height/2
});
draw();
};
})
function draw() {
loaded.forEach(i => imgCtx.drawImage(i.img, i.x , i.y, i.w, i.h));
}
body{margin:0}
<canvas width="600" height="170"></canvas>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Нужна функция removeArray(x, n), которая удаляет n из массива и извлекает полученный элементНапример:
Правлю код vuejs компонента в vscode, при этом периодически жму Alt + Shift + F для автоматического форматирования введённого кода
Есть слайдер с переключением слайда через определенный промежуток времениСделал так чтобы при клике на кнопку перелистывания слайда таймер,...
Создать переменную «resultArray» (массив)Создать переменные «first» = 1, «second» = 2, «senseOfLife» = 42