10 Commits

Author SHA1 Message Date
4f4c85c85a Bump version to 1.3.3 2025-06-11 21:34:28 -07:00
40bf1f6169 Improve theme settings interface 2025-06-11 21:26:56 -07:00
1ebb927c66 Zakarya page: add link to Colormatic Git profile 2025-06-11 21:25:33 -07:00
52662a6e4e Zakarya page: break up bio 2025-06-11 21:24:29 -07:00
5d9bd0f369 Remove period from construction notice
It did not play well with the formatter
2025-06-11 21:22:46 -07:00
12a51f18d2 Image optimizations 2025-06-11 21:22:05 -07:00
ea0cc34ba8 Require use of Svelte Runes 2025-06-11 21:18:37 -07:00
7fe92c971b Format bg.svelte 2025-06-11 21:17:43 -07:00
6df7d0565b Merge branch 'main' of git.colormatic.org:ColormaticStudios/Colormatic-Website
Merge commit oopsies
2025-06-11 16:38:18 -07:00
7958230d34 BG: Only update entities if animated is true 2025-06-11 16:37:10 -07:00
12 changed files with 149 additions and 78 deletions

View File

@ -1,6 +1,6 @@
{
"name": "colormatic-website",
"version": "1.3.1",
"version": "1.3.3",
"type": "module",
"scripts": {
"dev": "vite dev",

View File

@ -21,7 +21,7 @@
if (!animated && ctx) {
// Don't try to render if ctx hasn't initialized yet
render();
render(false);
}
});
@ -66,12 +66,12 @@
});
Promise.all(Object.values(imagePromises)).then(() => {
render();
render(false);
});
resize();
init();
render();
render(false);
animate();
window.addEventListener("resize", resize);
@ -84,7 +84,7 @@
canvasDpiScaler(canvas, ctx);
if (!animated) {
render();
render(false);
}
}
@ -306,8 +306,7 @@
let particleCount: number;
if (isMobile) {
particleCount = 25;
}
else {
} else {
particleCount = 40;
}
@ -321,25 +320,25 @@
}
}
function render() {
function render(update: boolean) {
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
for (let i_gradient = 0; i_gradient < gradients.length; i_gradient++) {
let gradient = gradients[i_gradient];
gradient.update();
if (update) gradient.update();
gradient.draw();
}
for (let i_particle = 0; i_particle < particles.length; i_particle++) {
let particle = particles[i_particle];
particle.update();
if (update) particle.update();
particle.draw();
}
}
function animate() {
if (animated) {
render();
render(true);
}
requestAnimationFrame(animate);

View File

@ -3,6 +3,8 @@
import { themes } from "../script/theme.ts";
import { setCookie, getCookie } from "../script/cookie.ts";
let panelRef = $state() as HTMLElement;
let lightButtonIcon = $state() as HTMLElement;
let darkButtonIcon = $state() as HTMLElement;
let autoButtonIcon = $state() as HTMLElement;
@ -13,32 +15,28 @@
let { themeOption = $bindable() } = $props();
let expanded = $state(false);
let currentIcon = $state("bi-circle-half");
let darkTheme: CallableFunction = getContext("darkTheme");
function setThemeOption(newThemeOption: string) {
expanded = false;
setCookie("theme", newThemeOption);
themeOption = newThemeOption;
switch (newThemeOption) {
case themes.LIGHT:
themeOption = themes.LIGHT;
lightButtonIcon.classList.replace("bi-sun", "bi-sun-fill");
darkButtonIcon.classList.replace("bi-moon-fill", "bi-moon");
autoButtonIcon.classList.replace("bi-display-fill", "bi-display");
currentIcon = "bi-sun-fill";
break;
case themes.DARK:
themeOption = themes.DARK;
lightButtonIcon.classList.replace("bi-sun-fill", "bi-sun");
darkButtonIcon.classList.replace("bi-moon", "bi-moon-fill");
autoButtonIcon.classList.replace("bi-display-fill", "bi-display");
currentIcon = "bi-moon-fill";
break;
case themes.AUTO:
themeOption = themes.AUTO;
lightButtonIcon.classList.replace("bi-sun-fill", "bi-sun");
darkButtonIcon.classList.replace("bi-moon-fill", "bi-moon");
autoButtonIcon.classList.replace("bi-display", "bi-display-fill");
currentIcon = "bi-circle-half";
break;
default:
console.error("setThemeOption was passed a value that is not a theme");
console.error("Invalid theme option");
}
}
@ -47,59 +45,113 @@
if (Object.values(themes).includes(themeCookie)) {
setThemeOption(themeCookie);
}
function handleClickOutside(event: MouseEvent) {
if (panelRef && !panelRef.contains(event.target as HTMLElement)) {
expanded = false;
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
});
let darkTheme: CallableFunction = getContext("darkTheme");
function togglePanel() {
expanded = !expanded;
}
</script>
<div class="panel settings {darkTheme() ? 'dark-theme' : ''}">
<div
bind:this={panelRef}
class="theme-toggle panel {darkTheme() ? 'dark-theme' : ''}"
>
<button
aria-label="Dark Theme"
bind:this={darkButton}
onclick={() => {
setThemeOption(themes.DARK);
}}
class="toggle-button"
onclick={togglePanel}
aria-label="Toggle Theme Selector"
>
<i bind:this={darkButtonIcon} class="bi bi-moon"></i>
</button>
<button
aria-label="Light Theme"
bind:this={lightButton}
onclick={() => {
setThemeOption(themes.LIGHT);
}}
>
<i bind:this={lightButtonIcon} class="bi bi-sun"></i>
</button>
<button
aria-label="Auto Theme"
bind:this={autoButton}
onclick={() => {
setThemeOption(themes.AUTO);
}}
>
<i bind:this={autoButtonIcon} class="bi bi-display-fill"></i>
<i class={`bi ${currentIcon}`}></i>
</button>
<!-- Unfortunately, we have to hard-code 72px because CSS won't animate `auto` or `min-content` -->
<div class="button-group" style:height={expanded ? "68px" : "0px"}>
<!-- Don't show the button if it is currently selected (it will be shown as the dropdown icon) -->
{#if themeOption !== themes.DARK}
<button
aria-label="Dark Theme"
bind:this={darkButton}
onclick={() => setThemeOption(themes.DARK)}
>
<i bind:this={darkButtonIcon} class="bi bi-moon"></i>
</button>
{/if}
{#if themeOption !== themes.LIGHT}
<button
aria-label="Light Theme"
bind:this={lightButton}
onclick={() => setThemeOption(themes.LIGHT)}
>
<i bind:this={lightButtonIcon} class="bi bi-sun"></i>
</button>
{/if}
{#if themeOption !== themes.AUTO}
<button
aria-label="Auto Theme"
bind:this={autoButton}
onclick={() => setThemeOption(themes.AUTO)}
>
<i bind:this={autoButtonIcon} class="bi bi-circle-half"></i>
</button>
{/if}
</div>
</div>
<style lang="scss">
@use "../style/global.scss";
div.panel.settings {
padding: 6px 8px;
div.theme-toggle {
padding: 4px;
position: fixed;
bottom: 20px;
right: 20px;
display: flex;
flex-direction: column-reverse;
align-items: flex-end;
}
div.panel.settings button {
color: global.$text-color;
font-size: 110%;
cursor: pointer;
// Reset buton style
button.toggle-button {
font-size: 1.3rem;
background: transparent;
border: none;
background-color: #00000000;
border-radius: 0;
cursor: pointer;
color: global.$text-color;
aspect-ratio: 1 / 1;
}
div.button-group {
overflow: hidden;
transition: height 0.3s ease;
display: flex;
flex-direction: column;
}
div.button-group button {
margin: 2px 0;
font-size: 1.3rem;
background: transparent;
border: none;
color: global.$text-color;
cursor: pointer;
}
@media screen and (max-width: global.$mobile-width) {
div.button-group button {
margin: 4px 0;
}
}
</style>

View File

@ -101,7 +101,6 @@
>
ColormaticStudios/Colormatic-Website
</a>
.
</p>
</div>
</main>

View File

@ -30,29 +30,47 @@
</svelte:head>
<main class={darkTheme() ? "dark-theme" : ""}>
<img class="banner" src="/img/zakarya-banner.png" alt="Zakarya Banner" />
<img
class="banner"
src="/img/zakarya-banner.webp"
alt="Zakarya Banner"
srcset="/img/zakarya-banner.webp 960w, /img/zakarya-banner@2x.webp 1920w"
/>
<div class="hero panel profile">
<div class="nameplate">
<img
src="/img/zakarya-icon.png"
src="/img/zakarya-icon.webp"
class="zakarya-icon"
alt="Zakarya Icon"
srcset="/img/zakarya-icon.webp 540w, /img/zakarya-icon@2x.webp 1080w"
/>
<span class="name-title">Zakarya</span>
</div>
<p>
I am a software and game developer, I run Colormatic and Colormatic
Studios, and I primarily study computer science, psychology, and
linguistics.
<br />
I have an intrinsic urge to create, and that's what Colormatic is all about.
My works include world building, music, videos, 3D modeling, video games, websites,
programs, and more.
</p>
<div class="bio">
<p>
I am a software and game developer, I run Colormatic and Colormatic
Studios, and I primarily study computer science, psychology, and
linguistics.
</p>
<p>
I have an intrinsic urge to create, and that's what Colormatic is all
about. My works include world building, music, videos, 3D modeling,
video games, websites, programs, and more.
</p>
</div>
<div class="linktree-container">
<ul class="linktree">
<li>
<a
href="https://git.colormatic.org/zakarya"
target="_blank"
rel="noopener noreferrer"
>
Colormatic Git
</a>
</li>
<li>
<a
href="https://mstdn.party/@zakarya"
@ -156,7 +174,7 @@
font-size: 200%;
}
main div.profile p {
main div.profile div.bio {
font-size: 120%;
max-width: 50%;
padding: 16px;
@ -185,7 +203,7 @@
margin: 24px auto;
}
main div.profile p {
main div.profile div.bio {
max-width: unset;
}
@ -212,7 +230,7 @@
}
}
main.dark-theme div.profile p {
main.dark-theme div.profile div.bio {
border-color: #ffffff55;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

View File

@ -7,6 +7,9 @@ const config = {
kit: {
adapter: adapter(),
},
compilerOptions: {
runes: true,
},
};
export default config;