forked from thedevelobear/react-rewards
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5b69713
commit 3ff3649
Showing
7 changed files
with
295 additions
and
280 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"env": { | ||
"jest": true | ||
} | ||
"env": { | ||
"jest": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,108 @@ | ||
const PI = Math.PI | ||
const defaultColors = [ | ||
'#A45BF1', | ||
'#25C6F6', | ||
'#72F753', | ||
'#F76C88', | ||
'#F5F770' | ||
] | ||
const PI = Math.PI; | ||
const defaultColors = ["#A45BF1", "#25C6F6", "#72F753", "#F76C88", "#F5F770"]; | ||
|
||
const createElements = (root, elementCount, elementSize, zIndex, colors) => ( | ||
Array | ||
.from({ length: elementCount }) | ||
.map((_, index) => { | ||
const element = document.createElement('span') | ||
const color = colors[index % colors.length] | ||
element.style['background-color'] = color | ||
element.style.width = `${elementSize}px` | ||
element.style.height = `${elementSize}px` | ||
element.style.position = 'absolute' | ||
element.style.zIndex = zIndex | ||
root.appendChild(element) | ||
return element | ||
}) | ||
) | ||
const createElements = (root, elementCount, elementSize, zIndex, colors) => | ||
Array.from({ length: elementCount }).map((_, index) => { | ||
const element = document.createElement("span"); | ||
const color = colors[index % colors.length]; | ||
element.style["background-color"] = color; | ||
element.style.width = `${elementSize}px`; | ||
element.style.height = `${elementSize}px`; | ||
element.style.position = "absolute"; | ||
element.style.zIndex = zIndex; | ||
root.appendChild(element); | ||
return element; | ||
}); | ||
|
||
const radiansFrom = degrees => degrees * (PI / 180) | ||
const radiansFrom = (degrees) => degrees * (PI / 180); | ||
|
||
const generatePhysics = (angle, spread, startVelocity, random) => { | ||
const radAngle = radiansFrom(angle) | ||
const radSpread = radiansFrom(spread) | ||
return { | ||
x: 0, | ||
y: 0, | ||
wobble: random() * 10, | ||
velocity: (startVelocity * 0.5) + (random() * startVelocity), | ||
angle2D: -radAngle + ((0.5 * radSpread) - (random() * radSpread)), | ||
angle3D: -(PI / 4) + (random() * (PI / 2)), | ||
tiltAngle: random() * PI | ||
} | ||
} | ||
const radAngle = radiansFrom(angle); | ||
const radSpread = radiansFrom(spread); | ||
return { | ||
x: 0, | ||
y: 0, | ||
wobble: random() * 10, | ||
velocity: startVelocity * 0.5 + random() * startVelocity, | ||
angle2D: -radAngle + (0.5 * radSpread - random() * radSpread), | ||
angle3D: -(PI / 4) + random() * (PI / 2), | ||
tiltAngle: random() * PI, | ||
}; | ||
}; | ||
|
||
const updateFetti = (fetti, progress, decay, index) => { | ||
fetti.physics.x += Math.cos(fetti.physics.angle2D) * fetti.physics.velocity | ||
fetti.physics.y += Math.sin(fetti.physics.angle2D) * fetti.physics.velocity | ||
fetti.physics.z += Math.sin(fetti.physics.angle3D) * fetti.physics.velocity | ||
fetti.physics.wobble += 0.05 | ||
fetti.physics.velocity *= decay | ||
fetti.physics.y += 3.5 | ||
fetti.physics.tiltAngle += 0.15 | ||
fetti.physics.x += Math.cos(fetti.physics.angle2D) * fetti.physics.velocity; | ||
fetti.physics.y += Math.sin(fetti.physics.angle2D) * fetti.physics.velocity; | ||
fetti.physics.z += Math.sin(fetti.physics.angle3D) * fetti.physics.velocity; | ||
fetti.physics.wobble += 0.05; | ||
fetti.physics.velocity *= decay; | ||
fetti.physics.y += 3.5; | ||
fetti.physics.tiltAngle += 0.15; | ||
|
||
const { x, y, tiltAngle, wobble } = fetti.physics | ||
const wobbleX = index % 2 === 0 ? x + (6 * Math.sin(wobble) + progress) : x + (12 * Math.cos(wobble) + progress) | ||
const wobbleY = y + (5 * Math.sin(wobble)) | ||
const transform = `translate3d(${wobbleX}px, ${wobbleY}px, 0) rotate3d(1, 1, 1, ${tiltAngle}rad)` | ||
const { x, y, tiltAngle, wobble } = fetti.physics; | ||
const wobbleX = | ||
index % 2 === 0 | ||
? x + (6 * Math.sin(wobble) + progress) | ||
: x + (12 * Math.cos(wobble) + progress); | ||
const wobbleY = y + 5 * Math.sin(wobble); | ||
const transform = `translate3d(${wobbleX}px, ${wobbleY}px, 0) rotate3d(1, 1, 1, ${tiltAngle}rad)`; | ||
|
||
fetti.element.style.transform = transform | ||
fetti.element.style.scale = 1 - 0.2 * progress | ||
fetti.element.style.opacity = 1 - progress | ||
} | ||
fetti.element.style.transform = transform; | ||
fetti.element.style.scale = 1 - 0.2 * progress; | ||
fetti.element.style.opacity = 1 - progress; | ||
}; | ||
|
||
const animate = (root, fettis, decay, lifetime) => { | ||
const totalTicks = lifetime | ||
let tick = 0 | ||
const totalTicks = lifetime; | ||
let tick = 0; | ||
|
||
const update = () => { | ||
fettis.forEach((fetti, index) => updateFetti(fetti, tick / totalTicks, decay, index)) | ||
const update = () => { | ||
fettis.forEach((fetti, index) => | ||
updateFetti(fetti, tick / totalTicks, decay, index) | ||
); | ||
|
||
tick += 1 | ||
if (tick < totalTicks) { | ||
window.requestAnimationFrame(update) | ||
} else { | ||
fettis.forEach((fetti) => { | ||
if (fetti.element.parentNode === root) { | ||
return root.removeChild(fetti.element) | ||
} | ||
}) | ||
} | ||
} | ||
tick += 1; | ||
if (tick < totalTicks) { | ||
window.requestAnimationFrame(update); | ||
} else { | ||
fettis.forEach((fetti) => { | ||
if (fetti.element.parentNode === root) { | ||
return root.removeChild(fetti.element); | ||
} | ||
}); | ||
} | ||
}; | ||
|
||
window.requestAnimationFrame(update) | ||
} | ||
window.requestAnimationFrame(update); | ||
}; | ||
|
||
const confetti = (root, { | ||
elementCount = 50, | ||
elementSize = 8, | ||
colors = defaultColors, | ||
angle = 90, | ||
spread = 45, | ||
decay = 0.9, | ||
lifetime = 200, | ||
startVelocity = 35, | ||
zIndex = 0, | ||
random = Math.random | ||
} = {}) => { | ||
const elements = createElements(root, elementCount, elementSize, zIndex, colors) | ||
const fettis = elements.map((element) => ({ | ||
element, | ||
physics: generatePhysics(angle, spread, startVelocity, random) | ||
})) | ||
const confetti = ( | ||
root, | ||
{ | ||
elementCount = 50, | ||
elementSize = 8, | ||
colors = defaultColors, | ||
angle = 90, | ||
spread = 45, | ||
decay = 0.9, | ||
lifetime = 200, | ||
startVelocity = 35, | ||
zIndex = 0, | ||
random = Math.random, | ||
} = {} | ||
) => { | ||
const elements = createElements( | ||
root, | ||
elementCount, | ||
elementSize, | ||
zIndex, | ||
colors | ||
); | ||
const fettis = elements.map((element) => ({ | ||
element, | ||
physics: generatePhysics(angle, spread, startVelocity, random), | ||
})); | ||
|
||
animate(root, fettis, decay, lifetime) | ||
} | ||
export default confetti | ||
animate(root, fettis, decay, lifetime); | ||
}; | ||
export default confetti; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,101 @@ | ||
const PI = Math.PI | ||
const defaultEmoji = [ | ||
'👍', | ||
'😊', | ||
'🎉' | ||
] | ||
const PI = Math.PI; | ||
const defaultEmoji = ["👍", "😊", "🎉"]; | ||
|
||
const createElements = (root, elementCount, elementSize, zIndex, emoji) => ( | ||
Array | ||
.from({ length: elementCount }) | ||
.map((_, index) => { | ||
const element = document.createElement('span') | ||
const emojiIcon = emoji[index % emoji.length] | ||
element.innerHTML = emojiIcon | ||
element.style.fontSize = `${elementSize}px` | ||
element.style.position = 'absolute' | ||
element.style.zIndex = zIndex | ||
root.appendChild(element) | ||
return element | ||
}) | ||
) | ||
const createElements = (root, elementCount, elementSize, zIndex, emoji) => | ||
Array.from({ length: elementCount }).map((_, index) => { | ||
const element = document.createElement("span"); | ||
const emojiIcon = emoji[index % emoji.length]; | ||
element.innerHTML = emojiIcon; | ||
element.style.fontSize = `${elementSize}px`; | ||
element.style.position = "absolute"; | ||
element.style.zIndex = zIndex; | ||
root.appendChild(element); | ||
return element; | ||
}); | ||
|
||
const radiansFrom = degrees => degrees * (PI / 180) | ||
const radiansFrom = (degrees) => degrees * (PI / 180); | ||
|
||
const generatePhysics = (angle, spread, startVelocity, random) => { | ||
const radAngle = radiansFrom(angle) | ||
const radSpread = radiansFrom(spread) | ||
return { | ||
x: 0, | ||
y: 0, | ||
wobble: random() * 10, | ||
velocity: (startVelocity * 0.5) + (random() * startVelocity), | ||
angle2D: -radAngle + ((0.5 * radSpread) - (random() * radSpread)), | ||
angle3D: -(PI / 4) + (random() * (PI / 2)), | ||
tiltAngle: random() * PI | ||
} | ||
} | ||
const radAngle = radiansFrom(angle); | ||
const radSpread = radiansFrom(spread); | ||
return { | ||
x: 0, | ||
y: 0, | ||
wobble: random() * 10, | ||
velocity: startVelocity * 0.5 + random() * startVelocity, | ||
angle2D: -radAngle + (0.5 * radSpread - random() * radSpread), | ||
angle3D: -(PI / 4) + random() * (PI / 2), | ||
tiltAngle: random() * PI, | ||
}; | ||
}; | ||
|
||
const updateMojis = (fetti, progress, decay) => { | ||
fetti.physics.x += Math.cos(fetti.physics.angle2D) * fetti.physics.velocity | ||
fetti.physics.y += Math.sin(fetti.physics.angle2D) * fetti.physics.velocity | ||
fetti.physics.wobble += 0 | ||
fetti.physics.velocity *= decay | ||
fetti.physics.y += 5 | ||
fetti.physics.tiltAngle += 0.1 | ||
fetti.physics.x += Math.cos(fetti.physics.angle2D) * fetti.physics.velocity; | ||
fetti.physics.y += Math.sin(fetti.physics.angle2D) * fetti.physics.velocity; | ||
fetti.physics.wobble += 0; | ||
fetti.physics.velocity *= decay; | ||
fetti.physics.y += 5; | ||
fetti.physics.tiltAngle += 0.1; | ||
|
||
const { x, y, tiltAngle } = fetti.physics | ||
const wobbleX = x + 0 | ||
const wobbleY = y + 0 | ||
const transform = `translate3d(${wobbleX}px, ${wobbleY}px, 0) rotate(${tiltAngle}rad)` | ||
const { x, y, tiltAngle } = fetti.physics; | ||
const wobbleX = x + 0; | ||
const wobbleY = y + 0; | ||
const transform = `translate3d(${wobbleX}px, ${wobbleY}px, 0) rotate(${tiltAngle}rad)`; | ||
|
||
fetti.element.style.transform = transform | ||
fetti.element.style.opacity = 1 - progress | ||
} | ||
fetti.element.style.transform = transform; | ||
fetti.element.style.opacity = 1 - progress; | ||
}; | ||
|
||
const animate = (root, mojis, decay, lifetime) => { | ||
const totalTicks = lifetime | ||
let tick = 0 | ||
const totalTicks = lifetime; | ||
let tick = 0; | ||
|
||
const update = () => { | ||
mojis.forEach((fetti) => updateMojis(fetti, tick / totalTicks, decay)) | ||
const update = () => { | ||
mojis.forEach((fetti) => updateMojis(fetti, tick / totalTicks, decay)); | ||
|
||
tick += 1 | ||
if (tick < totalTicks) { | ||
window.requestAnimationFrame(update) | ||
} else { | ||
mojis.forEach((fetti) => { | ||
if (fetti.element.parentNode === root) { | ||
return root.removeChild(fetti.element) | ||
} | ||
}) | ||
} | ||
} | ||
tick += 1; | ||
if (tick < totalTicks) { | ||
window.requestAnimationFrame(update); | ||
} else { | ||
mojis.forEach((fetti) => { | ||
if (fetti.element.parentNode === root) { | ||
return root.removeChild(fetti.element); | ||
} | ||
}); | ||
} | ||
}; | ||
|
||
window.requestAnimationFrame(update) | ||
} | ||
window.requestAnimationFrame(update); | ||
}; | ||
|
||
const emoji = (root, { | ||
angle = 90, | ||
decay = 0.9, | ||
spread = 45, | ||
startVelocity = 35, | ||
elementCount = 50, | ||
elementSize = 25, | ||
lifetime = 200, | ||
zIndex = 0, | ||
emoji = defaultEmoji, | ||
random = Math.random | ||
} = {}) => { | ||
const elements = createElements(root, elementCount, elementSize, zIndex, emoji) | ||
const mojis = elements.map((element) => ({ | ||
element, | ||
physics: generatePhysics(angle, spread, startVelocity, random) | ||
})) | ||
const emoji = ( | ||
root, | ||
{ | ||
angle = 90, | ||
decay = 0.9, | ||
spread = 45, | ||
startVelocity = 35, | ||
elementCount = 50, | ||
elementSize = 25, | ||
lifetime = 200, | ||
zIndex = 0, | ||
emoji = defaultEmoji, | ||
random = Math.random, | ||
} = {} | ||
) => { | ||
const elements = createElements( | ||
root, | ||
elementCount, | ||
elementSize, | ||
zIndex, | ||
emoji | ||
); | ||
const mojis = elements.map((element) => ({ | ||
element, | ||
physics: generatePhysics(angle, spread, startVelocity, random), | ||
})); | ||
|
||
animate(root, mojis, decay, lifetime) | ||
} | ||
animate(root, mojis, decay, lifetime); | ||
}; | ||
|
||
export default emoji | ||
export default emoji; |
Oops, something went wrong.