your personal website on atproto - mirror

improve fluid text effect, add colors, fix fps

Florian c5591712 246278ed

+38 -7
+3 -1
src/lib/cards/FluidTextCard/EditingFluidTextCard.svelte
··· 36 : ''}" 37 onclick={handleClick} 38 > 39 - <FluidTextCard {item} /> 40 41 {#if isEditing} 42 <!-- svelte-ignore a11y_autofocus -->
··· 36 : ''}" 37 onclick={handleClick} 38 > 39 + {#key item.color} 40 + <FluidTextCard {item} /> 41 + {/key} 42 43 {#if isEditing} 44 <!-- svelte-ignore a11y_autofocus -->
+20 -5
src/lib/cards/FluidTextCard/FluidTextCard.svelte
··· 1 <script lang="ts"> 2 import type { ContentComponentProps } from '../types'; 3 import { onMount, onDestroy, tick } from 'svelte'; 4 let { item }: ContentComponentProps = $props(); ··· 131 ctx.clearRect(0, 0, maskCanvas.width, maskCanvas.height); 132 ctx.scale(dpr, dpr); 133 134 ctx.fillStyle = 'black'; 135 ctx.fillRect(0, 0, width, height); 136 ··· 195 onMount(async () => { 196 // Wait for layout to settle 197 await tick(); 198 // Wait for a frame to ensure dimensions are set 199 requestAnimationFrame(() => { 200 - initFluidSimulation(); 201 }); 202 203 if (document.fonts?.ready) { ··· 214 if (resizeObserver) resizeObserver.disconnect(); 215 }); 216 217 - function initFluidSimulation() { 218 if (!fluidCanvas || !maskCanvas || !container) return; 219 220 maskReady = false; ··· 247 SUNRAYS: true, 248 SUNRAYS_RESOLUTION: 196, 249 SUNRAYS_WEIGHT: 1.0, 250 - START_HUE: 0.5, 251 - END_HUE: 1.0, 252 RENDER_SPEED: 0.4 253 }; 254 ··· 1510 function calcDeltaTime() { 1511 const now = Date.now(); 1512 let dt = (now - lastUpdateTime) / 1000; 1513 - dt = Math.min(dt, 0.016666); 1514 lastUpdateTime = now; 1515 return dt; 1516 }
··· 1 <script lang="ts"> 2 + import { colorToHue, getCSSVar } from '../helper'; 3 import type { ContentComponentProps } from '../types'; 4 import { onMount, onDestroy, tick } from 'svelte'; 5 let { item }: ContentComponentProps = $props(); ··· 132 ctx.clearRect(0, 0, maskCanvas.width, maskCanvas.height); 133 ctx.scale(dpr, dpr); 134 135 + //const color = getCSSVar('--color-base-900'); 136 + 137 ctx.fillStyle = 'black'; 138 ctx.fillRect(0, 0, width, height); 139 ··· 198 onMount(async () => { 199 // Wait for layout to settle 200 await tick(); 201 + 202 + let color = 203 + !item.color || item.color === 'transparent' || item.color === 'base' 204 + ? 'accent' 205 + : item.color; 206 + 207 + const computedColor = getCSSVar(`--color-${color}-500`); 208 + const hue = colorToHue(computedColor) / 360; 209 + console.log(computedColor, hue); 210 + 211 // Wait for a frame to ensure dimensions are set 212 requestAnimationFrame(() => { 213 + initFluidSimulation(hue, hue - 0.3); 214 }); 215 216 if (document.fonts?.ready) { ··· 227 if (resizeObserver) resizeObserver.disconnect(); 228 }); 229 230 + function initFluidSimulation(startHue: number, endHue: number) { 231 if (!fluidCanvas || !maskCanvas || !container) return; 232 233 maskReady = false; ··· 260 SUNRAYS: true, 261 SUNRAYS_RESOLUTION: 196, 262 SUNRAYS_WEIGHT: 1.0, 263 + START_HUE: startHue, 264 + END_HUE: endHue, 265 RENDER_SPEED: 0.4 266 }; 267 ··· 1523 function calcDeltaTime() { 1524 const now = Date.now(); 1525 let dt = (now - lastUpdateTime) / 1000; 1526 + // Allow up to ~30fps worth of time to pass per frame to handle browser throttling 1527 + // This prevents the simulation from appearing to slow down when RAF is throttled 1528 + dt = Math.min(dt, 0.033); 1529 lastUpdateTime = now; 1530 return dt; 1531 }
+1 -1
src/lib/cards/FluidTextCard/index.ts
··· 22 settingsComponent: FluidTextCardSettings, 23 sidebarButtonText: 'Fluid Text', 24 defaultColor: 'transparent', 25 - allowSetColor: false, 26 minW: 2 27 } as CardDefinition & { type: 'fluid-text' };
··· 22 settingsComponent: FluidTextCardSettings, 23 sidebarButtonText: 'Fluid Text', 24 defaultColor: 'transparent', 25 + allowSetColor: true, 26 minW: 2 27 } as CardDefinition & { type: 'fluid-text' };
+14
src/lib/cards/helper.ts
···
··· 1 + import { convertCSSToHex, hex_to_okhsv } from '@foxui/colors'; 2 + 3 + export function getCSSVar(variable: string) { 4 + return getComputedStyle(document.body).getPropertyValue(variable).trim(); 5 + } 6 + 7 + /** 8 + * Converts a CSS color string to a hue value in the 0-1 range 9 + */ 10 + export function colorToHue(color: string): number { 11 + const hex = convertCSSToHex(color); 12 + const okhsv = hex_to_okhsv(hex); 13 + return okhsv.h; 14 + }