Skip to content

Shenanigans Demos

Rocket

A singular rocket shoots out from a set spot on the page at an angle, followed by a burst of clouds and sparkles. Each set of emojis uses it's own emojiBlast function. The sparkle function is set to occur 400 milliseconds after the rocket and clouds go off.

const blastYPos = innerHeight - 10;
const rocket = () => {
emojiBlast({
emojiCount: 1,
emojis: ["🚀"],
physics: {
fontSize: 45,
gravity: 0,
initialVelocities: {
x: 12,
y: -10
},
rotation: 0,
rotationDeceleration: 0
},
position: {
x: 150,
y: blastYPos
}
});
};
const clouds = () => {
emojiBlast({
emojiCount: 10,
emojis: ["☁️"],
physics: {
fontSize: { max: 50, min: 38 },
gravity: 0.1,
initialVelocities: {
x: { max: 7, min: -7 },
y: { max: -2, min: -5 }
},
rotation: 0,
rotationDeceleration: 0
},
position: {
x: 150,
y: blastYPos
}
});
};
const sparkles = () => {
emojiBlast({
emojiCount: 10,
emojis: [""],
physics: {
fontSize: { max: 30, min: 10 },
gravity: 0.2,
initialVelocities: {
x: { max: 20, min: -15 },
y: { max: 20, min: -15 }
}
},
position: {
x: 200,
y: blastYPos - 60
}
});
};
rocket();
clouds();
setTimeout(sparkles, 400);

Heart on Fire

An outline of a heart made up of emojis appears on the page. The heart is formed by iterating through a 2d array of x, y coordinates and creating an explosion containing a singular heart emoji using each coordinate.

const heartCoords = [
[500, 600],
// bottom point
[500, 410],
// center point
// left line (y = x + 100)
[350, 450],
[375, 475],
[400, 500],
[425, 525],
[450, 550],
[475, 575],
// right line (y = -x + 1100)
[650, 450],
[623, 477],
[600, 500],
[550, 550],
[574, 526],
[526, 574],
// left curve
[340, 410],
[340, 430],
[350, 385],
[370, 365],
[400, 350],
[430, 355],
[460, 370],
[480, 385],
// right curve
[520, 385],
[540, 370],
[570, 355],
[600, 350],
[630, 365],
[650, 385],
[660, 410],
[660, 430]
];
const randXVelocity = Math.random() * 15 * (Math.round(Math.random()) ? 1 : -1);
const randYVelocity = Math.random() * -15 - 3;
const randStartXCoord = Math.random() * 350 * (Math.round(Math.random()) ? 1 : -1);
const randStartYCoord = Math.random() * 350 * (Math.round(Math.random()) ? 1 : -1);
for (const [xCoordinate, yCoordinate] of heartCoords) {
emojiBlast({
emojiCount: 1,
emojis: ["❤️‍🔥"],
physics: {
fontSize: 35,
gravity: 0.15,
initialVelocities: {
x: randXVelocity,
y: randYVelocity
},
rotation: 0,
rotationDeceleration: 0
},
position: {
x: xCoordinate + randStartXCoord,
y: yCoordinate + randStartYCoord
}
});
}

Rainstorm

emojiBlasts occurring from set points at the top of the page for 5 seconds emulating a rainstorm.

for (let i = 0; i < innerWidth; i += 25) {
const randGravity = Math.random() * 0.3 + 0.1;
const { cancel } = emojiBlasts({
emojiCount: 1,
emojis: ["💧"],
physics: {
fontSize: { max: 30, min: 18 },
gravity: randGravity,
initialVelocities: {
rotation: 0,
x: 0,
y: 0
},
rotation: 0,
rotationDeceleration: 0
},
position: {
// using our step value as our starting x position
x: i,
y: 100
},
// setting a random interval between 100 & 1000 for the explosion in each emojiBlasts to occur
interval() {
return Math.floor(Math.random() * 1e3) + 100;
}
});
setTimeout(cancel, 5e3);
}

Rainbow

A rainbow made up of hearts and clouds explodes as an arc across the page. The rainbow is made of columns, where each emoji within the column is a singular emojiBlast.

const pageMidpoint = Math.floor(innerHeight / 2);
const rainbowCol = () => {
const rainbows = ["❤️", "🧡", "💛", "💚", "💙", "💜"];
let positionY = pageMidpoint;
for (const rainbow of rainbows) {
emojiBlast({
emojiCount: 1,
emojis: [rainbow],
physics: {
fontSize: 35,
gravity: 0.08,
initialVelocities: {
rotation: 0,
x: 20,
y: -20
},
rotation: 0
},
position: {
x: 0,
y: positionY
}
});
positionY += 30;
}
};
const clouds = () => {
let positionY = pageMidpoint;
for (let i = 0; i < 6; i++) {
emojiBlast({
emojiCount: 1,
emojis: ["☁️"],
physics: {
fontSize: 65,
gravity: 0.08,
initialVelocities: {
rotation: 0,
x: 20,
y: -20
},
rotation: 0
},
position: {
x: 0,
y: positionY
}
});
positionY += 30;
}
};
clouds();
const intervalId = setInterval(rainbowCol, 80);
setTimeout(() => {
clearInterval(intervalId);
}, 3e3);
setTimeout(clouds, 3e3);

Shooting Stars

Stars shoot across the page with trails of sparkles. An emojiBlast is used for each individual emoji and set off in intervals.

