Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class MyDocument extends Document {
render() {
return (
<Html>
<Head />
<Head>
<script src="/fireworks.js" defer></script>
</Head>
<body className="bg-gray-300 dark:bg-gray-800">
<Main />
<NextScript />
Expand Down
183 changes: 183 additions & 0 deletions public/fireworks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/* Adapted from: https://github.com/shenhuang/shenhuang.github.io/blob/master/demo_projects/fireworkdemo.html */
let embedFireworks = document.getElementById('embed--fireworks')
const numOnLoad = 3
const windowWidth = window.innerWidth
const windowHeight = window.innerHeight

function isNY() {
const now = new Date()
const nowMonth = now.getMonth() + 1
const nowDate = now.getDate()
return nowMonth === 1 && nowDate >= 1 && nowDate <= 2
}

if (isNY() && !embedFireworks) {
const embCSS =
'@keyframes firework-animation{0%,100%{background-color:#ff8426}25%{background-color:#fffc84}50%{background-color:#ff83f4}75%{background-color:#83b6ff}}@-webkit-keyframes firework-animation{0%,100%{background-color:#ff8426}25%{background-color:#fffc84}50%{background-color:#ff83f4}75%{background-color:#83b6ff}}@keyframes firework-seed-animation{0%,100%{background-color:#ff8426}25%{background-color:#fffc84}}@-webkit-keyframes firework-seed-animation{0%,100%{background-color:#ff8426}25%{background-color:#fffc84}}@keyframes firework-fade-animation{0%,50%{opacity:1}100%{opacity:0}}@-webkit-keyframes firework-fade-animation{0%,50%{opacity:1}100%{opacity:0}}.fireWorkBatch{z-index:999;position:absolute;top:0;left:0;animation-name:firework-fade-animation;animation-timing-function:cubic-bezier(0.5,0,1. 1);animation-duration:2.5s}.fireWorkParticle,.fireWorkSeed{z-index:999;position:absolute;height:5px;width:5px;animation-timing-function:linear;animation-iteration-count:infinite}.fireWorkParticle{border-radius:2.5px;animation-name:firework-animation;animation-duration:1s}.fireWorkSeed{border-radius:5px;animation-name:firework-seed-animation;animation-duration:.5s}'
embedFireworks = document.createElement('div')
embedFireworks.id = 'embed--fireworks'
const embHTML = ''
embedFireworks.innerHTML =
'<style>#embed--fireworks{position:fixed;left:0;top:0;bottom:0;width:100vw;height:100vh;overflow:hidden;z-index:9999999;pointer-events:none}' +
embCSS +
'</style>' +
embHTML
document.body.appendChild(embedFireworks)

const brd = embedFireworks
const seeds = []
const particles = []

const fwkPtcIniV = 0.5
const fwkSedIniV = 0.5
const fwkPtcIniT = 2500
const fwkSedIniT = 1000
const a = 0.0005
const g = 0.0005
const v = 0.3
const cursorXOffset = 5
const cursorYOffset = 0

function newFireworkParticle(x, y, angle) {
let fwkPtc = document.createElement('DIV')
fwkPtc.setAttribute('class', 'fireWorkParticle')
fwkPtc.time = fwkPtcIniT
while (angle > 360) angle -= 360
while (angle < 0) angle += 360
fwkPtc.velocity = []
if (angle > 270) {
fwkPtc.velocity.x =
fwkPtcIniV *
Math.sin((angle * Math.PI) / 180) *
(1 - Math.random() * v)
fwkPtc.velocity.y =
fwkPtcIniV *
Math.cos((angle * Math.PI) / 180) *
(1 - Math.random() * v)
} else if (angle > 180) {
fwkPtc.velocity.x =
fwkPtcIniV *
Math.sin((angle * Math.PI) / 180) *
(1 - Math.random() * v)
fwkPtc.velocity.y =
fwkPtcIniV *
Math.cos((angle * Math.PI) / 180) *
(1 - Math.random() * v)
} else if (angle > 90) {
fwkPtc.velocity.x =
fwkPtcIniV *
Math.sin((angle * Math.PI) / 180) *
(1 - Math.random() * v)
fwkPtc.velocity.y =
fwkPtcIniV *
Math.cos((angle * Math.PI) / 180) *
(1 - Math.random() * v)
} else {
fwkPtc.velocity.x =
fwkPtcIniV *
Math.sin((angle * Math.PI) / 180) *
(1 - Math.random() * v)
fwkPtc.velocity.y =
fwkPtcIniV *
Math.cos((angle * Math.PI) / 180) *
(1 - Math.random() * v)
}
fwkPtc.position = []
fwkPtc.position.x = x
fwkPtc.position.y = y
fwkPtc.style.left = fwkPtc.position.x + 'px'
fwkPtc.style.top = fwkPtc.position.y + 'px'
particles.push(fwkPtc)
return fwkPtc
}

document.addEventListener('click', newFireWorkOnClick)

function newFireWorkOnClick(event) {
newFireworkSeed(
event.pageX - brd.offsetLeft + cursorXOffset,
event.pageY - brd.offsetTop + cursorYOffset
)
}

function newFireworkSeed(x, y) {
const fwkSed = document.createElement('div')
fwkSed.setAttribute('class', 'fireWorkSeed')
brd.appendChild(fwkSed)
fwkSed.time = fwkSedIniT
fwkSed.velocity = []
fwkSed.velocity.x = 0
fwkSed.velocity.y = fwkSedIniV
fwkSed.position = []
fwkSed.position.x = x
fwkSed.position.y = y
fwkSed.style.left = fwkSed.position.x + 'px'
fwkSed.style.top = fwkSed.position.y + 'px'
seeds.push(fwkSed)
return fwkSed
}

function newFireWorkStar(x, y) {
const fwkBch = document.createElement('DIV')
fwkBch.setAttribute('class', 'fireWorkBatch')
let a = 0
while (a < 360) {
const fwkPtc = newFireworkParticle(x, y, a)
fwkBch.appendChild(fwkPtc)
a += 5
}
brd.appendChild(fwkBch)
}

// Few on page load
for (let i = 0; i < numOnLoad; i++) {
setTimeout(() => {
newFireworkSeed(
windowWidth * (0.25 * (i + 1)),
windowHeight * 0.5 * (0.5 * (i + 1))
)
}, 1000 * i)
}

let before = Date.now()
function frame() {
const current = Date.now()
const deltaTime = current - before
before = current
for (let i in seeds) {
const fwkSed = seeds[i]
fwkSed.time -= deltaTime
if (fwkSed.time > 0) {
fwkSed.velocity.x -= fwkSed.velocity.x * a * deltaTime
fwkSed.velocity.y -=
g * deltaTime + fwkSed.velocity.y * a * deltaTime
fwkSed.position.x += fwkSed.velocity.x * deltaTime
fwkSed.position.y -= fwkSed.velocity.y * deltaTime
fwkSed.style.left = fwkSed.position.x + 'px'
fwkSed.style.top = fwkSed.position.y + 'px'
} else {
newFireWorkStar(fwkSed.position.x, fwkSed.position.y)
fwkSed.parentNode.removeChild(fwkSed)
seeds.splice(i, 1)
}
}
for (let i in particles) {
const fwkPtc = particles[i]
fwkPtc.time -= deltaTime
if (fwkPtc.time > 0) {
fwkPtc.velocity.x -= fwkPtc.velocity.x * a * deltaTime
fwkPtc.velocity.y -=
g * deltaTime + fwkPtc.velocity.y * a * deltaTime
fwkPtc.position.x += fwkPtc.velocity.x * deltaTime
fwkPtc.position.y -= fwkPtc.velocity.y * deltaTime
fwkPtc.style.left = fwkPtc.position.x + 'px'
fwkPtc.style.top = fwkPtc.position.y + 'px'
} else {
fwkPtc.parentNode.removeChild(fwkPtc)
particles.splice(i, 1)
}
}
window.requestAnimationFrame(frame)
}
window.requestAnimationFrame(frame)
}
95 changes: 95 additions & 0 deletions public/snow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* https://embed.im/snow */
const snowSize = 7
let embedimSnow = document.getElementById('embedim--snow')
let windowWidth

function isXmas() {
const now = new Date()
const nowMonth = now.getMonth() + 1
const nowDate = now.getDate()
return nowMonth === 12 && nowDate >= 15 && nowDate <= 31
}

if (isXmas() && !embedimSnow) {
windowWidth = window.innerWidth
function embRand(a, b) {
return Math.floor(Math.random() * (b - a + 1)) + a
}
let embCSS = `.embedim-snow{position: absolute;width: ${snowSize}px;height: ${snowSize}px;background: white;border-radius: 50%;margin-top:-10px}`
let embHTML = ''
for (i = 1; i < 200; i++) {
embHTML += '<i class="embedim-snow"></i>'
var rndX = embRand(0, 1000000) * 0.0001,
rndO = embRand(-100000, 100000) * 0.0001,
rndT = (embRand(3, 8) * 10).toFixed(2),
rndS = (embRand(0, 10000) * 0.0001).toFixed(2)
embCSS +=
'.embedim-snow:nth-child(' +
i +
'){' +
'opacity:' +
(embRand(1, 10000) * 0.0001).toFixed(2) +
';' +
'transform:translate(' +
rndX.toFixed(2) +
'vw,-10px) scale(' +
rndS +
');' +
'animation:fall-' +
i +
' ' +
embRand(10, 30) +
's -' +
embRand(0, 30) +
's linear infinite' +
'}' +
'@keyframes fall-' +
i +
'{' +
rndT +
'%{' +
'transform:translate(' +
(rndX + rndO).toFixed(2) +
'vw,' +
rndT +
'vh) scale(' +
rndS +
')' +
'}' +
'to{' +
'transform:translate(' +
(rndX + rndO / 2).toFixed(2) +
'vw, 105vh) scale(' +
rndS +
')' +
'}' +
'}'
}
embedimSnow = document.createElement('div')
embedimSnow.id = 'embedim--snow'
const innerHtml =
'<style>#embedim--snow{position:fixed;left:0;top:0;bottom:0;width:100vw;height:100vh;overflow:hidden;z-index:9999999;pointer-events:none}' +
embCSS +
'</style>' +
embHTML
embedimSnow.innerHTML = innerHtml

const resizeHandler = debounce(() => {
if (windowWidth !== window.innerWidth) {
embedimSnow.innerHTML = innerHtml
windowWidth = window.innerWidth
}
})
window.addEventListener('resize', resizeHandler)
document.body.appendChild(embedimSnow)
}

function debounce(cb, delay = 250) {
let timeout
return (...args) => {
clearTimeout(timeout)
timeout = setTimeout(() => {
cb(...args)
}, delay)
}
}
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2081,9 +2081,9 @@ json-stable-stringify-without-jsonify@^1.0.1:
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==

json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
dependencies:
minimist "^1.2.0"

Expand Down