Skip to content

Commit

Permalink
🥚 Let it snow - fixes #120
Browse files Browse the repository at this point in the history
  • Loading branch information
vegeta897 committed Oct 18, 2021
1 parent 02f7bf8 commit 42e0ac2
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 3 deletions.
21 changes: 21 additions & 0 deletions public/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,24 @@ button:focus {
small {
font-size: 0.8em;
}

@keyframes snowing {
0% {
transform: translate(var(--left-start), 0) rotate(var(--angle-start));
}
100% {
transform: translate(var(--left-end), 110vh) rotate(var(--angle-end));
}
}

* {
transition-property: color, background-color;
transition-duration: 0.15s;
transition-delay: 0s;
transition-timing-function: ease-out;
}

.preload,
.preload * {
transition-property: none !important;
}
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@
<script defer src="bundle.[hash].js"></script>
</head>

<body></body>
<body class="preload"></body>
</html>
20 changes: 18 additions & 2 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
detectTimeZone,
encodeSnowflake,
decodeSnowflake,
isSnowy,
} from './util.js'
import Help from './Help.svelte'
import Output from './Output.svelte'
Expand All @@ -17,6 +18,8 @@
import Switch from './Switch.svelte'
import IconMoon from './IconMoon.svelte'
import IconSun from './IconSun.svelte'
import LetItSnow from './LetItSnow.svelte'
import { onMount } from 'svelte'
const dynamicMode = window.__SNOWSTAMP_DYNAMIC__
const { SNOWFLAKE_EPOCH } = process.env
Expand All @@ -26,7 +29,8 @@
let snowflake = queries.s || (queries.f && decodeSnowflake(queries.f)) || '',
timestamp,
error,
url
url,
letItSnow
let shareStamp = getLocalStorageBoolean('shareStamp', true)
let shortenSnowflake = getLocalStorageBoolean('shortenSnowflake', true)
Expand All @@ -43,16 +47,25 @@
localStorage.setItem('darkMode', darkMode)
}
onMount(() =>
setTimeout(() => window.document.body.classList.remove('preload'))
)
// Validate snowflake and update timestamp or error
function updateSnowflake() {
timestamp = null
error = null
letItSnow = false
if (!snowflake.trim()) return
try {
timestamp = validateSnowflake(snowflake, EPOCH)
updateURL()
} catch (e) {
error = e
if (isSnowy(snowflake)) {
letItSnow = true
} else {
error = e
}
}
}
Expand Down Expand Up @@ -133,6 +146,9 @@
{#if error}
<p style="margin-top: 0.2em;">❌ {error}</p>
{/if}
{#if letItSnow}
<LetItSnow />
{/if}
<hr />
<Credits />
</main>
Expand Down
74 changes: 74 additions & 0 deletions src/LetItSnow.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script>
import { onDestroy, onMount } from 'svelte'
const existingContainer = document.getElementsByClassName('snow-container')[0]
const container = existingContainer || document.createElement('div')
container.classList.add('snow-container')
let timeout
function addSnowflake() {
const flake = document.createElement('i')
container.appendChild(flake)
const flakeLeft = Math.floor(Math.random() * 100)
const flakeDrift = Math.floor(-10 + Math.random() * 20)
flake.style.setProperty('--left-start', `${flakeLeft}vw`)
flake.style.setProperty('--left-end', `${flakeLeft + flakeDrift}vw`)
const flakeOrientation = Math.floor(Math.random() * 360)
let flakeSpin = Math.floor(30 + Math.random() * 180)
if (Math.random() > 0.5) flakeSpin *= -1
flake.style.setProperty('--angle-start', `${flakeOrientation}deg`)
flake.style.setProperty('--angle-end', `${flakeOrientation + flakeSpin}deg`)
const flakeDuration = Math.floor(10 + Math.random() * 10)
flake.style.animation = `snowing ${flakeDuration}s linear 0s 1 normal forwards`
flake.style.opacity = 0.5 + Math.random() * 0.5
flake.style.fontSize = Math.floor(16 + Math.random() * 24) + 'px'
setTimeout(() => {
flake.remove()
}, flakeDuration * 1000)
timeout = setTimeout(addSnowflake, 200 + Math.random() * 200)
}
onMount(() => {
if (!existingContainer) document.body.appendChild(container)
addSnowflake()
})
onDestroy(() => clearTimeout(timeout))
</script>

<p class="let-it-snow">❄️ <em>Let it snow</em></p>

<style>
p.let-it-snow {
margin-top: 0.2em;
color: #008dad;
font-size: 2em;
}
:global(body.dark-mode) p.let-it-snow {
color: #69eaff;
}
:global(.snow-container) {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
:global(i) {
font-style: normal;
font-size: 2.5em;
position: absolute;
top: -40px;
opacity: 0.8;
color: #444;
}
:global(body.dark-mode i) {
color: #fff;
}
:global(i::before) {
content: '';
}
</style>
7 changes: 7 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export function decodeSnowflake(encodedSnowflake) {
return chunks.map((chunk) => parseInt(chunk, 36).toString().slice(1)).join('')
}

export function isSnowy(input) {
for (let snowText of ['❄', '❆', '❅', '🌨', '🌨️', '⛄', '☃', 'snow']) {
if (input.toLowerCase().includes(snowText)) return true
}
return false
}

// https://svelte.dev/repl/b4db6313dfeb4b50871a9b43398a6952?version=3.16.7
/** Selects the text inside a text node when the node is focused */
export function selectTextOnFocus(node) {
Expand Down

0 comments on commit 42e0ac2

Please sign in to comment.