Animated Background With Scroll

Written by @phuang 20 December 2022

Drawing a background SVG line-art as you scroll up and down the page. Resizing also updates the position of the line-art. In this case, here is a sample cityscape line-art that "draws" itself as you scroll the page. For it to work, you must run the code in an html file, change the url of the svg, and host it on a webserver of your choice; something like XAMPP or your own webhosting service. SVG Download

Code Snippet:

                                                <!-- this script is provided by coded by: Kerixa Inc. -->
<!DOCTYPE html>
<html lang="en">

    <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>Animated Background With Scrolling</title>

<!-- font awesome library include 4.7 -->
<link rel="stylesheet" href="" integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<!-- font library -->
<link rel="preconnect" href=""><link rel="preconnect" href="" crossorigin><link href=";700&display=swap" rel="stylesheet">

<!-- css styles -->
@import url(';700&display=swap'); 

/* default light theme */
:root, html{
  margin: 0;
  padding: 0;
  font-family: "Inter", arial, monospace;

  --primary-color: #f45b69;
  --background-color: white;
  --button-color: black;
  --button-bg-color: yellow;
  --opacity: 0.75;

/* dark-mode theme */


/* main styles */
html, body{
  height: 100%;
  margin: 0;
  padding: 0;


  position: relative;

  box-sizing: border-box;
  font-family: "Inter", arial, monospace;
  font-size: 1rem;
  transition: all 0.5s ease-in-out;

  text-decoration: none;
  font-weight: 600;
  color: var(--secondary-color);

  color: var(--primary-color); 

  position: absolute;
  top: 0;
  z-index: 1000;

  width: 100%;


/* navigation */
  display: flex;
  justify-content: space-between;
  background-color: var(--background-color);
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);

  position: fixed;
  top: 0;
  width: 100%;

  z-index: 2000;
nav ul{
  display: flex;
  align-items: center;
  justify-content: center;
nav ul li{
  display: flex;
  list-style-type: none;
  min-width: 5rem;
  margin: 1rem;

nav .logo{
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 1rem;

nav .logo i{
  color: var(--secondary-color);

  border: 2px var(--secondary-color) solid;
  padding: 0.5rem;
  background: transparent;
  font-weight: bold;
  color: var(--secondary-color);

  border: 2px var(--primary-color) solid;
  color: var(--button-color);

  height: 100vh;  


  width: 100%;
  position: fixed;
  bottom: 0;

  background-color: rgba(90, 169, 230, var(--opacity));

  background-color: rgba(127, 200, 248, var(--opacity));

  background-color: rgba(249, 249, 249, var(--opacity));

  background-color: rgb(255, 228, 94, var(--opacity));

  background-color: rgb(255, 99, 146, var(--opacity));



  <div class="logo"><a href="">Javascript Free Code</a></div>
    <li><a href="">SERVICES</a></li>
    <li><a href="">CONTACT US</a></li>

    <li><button class="login">LOGIN / SIGN UP</button></li>

<!-- change svg url here -->
<object id="svg-bg" type="image/svg+xml" data="./buildings.svg" class="section-bg">


  <div id="main">
    <section id="section1">
    <section id="section2">
    <section id="section3">
    <section id="section4">
    <section id="section5">





Tutorial Description

Drawing a background SVG line-art as you scroll up and down the page. Resizing also updates the position of the line-art. In this case, here is a sample cityscape line-art that "draws" itself as you scroll the page.


const sections = document.querySelectorAll("section");
let pathLength = 0;
let path;
let scrollPercent = 0;
let heightLimit;

window.onload =  () => {

  // ensure svg is loaded before accessing paths 
  const svg = document.getElementById("svg-bg").contentDocument;

  path = svg.querySelector("path");
  const stylesArr = getInlineStyles(;

  stylesArr.forEach(style => {
    path.setAttribute(style[0], style[1]);

  // Trigger resize event on page laod
  window.dispatchEvent(new Event("resize"));

  // Scroll event listener
  window.addEventListener("scroll", event => {
      draw(path, heightLimit, pathLength)  

// Resize event listener
window.addEventListener("resize", event => {

    const body = document.body;
    const html = document.documentElement;
    heightLimit =  body.scrollHeight - window.innerHeight;

    pathLength = Math.ceil(path.getTotalLength());

    // length of animation = pathLength;
    // hide animation = pathLength;

    // update animation state if starting scroll in middle of page
    draw(path, heightLimit, pathLength);

  This function converts styles in the "style" property of the svg and returns an array of the actual properties
function getInlineStyles(styles){

  const stylesArr = styles.split(";")
  let arr= [];

  stylesArr.forEach( item => {

    if(item.length > 0){
      const e = item.split(":")

      const f = [e[0].trim(), e[1].trim()];

  return arr;

function draw(path, heightLimit, pathLength){
   const curPos = window.scrollY;  
   const curPercentage = curPos / heightLimit ;
   const val = curPercentage * pathLength; = pathLength - val;

</html><a target='_blank' href='' style='font-size: 8pt; text-decoration: none'>JavaScript Best Codes</a>                                                


About @phuang

Help desk analyst transitioning to a full-stack developer role. Hoping to learn and collaborate with everyone. Happy coding!



Here you can leave us commments. Let us know what you think about this code tutorial!

0 / 300

Online Users: 12
Recent Members: admin_js, bloxio, yqaice, flooketsu, phuang_test
advertisement 2