Shatter.js

Make images explode in JavaScript

Shatter.js is a little JS project I originally built back in 2014. I was playing around a lot with Phaser.js and making little mini games and experiments in JS. In one of my projects I really wanted to make a sprite graphic for a ground plane explode when a character walked over it.

The project aged and eventually broke due to both an oversight on my original implementation and browser updates, so I slapped a warning on the repository and planned to one day return to it. That day is now.

I’ve been working in Typescript quite a bit lately and really enjoying it, so I thought I’d rewrite the entire project in Typescript and update the entire pipeline/build. Previously it was building with Grunt and using some custom d3 build script. Oh, how times have changed in just a few years…

Check it out on GitHub

Show me

The core idea behind Shatter.js is that you give it an array of ‘pieces’. Each piece is an array of [x, y] coordinates which when followed, create the edges of the piece.

It might make more sense when you see it in action. Take a simple example of splitting a square image.

Multicolored Square
const squareImg = "/images/posts/14/shatter-js/_square.png";
const shatterSquare = new Shatter(squareImg);
shatterSquare.setPieces([
    [
        [0, 0],
        [50, 0],
        [50, 50],
        [0, 50],
    ],
    [
        [50, 0],
        [100, 0],
        [100, 50],
        [50, 50],
    ],
    [
        [0, 50],
        [50, 50],
        [50, 100],
        [0, 100],
    ],
    [
        [50, 50],
        [100, 50],
        [100, 100],
        [50, 100],
    ],
]);
const results = await shatterSquare.shatter();
results.forEach(res => {
    el.appendChild(res.image);
});
Square image split in 4

It’s likely you won’t want to manually provide the coordinates for pieces, so the library also includes a generator. The included Voronoi generator creates a random array of pieces based on a set of random numbers fed to a Voronoi diagram generator.

const demo2el = document.querySelector(".js-shatter-demo-2");
const vshatter = new Shatter(squareImg);
const voropieces = VoronoiPieces({
    height: 100,
    width: 100,
    numPieces: 4,
});

vshatter.setPieces(voropieces);
let demo2pieces = await vshatter.shatter();
demo2pieces.forEach(res => {
    demo2el.appendChild(res.image);
});
Square image split in with Voronoi

The returned objects also include the x and y offsets of each individual image. This allows you to display them together in their original places.

const demo3el = document.querySelector(".js-shatter-demo-3");
demo3el.style.position = 'relative';
demo3el.style.height = '100px';
demo3el.style.width = '100px';
demo3el.style.margin = '0 auto';
demo2pieces.forEach(res => {
    const clone = res.image.cloneNode();
    clone.setAttribute('style', `position: absolute; top: ${res.y}px; left: ${res.x}px;`);
    demo3el.appendChild(clone);
});
Line em up

Add a some physics and you can see how this could be fun to play around with!


Check out the project on GitHub