BLOG-58 feat: add Motto and MottoAnimatedMark components, update Terminal and page structure
All checks were successful
Frontend CI / build (push) Successful in 1m29s
All checks were successful
Frontend CI / build (push) Successful in 1m29s
This commit is contained in:
parent
2a7d0f9878
commit
96a0017f94
20
frontend-v2/src/lib/home/framework/ui/Motto.svelte
Normal file
20
frontend-v2/src/lib/home/framework/ui/Motto.svelte
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script>
|
||||||
|
import MottoAnimatedMark from './MottoAnimatedMark.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="mx-auto flex h-screen max-w-screen-xl flex-col items-center justify-center gap-y-2.5 px-4 md:gap-y-8 md:px-6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex w-[19rem] flex-col gap-y-3 text-3xl font-bold text-gray-800 md:w-[38rem] md:gap-y-4 md:text-6xl"
|
||||||
|
>
|
||||||
|
<div class="flex w-full flex-row items-center justify-start gap-x-2.5">
|
||||||
|
<span>Keep</span>
|
||||||
|
<MottoAnimatedMark text="Learning" direction="left" />
|
||||||
|
</div>
|
||||||
|
<div class="flex w-full flex-row items-center justify-end gap-x-2.5 md:gap-x-4">
|
||||||
|
<MottoAnimatedMark text="Keep" direction="right" />
|
||||||
|
<span>Progressing</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,42 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount } from 'svelte';
|
||||||
|
|
||||||
|
const { text, direction }: { text: string; direction: 'left' | 'right' } = $props();
|
||||||
|
|
||||||
|
let isReady: boolean = $state(false);
|
||||||
|
let origin = $derived(direction === 'left' ? 'origin-left' : 'origin-right');
|
||||||
|
|
||||||
|
let element: HTMLSpanElement | null = null;
|
||||||
|
let observer: IntersectionObserver | null = null;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
isReady = true;
|
||||||
|
observer?.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ threshold: 1 }
|
||||||
|
);
|
||||||
|
|
||||||
|
observer.observe(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => observer?.disconnect());
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span
|
||||||
|
bind:this={element}
|
||||||
|
class="rounded-md bg-blue-600 px-1 py-0.5 text-white transition-transform delay-500 duration-1000 md:rounded-lg md:px-2.5 md:py-2 {origin} {isReady
|
||||||
|
? 'scale-x-100'
|
||||||
|
: 'scale-x-0'}"
|
||||||
|
>
|
||||||
|
<span class="scale-x-100">{text}</span>
|
||||||
|
</span>
|
@ -21,7 +21,7 @@
|
|||||||
let observer: IntersectionObserver | null = null;
|
let observer: IntersectionObserver | null = null;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (element == null) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import Motto from '$lib/home/framework/ui/Motto.svelte';
|
||||||
import Terminal from '$lib/home/framework/ui/Terminal.svelte';
|
import Terminal from '$lib/home/framework/ui/Terminal.svelte';
|
||||||
import TitleScreen from '$lib/home/framework/ui/TitleScreen.svelte';
|
import TitleScreen from '$lib/home/framework/ui/TitleScreen.svelte';
|
||||||
</script>
|
</script>
|
||||||
@ -6,4 +7,5 @@
|
|||||||
<div>
|
<div>
|
||||||
<TitleScreen />
|
<TitleScreen />
|
||||||
<Terminal />
|
<Terminal />
|
||||||
|
<Motto />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user