Cover image for Bringing this 2-D Nebula Drawing to Life With Code

Bringing this 2-D Nebula Drawing to Life With Code

gabe profile image Gabe ・3 min read

A few weeks back, after wrapping up my space-themed drawing, I thought about how cool it would be if I could somehow go the extra step and potentially make my new scene interactive.

After some digging, I realized the easiest way to go about this would be to make my drawing a parallax-like experience using Matthew Wagerfield's Parallax.js

My goal was to turn this...

Alt Text

...into this

Alt Text

Preparing the assets

Before I could dive into my code, I had to prepare my assets. I had to export each layer of my drawing as its own image, or PNG in this case. I ended up with a total of 9 PNGs.

Alt Text

My assets were also pretty large in terms of file size, so to solve that, I used TinyPNG to help reduce file size without compromising too much on the image quality.

Project Structure

After optimizing my assets, I moved them into their own folder for the sake of organization. I downloaded the minified version of Parallax.js I found in the GitHub repository and placed it in the root of my project directory like so

Alt Text


With my files in place, I opened up index.html and set up my images

      <div id="scene">
        <div><img src="images/background.png" /></div>
        <div><img src="images/Nebula.png" /></div>
        <div><img src="images/Pink Haze_.png" /></div>
        <div><img src="images/Dark Haze.png" /></div>
        <div><img src="images/Stars.png" /></div>
        <div><img src="images/bottom.png" /></div>
        <div><img src="images/top.png" /></div>
          <img id="small-planets" src="images/Smallest Planets.png" />
          <img id="main-planet" src="images/Main Planet.png" />

With the images in place, I needed to add the data-depth attributes to their parent divs. The closer something was to the foreground, the higher its data-depth value.

The movement applied to each layer will be multiplied by its depth attribute.

      <div id="scene">
        <div data-depth="0.00"><img src="images/background.png" /></div>
        <div data-depth="0.00"><img src="images/Nebula.png" /></div>
        <div data-depth="0.00"><img src="images/Pink Haze_.png" /></div>
        <div data-depth="0.10"><img src="images/Dark Haze.png" /></div>
        <div data-depth="0.40"><img src="images/Stars.png" /></div>
        <div data-depth="0.60"><img src="images/bottom.png" /></div>
        <div data-depth="0.70"><img src="images/top.png" /></div>
        <div data-depth="1.00">
          <img id="small-planets" src="images/Smallest Planets.png" />
        <div data-depth="0.80">
          <img id="main-planet" src="images/Main Planet.png" />

I then targeted the scene with javascript and created a new parallax instance with that scene as the parameter.

      var scene = document.getElementById("scene");
      var parallax = new Parallax(scene);

I now had a functioning parallax experience. However, it was too large, and things were a bit out of place

Alt Text

I resolved this by adding some CSS, though ideally, I should have resized my actual images.

.scene {
  margin: auto;
  padding: 0;
  max-width: 700px;
  max-height: 700px;
  overflow: hidden;

[data-depth="0.80"] {
  left: 25% !important;
  top: 20% !important;

[data-depth="1.00"] {
  left: 80% !important;

#main-planet {
  width: 50%;

Alt Text

and with that, I had my end product. If you'd like to see it for yourself, head on over to my site on a desktop browser and hover over the canvas. Enjoy!

Posted on by:

gabe profile



House-Plant fanatic, Javascript connoisseur, & CSS artisan.


Editor guide

Looks sweet! You might even be able to get it working on mobile! From the docs: "Where no gyroscope or motion detection hardware is available, the position of the cursor is used instead".