|
|
|
|
@@ -15,8 +15,10 @@ import {
|
|
|
|
|
createTypographyControl,
|
|
|
|
|
} from '$shared/lib';
|
|
|
|
|
import type { LineData } from '$shared/lib';
|
|
|
|
|
import { Loader } from '$shared/ui';
|
|
|
|
|
import { comparisonStore } from '$widgets/ComparisonSlider/model';
|
|
|
|
|
import { Spring } from 'svelte/motion';
|
|
|
|
|
import { fade } from 'svelte/transition';
|
|
|
|
|
import CharacterSlot from './components/CharacterSlot.svelte';
|
|
|
|
|
import ControlsWrapper from './components/ControlsWrapper.svelte';
|
|
|
|
|
import Labels from './components/Labels.svelte';
|
|
|
|
|
@@ -26,6 +28,8 @@ import SliderLine from './components/SliderLine.svelte';
|
|
|
|
|
const fontA = $derived(comparisonStore.fontA);
|
|
|
|
|
const fontB = $derived(comparisonStore.fontB);
|
|
|
|
|
|
|
|
|
|
const isLoading = $derived(comparisonStore.isLoading || !comparisonStore.isReady);
|
|
|
|
|
|
|
|
|
|
let container: HTMLElement | undefined = $state();
|
|
|
|
|
let controlsWrapperElement = $state<HTMLDivElement | null>(null);
|
|
|
|
|
let measureCanvas: HTMLCanvasElement | undefined = $state();
|
|
|
|
|
@@ -164,31 +168,33 @@ $effect(() => {
|
|
|
|
|
</div>
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
{#if fontA && fontB}
|
|
|
|
|
<!-- Hidden canvas used for text measurement by the helper -->
|
|
|
|
|
<canvas bind:this={measureCanvas} class="hidden" width="1" height="1"></canvas>
|
|
|
|
|
<!-- Hidden canvas used for text measurement by the helper -->
|
|
|
|
|
<canvas bind:this={measureCanvas} class="hidden" width="1" height="1"></canvas>
|
|
|
|
|
|
|
|
|
|
<div class="relative">
|
|
|
|
|
<div
|
|
|
|
|
bind:this={container}
|
|
|
|
|
role="slider"
|
|
|
|
|
tabindex="0"
|
|
|
|
|
aria-valuenow={Math.round(sliderPos)}
|
|
|
|
|
aria-label="Font comparison slider"
|
|
|
|
|
onpointerdown={startDragging}
|
|
|
|
|
class="
|
|
|
|
|
group relative w-full py-16 px-24 sm:py-24 sm:px-24 overflow-hidden
|
|
|
|
|
rounded-[2.5rem]
|
|
|
|
|
select-none touch-none cursor-ew-resize min-h-100 flex flex-col justify-center
|
|
|
|
|
backdrop-blur-lg bg-gradient-to-br from-gray-100/70 via-white/50 to-gray-100/60
|
|
|
|
|
border border-gray-300/40
|
|
|
|
|
shadow-[inset_0_4px_12px_0_rgba(0,0,0,0.12),inset_0_2px_4px_0_rgba(0,0,0,0.08),0_1px_2px_0_rgba(255,255,255,0.8)]
|
|
|
|
|
before:absolute before:inset-0 before:rounded-[2.5rem] before:p-[1px]
|
|
|
|
|
before:bg-gradient-to-br before:from-black/5 before:via-black/2 before:to-transparent
|
|
|
|
|
before:-z-10 before:blur-sm
|
|
|
|
|
"
|
|
|
|
|
>
|
|
|
|
|
<!-- Text Rendering Container -->
|
|
|
|
|
<div class="relative">
|
|
|
|
|
<div
|
|
|
|
|
bind:this={container}
|
|
|
|
|
role="slider"
|
|
|
|
|
tabindex="0"
|
|
|
|
|
aria-valuenow={Math.round(sliderPos)}
|
|
|
|
|
aria-label="Font comparison slider"
|
|
|
|
|
onpointerdown={startDragging}
|
|
|
|
|
class="
|
|
|
|
|
group relative w-full py-16 px-24 sm:py-24 sm:px-24 overflow-hidden
|
|
|
|
|
rounded-[2.5rem]
|
|
|
|
|
select-none touch-none cursor-ew-resize min-h-100 flex flex-col justify-center
|
|
|
|
|
backdrop-blur-lg bg-gradient-to-br from-gray-100/70 via-white/50 to-gray-100/60
|
|
|
|
|
border border-gray-300/40
|
|
|
|
|
shadow-[inset_0_4px_12px_0_rgba(0,0,0,0.12),inset_0_2px_4px_0_rgba(0,0,0,0.08),0_1px_2px_0_rgba(255,255,255,0.8)]
|
|
|
|
|
before:absolute before:inset-0 before:rounded-[2.5rem] before:p-[1px]
|
|
|
|
|
before:bg-gradient-to-br before:from-black/5 before:via-black/2 before:to-transparent
|
|
|
|
|
before:-z-10 before:blur-sm
|
|
|
|
|
"
|
|
|
|
|
>
|
|
|
|
|
<!-- Text Rendering Container -->
|
|
|
|
|
{#if isLoading}
|
|
|
|
|
<Loader size={24} />
|
|
|
|
|
{:else}
|
|
|
|
|
<div
|
|
|
|
|
class="
|
|
|
|
|
relative flex flex-col items-center gap-4
|
|
|
|
|
@@ -197,6 +203,8 @@ $effect(() => {
|
|
|
|
|
drop-shadow-[0_3px_6px_rgba(255,255,255,0.9)]
|
|
|
|
|
"
|
|
|
|
|
style:perspective="1000px"
|
|
|
|
|
in:fade={{ duration: 300, delay: 300 }}
|
|
|
|
|
out:fade={{ duration: 300 }}
|
|
|
|
|
>
|
|
|
|
|
{#each charComparison.lines as line, lineIndex}
|
|
|
|
|
<div
|
|
|
|
|
@@ -212,8 +220,10 @@ $effect(() => {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SliderLine {sliderPos} {isDragging} />
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{#if fontA && fontB && !isLoading}
|
|
|
|
|
<Labels {fontA} {fontB} {sliderPos} weight={weightControl.value} />
|
|
|
|
|
<!-- Since there're slider controls inside we put them outside the main one -->
|
|
|
|
|
<ControlsWrapper
|
|
|
|
|
@@ -226,5 +236,5 @@ $effect(() => {
|
|
|
|
|
{sizeControl}
|
|
|
|
|
{heightControl}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
|
|
|
|
|