So I've got a 600x2400 image I'm trying to make scroll upwards (character will be autorunning down the screen) and repeat. I've got the scrolling, but not the repeat. My question is, how do I make the image redraw for a second instance from the top and continue when I get to the end of this one? so far when the code gets to the end of the image, I just get a staggered repeat of the bottom section of the first instance scrolling.
JS
let canvas;
let context;
let secondsPassed;
let oldTimeStamp;
let fps;
let map = new Image();
let roadMovement = 0;
let increment = 2;
window.onload = init;
function init() {
canvas = document.getElementById('gameCanvas');
context = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.requestAnimationFrame(gameLoop);
}
function draw() {
map.src = "map.png";
}
function gameLoop(timeStamp) {
secondsPassed = (timeStamp - oldTimeStamp) / 1000;
oldTimeStamp = timeStamp;
fps = Math.round(1 / secondsPassed);
roadMovement = increment;
map.onload = function () {
context.drawImage(map, 0, roadMovement, 600, 600, 0, 0, canvas.width, canvas.height);
};
draw();
window.requestAnimationFrame(gameLoop);
}
CSS
body{
position: absolute;
width:100vw;
height:100vh;
margin:0;
padding:0;
display: flex;
justify-content: center;
align-items: center;
}
#gameCanvas{
position: relative;
left:0;
top:0;
margin:0;
padding:0;
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="style.css">
<script src="jquery-3.6.0.min.js"></script>
</head>
<body>
<canvas id="gameCanvas">
</canvas>
<script src="script.js"></script>
</body>
</html>
Edited added let for increment value so autoscroll speed can be changed.
CodePudding user response:
What about placing the image as the background of the page directly in CSS?
Try this:
body{
position: absolute;
width:100vw;
height:1000vh;
margin:0;
padding:0;
display: flex;
justify-content: center;
align-items: center;
background-image: url('./map.png');
background-repeat: repeat;
background-size: 100%; /*scale the image at 100% of the page width*/
}
CodePudding user response:
You could draw the map image twice and reset the roadMovement
any time it gets larger than the image height. That's when you know the whole image is outside of the canvas view.
Technically, you only need to draw the second image when imageHeight - roadMovement < canvasHeight
, but it might not be worth it to optimize.
let canvas;
let context;
let secondsPassed;
let oldTimeStamp;
let fps;
let map = new Image(600, 600);
map.onload = init;
map.src = "http://www.secretdoors.com/playit/resources/chessboard.gif";
let roadMovement = 0;
let increment = 2;
function init() {
canvas = document.getElementById('gameCanvas');
context = canvas.getContext('2d');
canvas.width = 150;
canvas.height = 150;
window.requestAnimationFrame(gameLoop);
}
function gameLoop(timeStamp) {
secondsPassed = (timeStamp - oldTimeStamp) / 1000;
oldTimeStamp = timeStamp;
fps = Math.round(1 / secondsPassed);
roadMovement = increment;
roadMovement %= map.naturalHeight;
const y1 = roadMovement;
const y2 = y1 - map.naturalHeight;
context.clearRect(0, 0, 600, 600);
context.drawImage(
map,
0, y1, map.naturalWidth, map.naturalHeight
);
context.drawImage(
map,
0, y2, map.naturalWidth, map.naturalHeight
);
window.requestAnimationFrame(gameLoop);
}
#gameCanvas{
width: 150px;
height: 150px;
border: 1px solid red;
}
<canvas id="gameCanvas">
</canvas>