@makefinks/daemon 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/app/App.tsx +3 -0
- package/src/app/components/AvatarLayer.tsx +96 -24
- package/src/app/components/ConversationPane.tsx +3 -2
- package/src/avatar/DaemonAvatarRenderable.ts +26 -3
- package/src/avatar/daemon-avatar-rig.ts +10 -1159
- package/src/avatar/rig/core/rig-engine.ts +202 -0
- package/src/avatar/rig/core/rig-types.ts +17 -0
- package/src/avatar/rig/scene/create-scene-elements.ts +298 -0
- package/src/avatar/rig/state/rig-state.ts +193 -0
- package/src/avatar/rig/theme/rig-theme.ts +31 -0
- package/src/avatar/rig/tools/rig-tools.ts +8 -0
- package/src/avatar/rig/update/update-core.ts +32 -0
- package/src/avatar/rig/update/update-eye.ts +31 -0
- package/src/avatar/rig/update/update-fragments.ts +46 -0
- package/src/avatar/rig/update/update-glitch.ts +64 -0
- package/src/avatar/rig/update/update-idle.ts +95 -0
- package/src/avatar/rig/update/update-intensity.ts +16 -0
- package/src/avatar/rig/update/update-main-anchor.ts +20 -0
- package/src/avatar/rig/update/update-particles.ts +49 -0
- package/src/avatar/rig/update/update-rings.ts +35 -0
- package/src/avatar/rig/update/update-sigils.ts +26 -0
- package/src/avatar/rig/update/update-spawn.ts +83 -0
- package/src/avatar/rig/utils/math.ts +17 -0
- package/src/hooks/use-app-controller.ts +51 -1
- package/src/hooks/use-app-display-state.ts +1 -1
- package/src/hooks/use-glitchy-banner.ts +175 -0
- package/src/ui/startup.ts +5 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { STARTUP_BANNER_DURATION_MS } from "../ui/startup";
|
|
4
|
+
|
|
5
|
+
const DAEMON_BANNER_LINES = [
|
|
6
|
+
"88888888ba, db 88888888888 88b d88 ,ad8888ba, 888b 88",
|
|
7
|
+
'88 `"8b d88b 88 888b d888 d8"\' `"8b 8888b 88',
|
|
8
|
+
"88 `8b d8'`8b 88 88`8b d8'88 d8' `8b 88 `8b 88",
|
|
9
|
+
"88 88 d8' `8b 88aaaaa 88 `8b d8' 88 88 88 88 `8b 88",
|
|
10
|
+
'88 88 d8YaaaaY8b 88""""" 88 `8b d8\' 88 88 88 88 `8b 88',
|
|
11
|
+
'88 8P d8""""""""8b 88 88 `8b d8\' 88 Y8, ,8P 88 `8b 88',
|
|
12
|
+
"88 .a8P d8' `8b 88 88 `888' 88 Y8a. .a8P 88 `8888",
|
|
13
|
+
"88888888Y\"' d8' `8b 88888888888 88 `8' 88 `\"Y8888Y\"' 88 `888",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const BANNER_GRADIENT = [
|
|
17
|
+
"#8a3434",
|
|
18
|
+
"#7a2f2f",
|
|
19
|
+
"#692929",
|
|
20
|
+
"#582323",
|
|
21
|
+
"#481c1c",
|
|
22
|
+
"#371515",
|
|
23
|
+
"#260f0f",
|
|
24
|
+
"#160808",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// glitch chars
|
|
28
|
+
const GLITCH_CHARS = "!@#$%^&*()_+-=[]{}|;:',.<>?/\\`~01";
|
|
29
|
+
|
|
30
|
+
const BANNER_ANIMATION_DURATION = STARTUP_BANNER_DURATION_MS;
|
|
31
|
+
const LINE_STAGGER_MS = 80;
|
|
32
|
+
|
|
33
|
+
export interface GlitchyBannerState {
|
|
34
|
+
lines: string[];
|
|
35
|
+
colors: string[];
|
|
36
|
+
progress: number;
|
|
37
|
+
complete: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generates a glitched version of a string.
|
|
42
|
+
* @param original The original string
|
|
43
|
+
* @param glitchAmount 0-1, where 1 = fully glitched
|
|
44
|
+
* @param revealProgress 0-1, where 1 = fully revealed from left
|
|
45
|
+
*/
|
|
46
|
+
function glitchString(original: string, glitchAmount: number, revealProgress: number): string {
|
|
47
|
+
const revealedLength = Math.floor(original.length * revealProgress);
|
|
48
|
+
let result = "";
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < original.length; i++) {
|
|
51
|
+
const char = original[i];
|
|
52
|
+
|
|
53
|
+
if (i >= revealedLength) {
|
|
54
|
+
// Not yet revealed - either empty or glitch
|
|
55
|
+
if (Math.random() < glitchAmount * 0.7) {
|
|
56
|
+
result += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];
|
|
57
|
+
} else {
|
|
58
|
+
result += " ";
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
// Revealed area - occasional glitch corruption
|
|
62
|
+
if (char !== " " && Math.random() < glitchAmount * 0.15) {
|
|
63
|
+
result += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];
|
|
64
|
+
} else {
|
|
65
|
+
result += char;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Generates glitched color - subtle brightness/saturation shifts within red spectrum
|
|
75
|
+
*/
|
|
76
|
+
function glitchColor(baseColor: string, glitchAmount: number): string {
|
|
77
|
+
if (glitchAmount > 0.2 && Math.random() < glitchAmount * 0.4) {
|
|
78
|
+
const hex = baseColor.replace("#", "");
|
|
79
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
80
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
81
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
82
|
+
|
|
83
|
+
// Subtle variation: shift brightness and add slight color temperature changes
|
|
84
|
+
const brightnessShift = (Math.random() - 0.3) * glitchAmount * 80;
|
|
85
|
+
const newR = Math.max(0, Math.min(255, r + brightnessShift + Math.random() * 30));
|
|
86
|
+
const newG = Math.max(0, Math.min(255, g + brightnessShift * 0.3));
|
|
87
|
+
const newB = Math.max(0, Math.min(255, b + brightnessShift * 0.2));
|
|
88
|
+
|
|
89
|
+
return `#${Math.round(newR).toString(16).padStart(2, "0")}${Math.round(newG).toString(16).padStart(2, "0")}${Math.round(newB).toString(16).padStart(2, "0")}`;
|
|
90
|
+
}
|
|
91
|
+
return baseColor;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function useGlitchyBanner(isActive: boolean): GlitchyBannerState {
|
|
95
|
+
const [state, setState] = useState<GlitchyBannerState>({
|
|
96
|
+
lines: DAEMON_BANNER_LINES.map(() => ""),
|
|
97
|
+
colors: BANNER_GRADIENT.map(() => "#000000"),
|
|
98
|
+
progress: 0,
|
|
99
|
+
complete: false,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Animation loop
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (!isActive) {
|
|
105
|
+
setState({
|
|
106
|
+
lines: DAEMON_BANNER_LINES.map(() => ""),
|
|
107
|
+
colors: BANNER_GRADIENT.map(() => "#000000"),
|
|
108
|
+
progress: 0,
|
|
109
|
+
complete: false,
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const startTime = performance.now();
|
|
115
|
+
const animate = () => {
|
|
116
|
+
const elapsed = performance.now() - startTime;
|
|
117
|
+
const progress = Math.min(1, elapsed / BANNER_ANIMATION_DURATION);
|
|
118
|
+
|
|
119
|
+
if (progress >= 1) {
|
|
120
|
+
// Animation complete, show final state
|
|
121
|
+
setState({
|
|
122
|
+
lines: [...DAEMON_BANNER_LINES],
|
|
123
|
+
colors: [...BANNER_GRADIENT],
|
|
124
|
+
progress: 1,
|
|
125
|
+
complete: true,
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Calculate glitch intensity (high at start, fades out)
|
|
131
|
+
const glitchIntensity = Math.pow(1 - progress, 2);
|
|
132
|
+
|
|
133
|
+
// Generate glitched lines with staggered reveal
|
|
134
|
+
const lines = DAEMON_BANNER_LINES.map((line, i) => {
|
|
135
|
+
const lineStartTime = i * LINE_STAGGER_MS;
|
|
136
|
+
const lineElapsed = Math.max(0, elapsed - lineStartTime);
|
|
137
|
+
const lineProgress = Math.min(1, lineElapsed / (BANNER_ANIMATION_DURATION - i * LINE_STAGGER_MS));
|
|
138
|
+
|
|
139
|
+
// Reveal from left + glitch effect
|
|
140
|
+
const revealProgress = Math.pow(lineProgress, 0.7); // Ease out
|
|
141
|
+
return glitchString(line, glitchIntensity, revealProgress);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Generate colors with occasional glitch flash
|
|
145
|
+
const colors = BANNER_GRADIENT.map((color, i) => {
|
|
146
|
+
const lineStartTime = i * LINE_STAGGER_MS;
|
|
147
|
+
const lineElapsed = Math.max(0, elapsed - lineStartTime);
|
|
148
|
+
const lineProgress = Math.min(1, lineElapsed / (BANNER_ANIMATION_DURATION - i * LINE_STAGGER_MS));
|
|
149
|
+
|
|
150
|
+
if (lineProgress < 0.1) {
|
|
151
|
+
return "#000000";
|
|
152
|
+
}
|
|
153
|
+
return glitchColor(color, glitchIntensity);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
setState({
|
|
157
|
+
lines,
|
|
158
|
+
colors,
|
|
159
|
+
progress,
|
|
160
|
+
complete: false,
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Run at ~30fps for glitchy effect
|
|
165
|
+
const intervalId = setInterval(animate, 33);
|
|
166
|
+
// Run once immediately
|
|
167
|
+
animate();
|
|
168
|
+
|
|
169
|
+
return () => clearInterval(intervalId);
|
|
170
|
+
}, [isActive]);
|
|
171
|
+
|
|
172
|
+
return state;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export { DAEMON_BANNER_LINES, BANNER_GRADIENT };
|