Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

109
Views
make canvas image repeat scrolling upwards

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.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

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*/
    }
about 4 years ago · Juan Pablo Isaza Report

0

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>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!