Предположим имеется 1 изображение машины. Необходимо создать два объекта Image с этой машиной и двигать эти два изображения асинхронно. Привожу код, работает он явно не так как нужно, по задумке - вторая машина должна изначально отставать от первой и обе должны двигать влево с какой-то скоростью. В итоге получается слияние двух машин, будто это не два разных объекта, а один.
Наработки: https://jsfiddle.net/o236kta5/2/
<html>
<head>
</head>
<body>
<canvas id="canvas" width="550" height="550"></canvas>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("canvas")
ctx = canvas.getContext('2d')
//
var pic = [];
var timers = [];
for (var i = 0; i < 2; i++) {
pic[i] = new Image()
pic[i].src = "http://icons.iconarchive.com/icons/iconshow/transport/64/Sportscar-car-2-icon.png";
//pic[i].onload = function(pic) {
animate(pic[i]);
//}
}
function animate (pic, x){
timers[i] = setInterval(function() {
var x = 250 + i * 20; // начальная координата картинки по горизонтали
motion(pic, x);
}, 1000 / 30);
}
// функция движения картинки
function motion(picture, xcord) {
console.log(picture);
var pic = picture;
var x = xcord;
setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(pic, x, 0) // выводим картинку по координатам (pic, x, 0)
x-- // увеличиваем координату X
}, 1000 / 30);
}
}
</script>
</body>
</html>
Залог плавной анимации - функция положения объектов от времени между кадрами
setInterval
это плохо, но срабатывает через фиксированные интервалы времени, для вызова отрисовки в современных браузерах есть специальный метод -requestAnimationFrame
, браузер сам вызывает функцию переданную в этот метод, когда соберется отрисовать следующий кадр, на разных платформах это работает по-разному, например на мобильных устройствах он вызывается реже для экономии электроэнергии, так же он реже вызывается для неактивных вкладок.
let t = 0
let c = canvas.getContext('2d');
let cars = Array(7).fill(0).map((e,i) => ({
x: 560, y: i*20,
v: 0.2 + Math.random()/3
}));
function draw(dt) { // dt время с начала анимации
c.clearRect(0, 0, canvas.width, canvas.height);
cars.forEach(car => {
car.x -= (dt-t)*car.v;
car.x = car.x < 0 ? 600 : car.x;
c.drawImage(img, car.x , car.y, img.width, img.height);
});
t = dt;
requestAnimationFrame(draw);
}
<canvas id="canvas" width="640" height="175"></canvas>
<img id="img" style="display:none" onload="draw(0)" src="data:image/png;base64,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"/>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Изучая backend, столкнулся с такой проблемой недопонимания: есть сайт, сервер Nodejs (в принципе, какой угодно, но меня интересует именно Nodejs) и зашел...
Никак не получается добиться желаемого результата со slider-ом жуквэриЕсть шаг в 5, хотелось бы получить labels в виде 1,5,10,15,20 и т
Есть вот такой код формыОн по сути отправляет директорию, в которой расположено изображение и само название изображения