const star = (yPos) => {
emojiBlast({
emojiCount: 1,
emojis: ["⭐️"],
physics: {
fontSize: { max: 32, min: 20 },
gravity: 0.05,
initialVelocities: {
x: 45,
y: -10
}
},
position: {
x: 0,
y: yPos
}
});
};
const sparkles = (yPos, size) => {
emojiBlast({
emojiCount: 1,
emojis: [""],
physics: {
fontSize: size,
gravity: 0.05,
initialVelocities: {
rotation: 0,
x: 45,
y: -10
}
},
position: {
x: 0,
y: yPos
}
});
};
const shootingStar = () => {
const randYPos = Math.random() * innerHeight + 100;
let emojiSize = 18;
star(randYPos);
const intervalId2 = setInterval(() => {
sparkles(randYPos, emojiSize);
emojiSize -= 3;
}, 60);
setTimeout(() => {
clearInterval(intervalId2);
}, 400);
};
const intervalId = setInterval(shootingStar, 60);
setTimeout(() => {
clearInterval(intervalId);
}, 2e3);

Firework

A firework of emojiBlasts comprised of a singular random emoji is set off at a random position on the page.

const randStartXCoord = Math.random() * innerWidth;
const randStartYCoord = Math.random() * innerHeight;
const sparkles = () => {
const velocityCoords = [
[0, -15],
[0, 15],
[-15, 0],
[15, 0],
[10, 10],
[-10, -10],
[10, -10],
[-10, 10]
];
for (const [xCoordinate, yCoordinate] of velocityCoords) {
emojiBlast({
className: "sparkles",
emojiCount: 1,
emojis: [""],
physics: {
fontSize: 20,
gravity: 0,
initialVelocities: {
rotation: 0,
x: xCoordinate,
y: yCoordinate
},
rotation: 0,
rotationDeceleration: 0
},
position: {
x: randStartXCoord,
y: randStartYCoord
}
});
}
};
const blast = () => {
const randEmoji = defaultEmojis[Math.floor(Math.random() * defaultEmojis.length)];
const coordDiff = [
[0, -150],
[0, 150],
[-150, 0],
[150, 0],
[106, 106],
[-106, -106],
[106, -106],
[-106, 106]
];
for (const [xCoordinateDiff, yCoordinateDiff] of coordDiff) {
emojiBlast({
emojis: [randEmoji],
physics: {
gravity: 0.2,
initialVelocities: {
rotation: 0,
x: { max: 10, min: -10 },
y: { max: 15, min: -15 }
}
},
position: {
x: randStartXCoord + xCoordinateDiff,
y: randStartYCoord + yCoordinateDiff
},
uniqueness: 1
});
}
};
const removeSparkles = () => {
const elements = document.getElementsByClassName("sparkles");
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
};
sparkles();
setTimeout(removeSparkles, 630);
setTimeout(blast, 630);

Nope

A UFO appears on the page and briefly stops to abduct up a lone cow. The example consists of three stages defined by time, each with their own set of emojiBlasts. The first stage consists of the UFO flying onto the page, the second consists of the UFO stopping to abduct the cow, and the third consists of the UFO flying off the page.

const midPageHeight = innerHeight / 2;
const ufo = (pos, vel, className) => {
emojiBlast({
className,
emojiCount: 1,
emojis: ["🛸"],
physics: {
fontSize: 75,
gravity: 0,
initialVelocities: {
rotation: 0,
x: vel[0],
y: vel[1]
},
rotation: 20
},
position: {
x: pos[0],
y: pos[1]
}
});
};
const cow = (velY, className) => {
emojiBlast({
className,
emojiCount: 1,
emojis: ["🐄"],
physics: {
fontSize: 35,
gravity: 0,
initialVelocities: {
rotation: 0,
x: 0,
y: velY
},
rotation: 0
},
position: {
x: 480,
y: midPageHeight + 100
}
});
};
const vortex = () => {
emojiBlast({
className: "mid",
// Setting the className to mid as the vortex only occurs in the "mid" stage
emojiCount: 1,
emojis: ["🌪️"],
physics: {
fontSize: 120,
gravity: 0,
initialVelocities: {
rotation: 0,
x: 0,
y: 0
},
rotation: 180
},
position: {
x: 535,
y: midPageHeight + 70
}
});
};
const classNames = ["start", "mid", "end"];
const ufoPos = [
[0, midPageHeight - 200],
// Start stage
[500, midPageHeight]
// Mid stage & end stage
];
const ufoVel = [
[15, 6],
// Start stage
[0, 0],
// Mid stage
[15, -6]
// End stage
];
const cowYVel = [
0,
// Start stage
-3
// Mid stage
];
const removeEmoji = (className) => {
const elements = document.getElementsByClassName(className);
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
};
ufo(ufoPos[0], ufoVel[0], classNames[0]);
cow(cowYVel[0], classNames[0]);
setTimeout(vortex, 2e3);
setTimeout(() => {
cow(cowYVel[1], classNames[1]);
}, 2e3);
setTimeout(() => {
ufo(ufoPos[1], ufoVel[1], classNames[1]);
}, 2e3);
setTimeout(() => {
removeEmoji(classNames[0]);
}, 2e3);
setTimeout(() => {
removeEmoji(classNames[1]);
}, 4350);
setTimeout(() => {
ufo(ufoPos[1], ufoVel[2], classNames[2]);
}, 4350);