const cloud1 = new Image()
const cloud2 = new Image();
const cloud3 = new Image();
cloud1.src = 'http://i.imgur.com/GigS3KR.png';
cloud2.src = 'http://i.imgur.com/y3JAe69.png';
cloud3.src = 'http://i.imgur.com/v30JIWp.png';
const canvases = document.querySelectorAll('.canvas');
const canvasSize = document.documentElement.clientWidth;
for (const n of canvases) {
n.setAttribute('width', canvasSize);
n.setAttribute('height', canvasSize);
}
let ts0;
window.requestAnimationFrame(function draw(ts) {
for (const n of canvases) {
ts0 = ts0 || ts;
const dt = ts - ts0;
const ctx = n.getContext('2d');
ctx.clearRect(0, 0, canvasSize, canvasSize);
ctx.save();
ctx.translate(50, 50 + Math.sin(dt / 500) / 20);
ctx.rotate(Math.sin(dt / 340) / 200);
ctx.drawImage(cloud1, 0, 0, canvasSize * 0.95, canvasSize * 0.95);
ctx.restore();
ctx.save();
ctx.translate(5, 0 + Math.sin(dt / 382) * 2);
ctx.rotate(Math.sin(dt / 630) / 40);
ctx.drawImage(cloud2, 150, 100, canvasSize * 0.84, canvasSize * 0.84);
ctx.restore();
ctx.save();
ctx.translate(8, 150 + Math.sin(dt / 198) * 3);
ctx.rotate(Math.sin(dt / 500) / 450);
ctx.drawImage(cloud3, 0, 0, canvasSize * 0.7, canvasSize * 0.7);
ctx.restore();
}
window.requestAnimationFrame(draw);
});
const cloud = new Image();
cloud.src = 'https://avatanplus.com/files/resources/mid/56dc1ba4ba1b81534bcbfb9a.png';
(function draw() {
const ctx = document.getElementById('canvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'rgba(0,0,0,0.4)';
ctx.strokeStyle = 'rgba(0,153,255,0.4)';
ctx.save();
ctx.translate(300, 200);
const time = new Date();
ctx.rotate(Math.sin(time / 500) / 10);
ctx.drawImage(cloud, -300, -200);
ctx.restore();
window.requestAnimationFrame(draw);
})();
var ts0;
function draw(ts) {
// ...
if(!ts0) ts0 = ts;
const dt = ts - ts0; // сколько прошло миллисекунд
// ...
ctx.translate(500, 180 + Math.sin(dt/352)*3);
ctx.rotate( Math.sin(dt/630) / 40 );
Тут помимо поворота ещё по вертикали слегка покачивается. Так же, плавной синусоидой, но с другим периодом, чтобы не выглядело циклично.requestAnimationFrame()
параметром передаётся текущее время, так что можно не заморачиваться с созданием нового объекта Date, а использовать этот параметр.ctx.drawImage(cloud, -350, -250);
с размерами картинки определяется центр, относительно которого получится вращение. Желательно его подобрать так, чтобы они приходился на визуальный центр масс тучи.