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.
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);
});
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);
});
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);
});
Add a some physics and you can see how this could be fun to play around with!
Check out the project on GitHub