Skip to content

Instantly share code, notes, and snippets.

@kurtroberts
Last active October 7, 2022 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurtroberts/d09b51107d641d4019ce62b22b61a0d7 to your computer and use it in GitHub Desktop.
Save kurtroberts/d09b51107d641d4019ce62b22b61a0d7 to your computer and use it in GitHub Desktop.
Confetti Animation Walkthrough
// Check out https://editor.p5js.org/
var a = 0,
r = 100;
function setup() {
createCanvas(600, 600);
}
function draw() {
background(0); //background black
translate(width/2, height/2); //center the origin so it's more like working with a polar system
stroke(255); //white stroke
noFill(); //hollow circle
var x = r * cos(a),
y = r * sin(a);
circle(x, y, 5, 5);
a += 0.1;
}
var phase = 0,
a = 0;
function setup() {
createCanvas(600, 600);
}
function draw() {
background(0); //background black
translate(width/2, height/2); //center the origin so it's more like working with a polar system
stroke(255); //white stroke
noFill(); //hollow circle
for (var a = 0; a < TWO_PI; a+=0.1) {
var r = map(Math.random(), 0, 1, 100, 200),
x = r * cos(a),
y = r * sin(a);
circle(x, y, 5, 5);
}
phase += 0.01
}
// for more on this, check out Daniel Shiffman's Coding Train - https://www.youtube.com/watch?v=BjoM9oKOAKY
var noiseMax = 5,
phase = 0,
a = 0;
function setup() {
createCanvas(600, 600);
}
function draw() {
background(0); //background black
translate(width/2, height/2); //center the origin so it's more like working with a polar system
stroke(255); //white stroke
noFill(); //hollow circle
for (var a = 0; a < TWO_PI; a+=0.1) {
var xoff = map(cos(a + phase), -1, 1, 0, noiseMax),
yoff = map(sin(a), -1, 1, 0, noiseMax),
r = map(noise(xoff, yoff), 0, 1, 100, 200),
x = r * cos(a),
y = r * sin(a);
circle(x, y, 5, 5);
}
phase += 0.01
a += 0.1;
}
var noiseMax = 5,
phase = 0,
a = 0;
function setup() {
createCanvas(600, 600);
}
function draw() {
background(0); //background black
translate(width/2, height/2); //center the origin so it's more like working with a polar system
stroke(255); //white stroke
noFill(); //hollow circle
for (var a = 0; a < TWO_PI; a+=0.1) {
var xoff = map(cos(a + phase), -1, 1, 0, noiseMax),
yoff = map(sin(a), -1, 1, 0, noiseMax),
r = map(noise(xoff, yoff), 0, 1, 100, 200),
x = r * cos(a),
y = r * sin(a);
circle(x + 150, y + 200, 5, 5); //translate the circle to the right and down to take the confetti off screen
circle(-x - 150, y + 200, 5, 5); //and translate down and left and reverse the direction
}
phase += 0.01
//a += 0.1;
}
var perlinNoise = require('perlin-fp'),
{ getNoiseByCoordinate } = perlinNoise(),
nodes = [],
confettiCount = 100,
colors = ['#f6a2af', '#ee3f75', '#08b89d', '#a0d7c9', '#a09ec9', '#6262a4', '#94c4e6', '#4296d0', '#b4d187', '#86bc57'],
styles = [];
for (let i = 0; i < confettiCount; i++) {
let x = Math.floor(Math.random() * 1),
y = Math.floor(Math.random() * 1),
r = Math.floor(Math.random() * 50) + 50,
c = colors[Math.floor(Math.random() * colors.length)];
nodes.push(`<circle id="sparkle${i}" stroke="${c}" fill="${c}" cx="${x}" cy="${y}" r="${r * 0.05}" ></circle>`);
}
let phase = 0;
for (let i = 0; i < confettiCount; i++) {
let xs = [],
ys = [],
amplitude = 100,
TWO_PI = 2 * Math.PI,
maxRadius = 100,
minRadius = 80,
noiseLevel = 25,
R = minRadius + Math.floor(Math.random() * (maxRadius - minRadius));
for (let a = 0; a < TWO_PI; a += TWO_PI / 8) {
let xoff = (Math.cos(a + phase) + 1) * amplitude,
yoff = (Math.sin(a) + 1) * amplitude,
r = getNoiseByCoordinate(xoff, yoff, 0) * noiseLevel + R,
x = r * Math.cos(a),
y = r * Math.sin(a);
if(i % 2) {
xs.push(- x + 200);
ys.push(y + 300);
} else {
xs.push(x + 400);
ys.push(y + 300);
}
phase += .3;
}
styles.push(`@keyframes pattern${i} {
0% {
transform: translate(${xs[0]}px, ${ys[0]}px);
opacity: 0.6;
}
1% {
opacity: 0;
}
12% {
transform: translate(${xs[1]}px, ${ys[1]}px);
opacity: 0.0;
}
25% {
transform: translate(${xs[2]}px, ${ys[2]}px);
opacity: 0.0;
}
37%{
transform: translate(${xs[3]}px, ${ys[3]}px);
opacity: 0.0;
}
50% {
transform: translate(${xs[4]}px, ${ys[4]}px);
opacity: 0.0;
}
62% {
transform: translate(${xs[5]}px, ${ys[5]}px);
opacity: 0.6;
}
75% {
transform: translate(${xs[6]}px, ${ys[6]}px);
opacity: 0.6;
}
87%{
transform: translate(${xs[7]}px, ${ys[7]}px);
}
100% {
transform: translate(${xs[0]}px, ${ys[0]}px);
opacity: 0.8;
}
}`);
var timing = (Math.random() * 2) + 2;
styles.push(`#sparkle${i} {
animation: pattern${i} ${timing}s linear;
animation-iteration-count: 2;
}`);
}
var nodesJoined = nodes.join("\n"),
stylesJoined = styles.join("\n"),
template = `<?xml version="1.0" encoding="UTF-8"?>
<svg width="512px" height="512px" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Goodbeast Generative Weirdness -->
<title>Confetti</title>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation=".25" />
</filter>
<g id="Confetti" stroke="none" stroke-width="1" fill="none" filter="url(#blurMe)" fill-rule="evenodd">
${nodesJoined}
</g>
<style>
${stylesJoined}
</style>
</svg>`;
console.log(template);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment