1
0
Fork 0
mirror of https://github.com/mat-1/matdoesdev.git synced 2025-08-02 14:46:04 +00:00

add lightswitch

This commit is contained in:
mat 2024-04-30 20:23:55 -05:00
parent 5376d198d7
commit 9a10a0d910
7 changed files with 147 additions and 0 deletions

View file

@ -100,3 +100,24 @@ pre {
.token.string {
color: #aad94c;
}
body.light-theme,
body.extra-light-theme {
--background-color: #fff;
--background-color-transparent: #fff0;
--background-color-alt: #f7f7f7;
--background-color-alt-2: #eee;
--background-color-alt-3: #ddd;
--text-color: #000;
--text-color-alt: #333;
--text-color-alt-2: #666;
--text-color-alt-3: #999;
}
body.extra-light-theme {
filter: brightness(1) opacity(0.1);
}
body.extra-dark-theme {
background-color: #000;
filter: brightness(0.1);
}

View file

@ -3,6 +3,7 @@
import { fly } from 'svelte/transition'
import type { LayoutData } from '../$types'
import { browser } from '$app/environment'
import { writable } from 'svelte/store'
export let data: LayoutData
@ -50,6 +51,24 @@
}
}
}
if (browser) {
const initialTheme = localStorage.getItem('theme') ?? 'dark'
let globalTheme = writable(initialTheme)
window.addEventListener('storage', (e) => {
if (e.key === 'theme' && e.newValue) {
globalTheme.set(e.newValue)
}
})
let lastGlobalTheme = initialTheme
globalTheme.subscribe((theme) => {
document.body.classList.remove(`${lastGlobalTheme}-theme`)
if (theme !== 'dark') {
document.body.classList.add(`${theme}-theme`)
}
lastGlobalTheme = theme
})
}
</script>
{#key data.pathname}

View file

@ -0,0 +1,107 @@
<script lang="ts">
import lightSwitchOnImage from './lightswitch-on.png'
import lightSwitchOnSound from './lightswitch-on.mp3'
import lightSwitchOffImage from './lightswitch-off.png'
import lightSwitchOffSound from './lightswitch-off.mp3'
import { writable } from 'svelte/store'
import { browser } from '$app/environment'
import { onMount } from 'svelte'
let globalTheme = writable(browser ? localStorage.getItem('theme') ?? 'dark' : 'dark')
let isLightSwitchOn = writable($globalTheme === 'light' || $globalTheme === 'extra-light')
let mounted = false
onMount(() => {
window.addEventListener('storage', (e) => {
if (e.key === 'theme' && e.newValue) {
globalTheme.set(e.newValue)
}
})
mounted = true
let lastGlobalTheme = $globalTheme
globalTheme.subscribe((theme) => {
document.body.classList.remove(`${lastGlobalTheme}-theme`)
// dark theme is the default so it doesn't need to be added
if (theme !== 'dark') {
document.body.classList.add(`${theme}-theme`)
}
lastGlobalTheme = theme
})
})
isLightSwitchOn.subscribe((isLight) => {
if (!mounted) return
// play sound effect
const audio = new Audio(isLight ? lightSwitchOnSound : lightSwitchOffSound)
audio.play()
// 100ms delay to be slightly more realistic
setTimeout(() => {
if (isLight) {
$globalTheme = $globalTheme !== 'light' ? 'light' : 'extra-light'
} else {
$globalTheme = $globalTheme !== 'dark' ? 'dark' : 'extra-dark'
}
localStorage.setItem('theme', $globalTheme)
}, 100)
})
</script>
<main>
{#if mounted}
<button on:click={() => ($isLightSwitchOn = !$isLightSwitchOn)}>
<img
src={$isLightSwitchOn ? lightSwitchOnImage : lightSwitchOffImage}
alt="Light switch on"
class="lightswitch"
/>
</button>
{/if}
</main>
<style>
:global(html, body) {
height: 100%;
margin: 0;
}
button {
margin: 0;
padding: 0;
background: transparent;
border: none;
}
main {
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
filter: brightness(0.5);
}
:global(body.light-theme) main {
background-color: #fff;
filter: brightness(1);
}
:global(body.extra-light-theme) main {
background-color: #fff;
filter: brightness(1) opacity(0.1);
}
:global(body.extra-dark-theme) main {
background-color: #000;
filter: brightness(0.05);
}
.lightswitch {
image-rendering: pixelated;
cursor: pointer;
}
</style>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB