const ctx = document.querySelector('canvas').getContext('2d');
const sprites = [...Array(16).keys()].map(i => {
return {
id: String.fromCharCode(i + 65),
color: `hsl(${i / 26 * 360}, 100%, 50%)`,
width: 20,
height: 20,
position: {
x: 0,
y: 0,
set(x, y) {
this.x = x;
this.y = y;
},
},
};
});
requestAnimationFrame(animate);
function animate(time) {
time *= 0.001;
update(time);
render();
requestAnimationFrame(animate);
}
function update(time) {
tileX = Math.sin(time) * 100;
sprites.forEach((_, i) => {
const scrollWidth = ctx.canvas.width + _.width;
let x = (tileX + i * _.width) % scrollWidth;
if (x < 0) x += scrollWidth;
if (x > ctx.canvas.width) x -= scrollWidth;
_.position.set(x, 0);
});
}
function render() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.font = '28px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for (const sprite of sprites) {
ctx.fillStyle = sprite.color;
ctx.fillRect(sprite.position.x, sprite.position.y, sprite.width, sprite.height);
ctx.fillStyle = 'black';
ctx.fillText(
sprite.id,
sprite.position.x + sprite.width / 2,
sprite.position.y + sprite.height / 2);
}
}
canvas { border: 1px solid black; }
<canvas></canvas>