Adding Christmas Animations with the Canvas HTML Tag in Shopify


In the fast-paced world of online shopping, grabbing the attention of visitors is key to success. Keeping your store visually appealing and up-to-date with seasonal promotions and styles is a powerful way to engage customers. In this tutorial, we’ll guide you through the process of turning a section background into a captivating winter wonderland, complete with falling snow and a charming Santa hat adorning your call-to-action button.

Get the full code here: https://github.com/ndrishinski/blogs/blob/master/christmas-css-background/image-banner.liquid

Note: This tutorial is designed for use with the default Shopify Dawn theme. However, the provided code snippets are versatile and should work seamlessly with any theme, provided they are placed correctly. The animations used in this tutorial are from this public CodePen.

Prefer video?

Nick Drishinski Youtube

Identify Target Section

The first thing we are going to do, is identify the section that we want to transform. Since I am going to add this to my homepage, I am going to open my theme editor and navigate to the index.json file, and check for the top nested section being referenced. In this case, it is a file called image-banner.liquid.

Modify the HTML

Open the identified file (image-banner.liquid) and add a line just below the container div, introducing the canvas element.

<div id="Banner-{{ section.id }}" …>
  <canvas class="canvas"></canvas> <!-- insert here -->

If you don’t know about canvas, “The HTML <canvas> element is used to draw graphics, on the fly, via scripting (usually JavaScript). The <canvas> element is only a container for graphics. You must use a script to actually draw the graphics” – W3Schools. Essentially this is where our winter animations are going to take place.

Apply CSS

Within the {% style %} tag, insert the provided CSS code to ensure the background takes up the correct space.

{%- style -%}
  #Banner-{{ section.id }} {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1em;
    /* min-height: 100vh; */
    background-image: radial-gradient(circle at 50% 100%, #1b1b35, #121225);
  }

  .canvas {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
{%- endstyle -%}

Add JavaScript for Animation

To manipulate the canvas and create a winter wonderland effect, insert the provided JavaScript code within a script tag.

<script>
const canvas = document.querySelector('.canvas');
const ctx = canvas.getContext('2d');

const pixelRatio = window.devicePixelRatio || 1;

const snowflakes = [];

class Snowflake {
    constructor() {
        this.x = Math.random() * canvas.width;
        this.y = Math.random() * canvas.height;

        const maxSize = 3;
        this.size = Math.random() * (maxSize - 1) + 1;
        this.velocity = this.size * 0.35;
        const opacity = this.size / maxSize;
        this.fill = `rgb(255 255 255 / ${opacity})`;

        this.windSpeed = (Math.random() - 0.5) * 0.1;
        this.windAngle = Math.random() * Math.PI * 2;
    }
    isOutsideCanvas() {
        return this.y > canvas.height + this.size;
    }
    reset() {
        this.x = Math.random() * canvas.width;
        this.y = -this.size;
    }
    update() {
        this.windAngle += this.windSpeed;
        this.wind = Math.cos(this.windAngle) * 0.5;

        this.x += this.wind;
        this.y += this.velocity;

        if (this.isOutsideCanvas()) {
            this.reset();
        }
    }
    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fillStyle = this.fill;
        ctx.fill();
        ctx.closePath();
    }
}

const createSnowflakes = () => {
    snowflakeCount = Math.floor(window.innerWidth * window.innerHeight / 1400);

    for (let i = 0; i < snowflakeCount; i++) {
        snowflakes.push(new Snowflake());
    }
}

const resizeCanvas = () => {
    const width = window.innerWidth;
    const height = window.innerHeight;
    canvas.width = width * pixelRatio;
    canvas.height = height * pixelRatio;
    canvas.style.width = `${width}px`;
    canvas.style.height = `${height}px`;
    ctx.scale(pixelRatio, pixelRatio);
    snowflakes.length = 0;
    createSnowflakes();
};

window.addEventListener('resize', resizeCanvas);

resizeCanvas();

const render = () => {
    requestAnimationFrame(render);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    snowflakes.forEach(snowflake => {
        snowflake.update();
        snowflake.draw();
    });
};

render(); 
</script>

This JavaScript code is querying the canvas element that we created and painting our snow to it. It does this by creating a class of Snowflake which is used to create all the snowflake animations we will see. I recommend checking out the Mozilla docs on canvas.

If you save and refresh your theme preview, you should see a snowing background!

Adding the Santa Hat

For that final festive touch, add an img tag within your call-to-action button. First find all occurrences of your button (note it may be a <a> tag) and insert this img tag like within the button tags so:

               <a
                  class="button">
                  {{- block.settings.button_label_2 | escape -}}
                  <img
                    class="button-hat"
                    src="https://assets.codepen.io/4175254/santa-hat-test-9.png"
                    alt="">
                </a>

Now we can add this css to our existing block:

.button-hat {
    position: absolute;
    top: -15px;
    left: -17px;
    height: 44px;
    filter: drop-shadow(0 2px 1px rgb(0 0 0 / .25));
    z-index: 99;
  }

This CSS is setting the hat’s position to absolute within it’s parent container, and setting it on the top left corner and bringing it to the front of the user’s view using z-index.

Conclusion

With these additions, your Shopify section will now boast a fully responsive, animated winter wonderland, ensuring a cheerful shopping experience for your visitors.