Scrolling to the current position
There are lots of times when you want to control what is in view of the browser window in a large page. This is useful for things like side-scroller games, large maps, big data tables, and so on...
You can use the window.scrollTo()
method in order to scroll an element into view.
However, this will try to locate the element in the top right corner of the screen: you may have to
add an offset to get the positioning the way you want it.
You should use position: absolute;
CSS code when using this.
Look at the code below to see how window.scrollTo()
is used.
Creating a side-scroll effect
Animating side-scroll movement can be done with a few changes to regular animation:
-
Add
position: absolute;
to your CSS elements - Program your own position-based animations instead of using jQuery. See the code example for more information.
-
Set up a variable for the current speed (
this.currentSpeed
), and preset values for slow, medium, and fast speeds (this.slowSpeed
,this.mediumSpeed
, andthis.fastSpeed
). - Change the animation behaviour slightly:
- When going right, increase to fast speed and then animate right
- When going up or down, switch to medium speed, and then animate both up and left/right
- When going left, switch to slow speed, and then keep animating right.
- In this example, we are flying against a background image, but you can also generate a grid with obstacles to fly over.
Click inside the window and use the keys to start flying! Or open in it's own browser window
Learn more
- w3schools.com's Window scrollTo() Method
Source code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Automatically scrolling to maintain focus on an element</title>
<script>
// rocket OBJECT
// rocket properties:
// rocket.element
//
// rocket.currentSpeed
// rocket.slowSpeed
// rocket.mediumSpeed
// rocket.fastSpeed
//
// rocket.top
// rocket.left
// rocket.scrollOffset
//
// rocket.interval
// rocket.fps
// rocket.lastKeyCode
//
// rocket methods
// rocket.initialize()
// rocket.goUp()
// rocket.goDown()
// rocket.goLeft()
// rocket.goRight()
// rocket.animate()
//
var rocket = {
element: null, // the element to animate
currentSpeed: null, // the current speed
slowSpeed: 4, // move the element over by this many pixels at slow speed
fastSpeed: 12, // move the element over by this many pixels at fast speed
mediumSpeed: 8, // move the element over by this many pixels at medium speed
top: null, // current top coordinate
left: null, // current left coordinate
scrollOffset: -200, // the position of the rocket from the side of the screen while scrolling
interval: null, // holds the animation repeater
fps: 30, // the frame rate to aim for
lastKeyCode: null, // the last key code that was pressed
// INPUT: get the element containing the rocket
// and get the current top and left coordinates
initialize: function ( id ) {
console.log( 'initializing...' );
this.element = document.getElementById( id );
this.top = this.element.offsetTop;
this.left = this.element.offsetLeft;
this.currentSpeed = this.mediumSpeed;
window.scrollTo( this.left + this.leftOffset, this.top );
},
// OUTPUT: animate upwards
goUp: function () {
this.top = this.top - this.currentSpeed;
this.element.style.top = this.top + 'px';
// follow by scrolling
window.scrollTo( this.left + this.scrollOffset, this.top );
},
// OUTPUT: animate downwards
goDown: function () {
this.top = this.top + this.currentSpeed;
this.element.style.top = this.top + 'px';
// follow by scrolling
window.scrollTo( this.left + this.scrollOffset, this.top );
},
// OUTPUT: animate leftwards
goLeft: function () {
this.left = this.left - this.currentSpeed;
this.element.style.left = this.left + 'px';
// follow by scrolling
window.scrollTo( this.left + this.scrollOffset, this.top );
},
// OUTPUT: animate rightwards
goRight: function () {
this.left = this.left + this.currentSpeed;
this.element.style.left = this.left + 'px';
// follow by scrolling
window.scrollTo( this.left + this.scrollOffset, this.top );
},
// PROCESS: repeat an animation in an interval
animate: function ( animationFunction ) {
// clear the previous animation repetition
window.clearTimeout( this.interval );
// move up once every animation frame
this.interval = window.setInterval( animationFunction, 1000 / rocket.fps );
}
}
// while a key is pressed down...
window.onkeydown = function ( keyEvent ) {
// INPUT: read the key that was pressed...
var keyCode = keyEvent.which || keyEvent.keyCode;
console.log( 'a key has been pressed...' );
console.log( keyCode );
// PROCESS: only act if the key pressed is different that the last one,
// or if the key has been released before repressing
if ( rocket.lastKeyCode != keyCode ) {
rocket.lastKeyCode = keyCode;
if ( keyCode == 87 ) { // W = up
rocket.animate(
function () {
rocket.currentSpeed = rocket.mediumSpeed; // use medium speed for side-scroll effect
rocket.goUp();
rocket.goRight(); // add right movement only for side-scroll effect
}
);
} else if ( keyCode == 65 ) { // A = left
rocket.animate(
function () {
rocket.currentSpeed = rocket.slowSpeed; // use slow speed for side-scroll effect
rocket.goRight(); // normally goLeft(), but changed for side-scroll effect
}
);
} else if ( keyCode == 83 ) { // S = down
rocket.animate(
function () {
rocket.currentSpeed = rocket.mediumSpeed; // use medium speed for side-scroll effect
rocket.goDown();
rocket.goRight(); // add right movement only for side-scroll effect
}
);
} else if ( keyCode == 68 ) { // D = right
rocket.animate(
function () {
rocket.currentSpeed = rocket.fastSpeed; // use fast speed for side-scroll effect
rocket.goRight();
}
);
}
}
}
/*
// stop moving when a key is released
// delete this function if you want your image to drift forever
window.onkeyup = function () {
// clear the previous animation repetition
window.clearTimeout( rocket.interval );
// clear the current key being pressed
rocket.lastKeyCode = null;
}
*/
</script>
<style>
#information {
position: absolute;
top: 20px;
left: 20px;
}
#backgroundID {
height: 93vh; /* set height to part of the viewport height to deal with scroll bars */
}
#animateID {
position: absolute;
height: 20vh; /* set height to 20% of viewport height */
top: 50%;
left: 5%;
}
</style>
</head>
<body onload="rocket.initialize( 'animateID' );">
<img
id="backgroundID"
src="http://drapak.ca/cpg/img/SuperMarioWorld.png" />
<div id="information">
<h2>
Scroll automatically to maintain focus on an element
</h2>
<p>
<strong>Movement keys:</strong>
↑W ←A ↓S →D <br />
</p>
</div>
<img
id="animateID"
src="https://www.kasandbox.org/programming-images/space/octopus.png" />
</body>
</html>