Skip to content

Commit 907546b

Browse files
committed
Terminal transitions are smooth and snappy!
1 parent b770eb7 commit 907546b

8 files changed

Lines changed: 140 additions & 66 deletions

File tree

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { onMount } from "svelte";
2+
import BlinkingCursor from "$lib/components/ui/BlinkingCursor.svelte";
33
import { finishBooting } from "$lib/stores/terminalStore";
44
55
const lines = [
@@ -11,26 +11,25 @@
1111
"ACCESS GRANTED.",
1212
"Welcome, Guest.",
1313
];
14-
15-
let displayedLines: string[] = [];
16-
17-
onMount(() => {
18-
let i = 0;
19-
const interval = setInterval(() => {
20-
if (i < lines.length) {
21-
displayedLines = [...displayedLines, lines[i]];
22-
i++;
23-
} else {
24-
clearInterval(interval);
25-
setTimeout(finishBooting, 500); // Wait a moment before switching view
26-
}
27-
}, 300); // Speed of the boot sequence
28-
});
2914
</script>
3015

3116
<div>
32-
{#each displayedLines as line}
33-
<p>> {line}</p>
17+
{#each lines as line, i}
18+
{#if i === lines.length - 1}
19+
<p
20+
on:animationend={finishBooting}
21+
class="opacity-0 animate-fade animate-duration-[1]"
22+
style="animation-delay: {i * 0.3}s">
23+
&gt; {line}
24+
</p>
25+
{:else}
26+
<p
27+
class="opacity-0 animate-fade animate-duration-[0.1]"
28+
style="animation-delay: {i * 0.3}s">
29+
&gt; {line}
30+
</p>
31+
{/if}
3432
{/each}
35-
<span class="blinking-cursor h-5 w-2 bg-ctp-green inline-block"></span>
33+
34+
<BlinkingCursor />
3635
</div>

src/lib/components/features/terminal/FileExplorer.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import ProjectFile from "./ProjectFile.svelte";
44
import { viewProject } from "$lib/stores/terminalStore";
55
import BlinkingCursor from "../../ui/BlinkingCursor.svelte";
6+
import { fade } from "svelte/transition";
67
export let projects: Project[];
78
</script>
89

9-
<div>
10+
<div in:fade>
1011
<p>> ls -l</p>
1112
<div class="my-4 flex flex-col gap-1">
1213
{#each projects as project, index ((project.id, index))}

src/lib/components/features/terminal/ProjectFile.svelte

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
export let project: Project;
44
</script>
55

6-
<div class="grid grid-cols-[1fr_max-content] gap-4">
6+
<div class="flex flex-col sm:grid sm:grid-cols-[1fr_max-content] sm:gap-x-4">
7+
<!-- Filename and permissions -->
78
<p class="text-ctp-blue whitespace-nowrap overflow-hidden text-ellipsis">
8-
-rwx--r--r-- {project.title}.{project.extension}
9+
<span class="hidden sm:inline">-rwx--r--r-- </span>
10+
{project.title}.{project.extension}
11+
</p>
12+
13+
<p class="text-ctp-subtext1 text-right sm:text-left">
14+
{project.date}
915
</p>
10-
<p class="text-ctp-subtext1">{project.date}</p>
1116
</div>

src/lib/components/features/terminal/ProjectView.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
<script lang="ts">
22
import type { Project } from "$lib/data/projects";
33
import { closeProject } from "$lib/stores/terminalStore";
4+
import { crtShutdown } from "$lib/transitions/crtShutdown";
5+
import { fade } from "svelte/transition";
46
import GlitchText from "../../ui/GlitchText.svelte";
57
export let project: Project;
68
</script>
79

8-
<div class="project-view flex flex-col h-full max-h-full min-h-0">
10+
<div
11+
in:fade
12+
out:crtShutdown
13+
class="project-view flex flex-col h-full max-h-full min-h-0">
914
<header class="mb-4 pb-2 flex-shrink-0">
1015
<p>> cat {project.title}.{project.extension}</p>
1116
<div class="ascii-hr mt-2"></div>

src/lib/components/features/terminal/Terminal.svelte

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,37 @@
2828

2929
<div
3030
bind:this={terminalElement}
31-
class="font-mono bg-ctp-crust text-ctp-green h-[60vh] ascii-border">
31+
class="
32+
relative
33+
w-full
34+
h-[60vh]
35+
overflow-y-auto
36+
overflow-x-hidden
37+
font-mono
38+
text-sm
39+
sm:text-base
40+
leading-relaxed
41+
bg-ctp-crust
42+
text-ctp-green
43+
p-4
44+
rounded
45+
ascii-border
46+
">
3247
{#if $terminalStore.state === "waiting"}
33-
<p>> STANDBY_</p>
48+
<div class="absolute inset-0 p-4">
49+
<p>> STANDBY_</p>
50+
</div>
3451
{:else if $terminalStore.state === "booting"}
35-
<BootSequence />
52+
<div class="absolute inset-0 p-4">
53+
<BootSequence />
54+
</div>
3655
{:else if $terminalStore.state === "listing_files"}
37-
<FileExplorer {projects} />
56+
<div class="absolute inset-0 p-4">
57+
<FileExplorer {projects} />
58+
</div>
3859
{:else if $terminalStore.state === "viewing_project" && $terminalStore.activeProject}
39-
<ProjectView project={$terminalStore.activeProject} />
60+
<div class="absolute inset-0 p-4">
61+
<ProjectView project={$terminalStore.activeProject} />
62+
</div>
4063
{/if}
4164
</div>

src/lib/components/features/terminal/TerminalReveal.svelte

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/lib/components/ui/GlitchText.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
sky: "text-ctp-sky",
3434
red: "text-ctp-red",
3535
};
36-
36+
// TODO: LANGUAGE DOESNT CHANGE UNLESS YOU RE-HOVER IT
3737
$: finalClasses = `font-mono font-bold ${sizeClasses[size] || sizeClasses["3xl"]} ${colorClasses[color] || colorClasses["mauve"]} cursor-pointer focus:outline-none`;
3838
3939
// --- Scramble Animation Logic ---

src/lib/transitions/crtShutdown.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { quintIn, quintOut, quintInOut } from "svelte/easing";
2+
import type { TransitionConfig } from "svelte/transition";
3+
4+
export function crtShutdown(
5+
_: Element,
6+
{ delay = 0, duration = 550 } = {},
7+
): TransitionConfig {
8+
return {
9+
delay,
10+
duration,
11+
easing: quintOut,
12+
css: (t: number) => {
13+
// Invert t since this is outro (t:0->1 intro, want progress 1->0)
14+
const progress = 1 - t;
15+
16+
// Vertical jitter for old CRT wobble effect
17+
const jitter = 2 * Math.sin(progress * 50);
18+
19+
let scaleX: number, scaleY: number;
20+
let brightness: number, contrast: number, saturate: number;
21+
let glowOpacity: number;
22+
let opacity = 1;
23+
24+
if (progress <= 0.6) {
25+
// First 60% of the animation
26+
const localT = progress / 0.6;
27+
28+
// Eased scaling
29+
scaleX = 1 + 0.3 * quintInOut(localT);
30+
scaleY = 1.3 - 1.299 * quintInOut(localT);
31+
32+
// Filters for bright white flash glow
33+
brightness = 1 + 9 * localT;
34+
contrast = 1 + 10 * localT;
35+
saturate = 1 + 30 * localT;
36+
37+
// Pulsing glow opacity (2 full pulses)
38+
glowOpacity = 0.8 * Math.sin(progress * Math.PI * 4) ** 2;
39+
} else {
40+
// Last 40% of animation with easing
41+
const localT = (progress - 0.6) / 0.4;
42+
const easedT = quintIn(localT);
43+
44+
scaleX = 1.3 - 1.3 * easedT;
45+
scaleY = 0.001 - 0.0009 * easedT;
46+
47+
brightness = 10 + 40 * easedT;
48+
contrast = 11 + 39 * easedT;
49+
saturate = 31 + 69 * easedT;
50+
51+
glowOpacity = 0.8 * Math.sin(progress * Math.PI * 4) ** 2;
52+
}
53+
54+
// Flickering opacity in last 10% of shutdown, smoothed out to avoid flicker at very end
55+
if (progress < 0.1) {
56+
opacity = 0.7 + 0.3 * Math.random();
57+
}
58+
59+
// Chromatic aberration effect with subtle colored drop shadows, softer with blur
60+
const chroma = `
61+
drop-shadow(1.5px 0 rgba(255, 0, 0, 0.5))
62+
drop-shadow(-1.5px 0 rgba(0, 255, 255, 0.5))
63+
drop-shadow(0 1.5px rgba(0, 0, 255, 0.3))
64+
`;
65+
66+
// Soften the white glow box-shadow: less spread, more blur, less opacity
67+
const softGlow = `inset 0 0 50px 30px rgba(255,255,255,${glowOpacity.toFixed(2)})`;
68+
69+
return `
70+
transform: scale(${scaleX.toFixed(3)}, ${scaleY.toFixed(3)}) translate3d(0, ${jitter.toFixed(2)}px, 0);
71+
filter: brightness(${brightness.toFixed(2)}) contrast(${contrast.toFixed(2)}) saturate(${saturate.toFixed(2)}) ${chroma};
72+
box-shadow: ${softGlow};
73+
opacity: ${opacity.toFixed(2)};
74+
`;
75+
},
76+
};
77+
}

0 commit comments

Comments
 (0)