@5even7/dlc-ui 0.2.18 → 0.2.20
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/CHANGELOG.md +158 -144
- package/EXTENDING.md +114 -0
- package/LICENSE +21 -21
- package/README.md +389 -338
- package/THIRD_PARTY_NOTICES.md +221 -0
- package/dist/avatar-creator/styles/humation.mjs +26 -0
- package/dist/avatar-creator/styles.mjs +76 -0
- package/dist/avatar-creator.cjs +7831 -0
- package/dist/avatar-creator.mjs +74 -0
- package/dist/capsule.cjs +185 -66
- package/dist/capsule.mjs +364 -1340
- package/dist/chunks/avatar-creator-DiAmhpRa.mjs +687 -0
- package/dist/chunks/color-DnmNceaf.mjs +350 -0
- package/dist/chunks/controls-B5_ctvvA.mjs +160 -0
- package/dist/chunks/copy-7J0XIj_0.mjs +13 -0
- package/dist/chunks/cosmic-fallback-v8G5_ibh.mjs +408 -0
- package/dist/chunks/emitter-CxLYMSbw.mjs +38 -0
- package/dist/chunks/emo-Dvahy5Qr.mjs +1140 -0
- package/dist/chunks/hash-BiO02UNb.mjs +38 -0
- package/dist/chunks/humation-B9OPUGL7.mjs +2987 -0
- package/dist/chunks/identicon-BUdMd-yf.mjs +3063 -0
- package/dist/chunks/index-BchW1tWE.mjs +478 -0
- package/dist/chunks/index-BtH8Lbra.mjs +296 -0
- package/dist/chunks/index-C02dvGLD.mjs +263 -0
- package/dist/chunks/index-CFybYBA1.mjs +278 -0
- package/dist/chunks/index-DgI872-7.mjs +241 -0
- package/dist/chunks/index-_sf_14Zu.mjs +455 -0
- package/dist/chunks/index-w5Pzdwhv.mjs +305 -0
- package/dist/chunks/motion-a8_f8_Ui.mjs +177 -0
- package/dist/chunks/number-BqWLX0iQ.mjs +231 -0
- package/dist/chunks/progress-KweS4Rx0.mjs +1836 -0
- package/dist/chunks/size-Bztk2ryJ.mjs +22 -0
- package/dist/chunks/wrapper-DXhy1E7Z.mjs +514 -0
- package/dist/color.cjs +186 -67
- package/dist/color.mjs +341 -1280
- package/dist/emo/miao/angry.mjs +4 -0
- package/dist/emo/miao/asleep.mjs +4 -0
- package/dist/emo/miao/badminton.mjs +4 -0
- package/dist/emo/miao/confident.mjs +4 -0
- package/dist/emo/miao/cry.mjs +4 -0
- package/dist/emo/miao/investigate.mjs +4 -0
- package/dist/emo/miao/laugh.mjs +4 -0
- package/dist/emo/miao/leisure.mjs +4 -0
- package/dist/emo/miao/mock.mjs +4 -0
- package/dist/emo/miao/music.mjs +4 -0
- package/dist/emo/miao/mute.mjs +4 -0
- package/dist/emo/miao/panic.mjs +4 -0
- package/dist/emo/miao/ponder.mjs +4 -0
- package/dist/emo/miao/question.mjs +4 -0
- package/dist/emo/miao/sad.mjs +4 -0
- package/dist/emo/miao/shocked.mjs +4 -0
- package/dist/emo/miao/shy.mjs +4 -0
- package/dist/emo/miao/sigh.mjs +4 -0
- package/dist/emo/miao/smile.mjs +4 -0
- package/dist/emo/miao/snigger.mjs +4 -0
- package/dist/emo/miao/static.mjs +4 -0
- package/dist/emo/miao/yawn.mjs +4 -0
- package/dist/emo/miao/yummy.mjs +4 -0
- package/dist/emo.cjs +27161 -25964
- package/dist/emo.mjs +8 -1421
- package/dist/index.cjs +32729 -24466
- package/dist/index.mjs +16 -4757
- package/dist/index.umd.js +33115 -24852
- package/dist/index.umd.min.js +3 -1
- package/dist/progress.cjs +195 -76
- package/dist/progress.mjs +7 -2448
- package/dist/vue2.cjs +33282 -25002
- package/dist/vue2.mjs +63 -5131
- package/dist/vue3.cjs +33282 -25002
- package/dist/vue3.mjs +53 -5122
- package/package.json +161 -136
- package/styles/avatar-creator.css +38 -0
- package/styles/base.css +32 -32
- package/styles/color.css +18 -18
- package/styles/emo.css +110 -89
- package/styles/progress.css +96 -96
- package/styles/theme.css +1 -0
- package/types/avatar-creator-styles.d.ts +10 -0
- package/types/avatar-creator.d.ts +143 -0
- package/types/capsule.d.ts +15 -15
- package/types/color.d.ts +15 -15
- package/types/emo-miao.d.ts +9 -0
- package/types/emo.d.ts +38 -37
- package/types/index.d.ts +593 -554
- package/types/progress.d.ts +16 -16
- package/types/vue2.d.ts +11 -10
- package/types/vue3.d.ts +169 -146
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { h as hexToRgb01 } from './color-DnmNceaf.mjs';
|
|
2
|
+
|
|
3
|
+
const VERTEX_SHADER = `#version 300 es
|
|
4
|
+
in vec2 a_position;
|
|
5
|
+
out vec2 v_uv;
|
|
6
|
+
void main() {
|
|
7
|
+
v_uv = a_position * 0.5 + 0.5;
|
|
8
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
9
|
+
}`;
|
|
10
|
+
|
|
11
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
12
|
+
precision highp float;
|
|
13
|
+
|
|
14
|
+
in vec2 v_uv;
|
|
15
|
+
out vec4 outColor;
|
|
16
|
+
|
|
17
|
+
uniform vec2 u_resolution;
|
|
18
|
+
uniform float u_time;
|
|
19
|
+
uniform float u_seed;
|
|
20
|
+
uniform float u_motion;
|
|
21
|
+
uniform vec2 u_pointer;
|
|
22
|
+
uniform vec3 u_colorA;
|
|
23
|
+
uniform vec3 u_colorB;
|
|
24
|
+
uniform vec3 u_colorC;
|
|
25
|
+
uniform vec3 u_colorD;
|
|
26
|
+
|
|
27
|
+
float hash21(vec2 p) {
|
|
28
|
+
p = fract(p * vec2(123.34, 456.21));
|
|
29
|
+
p += dot(p, p + 45.32 + u_seed);
|
|
30
|
+
return fract(p.x * p.y);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
float noise(vec2 p) {
|
|
34
|
+
vec2 i = floor(p);
|
|
35
|
+
vec2 f = fract(p);
|
|
36
|
+
f = f * f * (3.0 - 2.0 * f);
|
|
37
|
+
float a = hash21(i);
|
|
38
|
+
float b = hash21(i + vec2(1.0, 0.0));
|
|
39
|
+
float c = hash21(i + vec2(0.0, 1.0));
|
|
40
|
+
float d = hash21(i + vec2(1.0, 1.0));
|
|
41
|
+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
float fbm(vec2 p) {
|
|
45
|
+
float value = 0.0;
|
|
46
|
+
float amplitude = 0.52;
|
|
47
|
+
mat2 rotation = mat2(0.80, 0.60, -0.60, 0.80);
|
|
48
|
+
for (int i = 0; i < 6; i++) {
|
|
49
|
+
value += amplitude * noise(p);
|
|
50
|
+
p = rotation * p * 2.03 + 17.7;
|
|
51
|
+
amplitude *= 0.5;
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
float gaussian(float value, float center, float width) {
|
|
57
|
+
return exp(-pow(value - center, 2.0) / max(width, 0.0001));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
vec3 palette(float t) {
|
|
61
|
+
t = clamp(t, 0.0, 1.0);
|
|
62
|
+
vec3 shadow = mix(u_colorA, u_colorB, smoothstep(0.06, 0.62, t));
|
|
63
|
+
vec3 body = mix(u_colorB, u_colorC, smoothstep(0.30, 0.82, t));
|
|
64
|
+
vec3 highlight = mix(u_colorC, u_colorD, smoothstep(0.74, 1.0, t));
|
|
65
|
+
vec3 restrained = mix(shadow, body, smoothstep(0.26, 0.72, t));
|
|
66
|
+
return mix(restrained, highlight, smoothstep(0.78, 0.97, t));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
vec3 renderNebula(vec2 uv, vec2 p, vec2 pointer, float distanceToPointer, float t) {
|
|
70
|
+
vec2 delta = p - pointer;
|
|
71
|
+
float influence = exp(-distanceToPointer * 4.6) * u_motion;
|
|
72
|
+
float angle = influence * 1.7;
|
|
73
|
+
mat2 swirl = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
|
|
74
|
+
p = pointer + swirl * delta;
|
|
75
|
+
p += normalize(delta + 0.0001) * influence * 0.08;
|
|
76
|
+
|
|
77
|
+
vec2 drift = vec2(t * 0.22, -t * 0.13);
|
|
78
|
+
vec2 q = vec2(
|
|
79
|
+
fbm(p * 1.35 + drift + u_seed),
|
|
80
|
+
fbm(p * 1.35 + vec2(5.2, 1.3) - drift * 0.85)
|
|
81
|
+
);
|
|
82
|
+
vec2 r = vec2(
|
|
83
|
+
fbm(p * 2.0 + 3.6 * q + vec2(1.7, 9.2) + t * 0.10),
|
|
84
|
+
fbm(p * 2.0 + 3.0 * q + vec2(8.3, 2.8) - t * 0.085)
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
float cloud = fbm(p * 1.7 + 4.2 * r);
|
|
88
|
+
float veins = fbm(p * 4.0 - 2.0 * q + t * 0.065);
|
|
89
|
+
float nebula = smoothstep(0.18, 0.91, cloud * 0.9 + veins * 0.22);
|
|
90
|
+
|
|
91
|
+
vec3 color = palette(nebula);
|
|
92
|
+
color += u_colorD * pow(max(cloud - 0.63, 0.0), 2.0) * 1.05;
|
|
93
|
+
color *= 0.78 + 0.34 * smoothstep(0.15, 0.9, veins);
|
|
94
|
+
|
|
95
|
+
vec2 starGrid = floor((uv + vec2(u_seed * 0.013, 0.0)) * vec2(132.0, 58.0));
|
|
96
|
+
vec2 starCell = fract(uv * vec2(132.0, 58.0)) - 0.5;
|
|
97
|
+
float starRandom = hash21(starGrid);
|
|
98
|
+
float starShape = smoothstep(0.075, 0.0, length(starCell));
|
|
99
|
+
float starMask = step(0.989, starRandom) * starShape;
|
|
100
|
+
float twinkle = 0.35 + 0.65 * sin(t * (1.0 + starRandom * 2.4) + starRandom * 40.0) * 0.5 + 0.5;
|
|
101
|
+
color += starMask * twinkle * mix(u_colorC, u_colorD, starRandom) * 1.05;
|
|
102
|
+
|
|
103
|
+
float pointerGlow = exp(-distanceToPointer * 7.0) * u_motion;
|
|
104
|
+
color += u_colorD * pointerGlow * 0.28;
|
|
105
|
+
return color;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void main() {
|
|
109
|
+
vec2 uv = v_uv;
|
|
110
|
+
vec2 p = uv - 0.5;
|
|
111
|
+
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
|
|
112
|
+
|
|
113
|
+
vec2 pointer = u_pointer - 0.5;
|
|
114
|
+
pointer.x *= u_resolution.x / max(u_resolution.y, 1.0);
|
|
115
|
+
float distanceToPointer = length(p - pointer);
|
|
116
|
+
|
|
117
|
+
vec3 color = renderNebula(uv, p, pointer, distanceToPointer, u_time);
|
|
118
|
+
float vignette = smoothstep(0.94, 0.18, length((uv - 0.5) * vec2(1.0, 1.35)));
|
|
119
|
+
color *= 0.70 + vignette * 0.42;
|
|
120
|
+
color = pow(max(color, vec3(0.0)), vec3(0.88));
|
|
121
|
+
|
|
122
|
+
outColor = vec4(color, 1.0);
|
|
123
|
+
}`;
|
|
124
|
+
|
|
125
|
+
function compileShader(gl, type, source) {
|
|
126
|
+
const shader = gl.createShader(type);
|
|
127
|
+
gl.shaderSource(shader, source);
|
|
128
|
+
gl.compileShader(shader);
|
|
129
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
130
|
+
const message = gl.getShaderInfoLog(shader) || 'Unknown shader compile error';
|
|
131
|
+
gl.deleteShader(shader);
|
|
132
|
+
throw new Error(message);
|
|
133
|
+
}
|
|
134
|
+
return shader;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function createProgram(gl) {
|
|
138
|
+
const vertex = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
|
|
139
|
+
const fragment = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
|
|
140
|
+
const program = gl.createProgram();
|
|
141
|
+
gl.attachShader(program, vertex);
|
|
142
|
+
gl.attachShader(program, fragment);
|
|
143
|
+
gl.linkProgram(program);
|
|
144
|
+
gl.deleteShader(vertex);
|
|
145
|
+
gl.deleteShader(fragment);
|
|
146
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
147
|
+
const message = gl.getProgramInfoLog(program) || 'Unknown program link error';
|
|
148
|
+
gl.deleteProgram(program);
|
|
149
|
+
throw new Error(message);
|
|
150
|
+
}
|
|
151
|
+
return program;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
class CosmicRenderer {
|
|
155
|
+
constructor(canvas, preset, options = {}) {
|
|
156
|
+
this.canvas = canvas;
|
|
157
|
+
this.preset = { ...preset };
|
|
158
|
+
this.options = { dprCap: 1.75, mouseColor: true, ...options };
|
|
159
|
+
this.gl = canvas.getContext('webgl2', {
|
|
160
|
+
alpha: false,
|
|
161
|
+
antialias: false,
|
|
162
|
+
depth: false,
|
|
163
|
+
powerPreference: this.options.powerPreference || 'high-performance',
|
|
164
|
+
preserveDrawingBuffer: false
|
|
165
|
+
});
|
|
166
|
+
if (!this.gl) throw new Error('WebGL2 is not available');
|
|
167
|
+
|
|
168
|
+
this.program = createProgram(this.gl);
|
|
169
|
+
this.locations = this.#getLocations();
|
|
170
|
+
this.pointer = [0.72, 0.45];
|
|
171
|
+
this.pointerTarget = [...this.pointer];
|
|
172
|
+
this.motion = 0;
|
|
173
|
+
this.motionTarget = 0;
|
|
174
|
+
this.timeOffset = preset.seed * 0.73;
|
|
175
|
+
this.colors = preset.colors.map(hexToRgb01);
|
|
176
|
+
this.visible = true;
|
|
177
|
+
this.disposed = false;
|
|
178
|
+
|
|
179
|
+
this.#setupGeometry();
|
|
180
|
+
this.#bindEvents();
|
|
181
|
+
this.#bindContextEvents();
|
|
182
|
+
this.resize();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
#getLocations() {
|
|
186
|
+
const gl = this.gl;
|
|
187
|
+
const uniform = (name) => gl.getUniformLocation(this.program, name);
|
|
188
|
+
return {
|
|
189
|
+
position: gl.getAttribLocation(this.program, 'a_position'),
|
|
190
|
+
resolution: uniform('u_resolution'),
|
|
191
|
+
time: uniform('u_time'),
|
|
192
|
+
seed: uniform('u_seed'),
|
|
193
|
+
motion: uniform('u_motion'),
|
|
194
|
+
pointer: uniform('u_pointer'),
|
|
195
|
+
colorA: uniform('u_colorA'),
|
|
196
|
+
colorB: uniform('u_colorB'),
|
|
197
|
+
colorC: uniform('u_colorC'),
|
|
198
|
+
colorD: uniform('u_colorD')
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#setupGeometry() {
|
|
203
|
+
const gl = this.gl;
|
|
204
|
+
const vertices = new Float32Array([-1, -1, 3, -1, -1, 3]);
|
|
205
|
+
this.buffer = gl.createBuffer();
|
|
206
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
207
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
#bindEvents() {
|
|
211
|
+
if (this.options.mouseColor === false) return;
|
|
212
|
+
this.eventTarget = this.options.eventTarget || this.canvas.parentElement || this.canvas;
|
|
213
|
+
this.onPointerMove = (event) => {
|
|
214
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
215
|
+
this.pointerTarget[0] = (event.clientX - rect.left) / Math.max(rect.width, 1);
|
|
216
|
+
this.pointerTarget[1] = 1 - (event.clientY - rect.top) / Math.max(rect.height, 1);
|
|
217
|
+
this.motionTarget = 1;
|
|
218
|
+
};
|
|
219
|
+
this.onPointerLeave = () => { this.motionTarget = 0; };
|
|
220
|
+
this.eventTarget.addEventListener('pointermove', this.onPointerMove, { passive: true });
|
|
221
|
+
this.eventTarget.addEventListener('pointerdown', this.onPointerMove, { passive: true });
|
|
222
|
+
this.eventTarget.addEventListener('pointerleave', this.onPointerLeave, { passive: true });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#bindContextEvents() {
|
|
226
|
+
this.onContextLost = (event) => {
|
|
227
|
+
event.preventDefault();
|
|
228
|
+
if (this.disposed) return;
|
|
229
|
+
this.visible = false;
|
|
230
|
+
if (typeof this.options.onContextLost === 'function') this.options.onContextLost(event);
|
|
231
|
+
};
|
|
232
|
+
this.onContextRestored = () => {
|
|
233
|
+
if (this.disposed) return;
|
|
234
|
+
this.program = createProgram(this.gl);
|
|
235
|
+
this.locations = this.#getLocations();
|
|
236
|
+
this.#setupGeometry();
|
|
237
|
+
this.visible = true;
|
|
238
|
+
this.resize();
|
|
239
|
+
if (typeof this.options.onContextRestored === 'function') this.options.onContextRestored();
|
|
240
|
+
};
|
|
241
|
+
this.canvas.addEventListener('webglcontextlost', this.onContextLost, false);
|
|
242
|
+
this.canvas.addEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
setPreset(preset) {
|
|
246
|
+
this.preset = { ...preset };
|
|
247
|
+
this.colors = preset.colors.map(hexToRgb01);
|
|
248
|
+
this.timeOffset = preset.seed * 0.73;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
setDprCap(cap) {
|
|
252
|
+
this.options.dprCap = cap;
|
|
253
|
+
this.resize();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
setMouseColor(enabled) {
|
|
257
|
+
this.options.mouseColor = enabled !== false;
|
|
258
|
+
if (this.options.mouseColor) {
|
|
259
|
+
if (this.onPointerMove) return this;
|
|
260
|
+
this.#bindEvents();
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
if (this.onPointerMove) {
|
|
264
|
+
const target = this.eventTarget;
|
|
265
|
+
target.removeEventListener('pointermove', this.onPointerMove);
|
|
266
|
+
target.removeEventListener('pointerdown', this.onPointerMove);
|
|
267
|
+
target.removeEventListener('pointerleave', this.onPointerLeave);
|
|
268
|
+
this.onPointerMove = null;
|
|
269
|
+
this.onPointerLeave = null;
|
|
270
|
+
}
|
|
271
|
+
this.motionTarget = 0;
|
|
272
|
+
return this;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
randomize() {
|
|
276
|
+
this.preset.seed = Math.random() * 100;
|
|
277
|
+
this.timeOffset = Math.random() * 40;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
resize() {
|
|
281
|
+
const dpr = Math.min(window.devicePixelRatio || 1, this.options.dprCap);
|
|
282
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
283
|
+
const width = Math.max(2, Math.round(rect.width * dpr));
|
|
284
|
+
const height = Math.max(2, Math.round(rect.height * dpr));
|
|
285
|
+
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
286
|
+
this.canvas.width = width;
|
|
287
|
+
this.canvas.height = height;
|
|
288
|
+
}
|
|
289
|
+
this.gl.viewport(0, 0, width, height);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
draw(elapsedSeconds, paused = false) {
|
|
293
|
+
if (this.disposed || !this.visible) return;
|
|
294
|
+
const gl = this.gl;
|
|
295
|
+
this.pointer[0] += (this.pointerTarget[0] - this.pointer[0]) * 0.08;
|
|
296
|
+
this.pointer[1] += (this.pointerTarget[1] - this.pointer[1]) * 0.08;
|
|
297
|
+
this.motion += (this.motionTarget - this.motion) * 0.07;
|
|
298
|
+
|
|
299
|
+
gl.useProgram(this.program);
|
|
300
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
301
|
+
gl.enableVertexAttribArray(this.locations.position);
|
|
302
|
+
gl.vertexAttribPointer(this.locations.position, 2, gl.FLOAT, false, 0, 0);
|
|
303
|
+
|
|
304
|
+
gl.uniform2f(this.locations.resolution, this.canvas.width, this.canvas.height);
|
|
305
|
+
gl.uniform1f(this.locations.time, this.timeOffset + (paused ? 0 : elapsedSeconds * this.preset.speed));
|
|
306
|
+
gl.uniform1f(this.locations.seed, this.preset.seed);
|
|
307
|
+
gl.uniform1f(this.locations.motion, this.motion);
|
|
308
|
+
gl.uniform2f(this.locations.pointer, this.pointer[0], this.pointer[1]);
|
|
309
|
+
gl.uniform3fv(this.locations.colorA, this.colors[0]);
|
|
310
|
+
gl.uniform3fv(this.locations.colorB, this.colors[1]);
|
|
311
|
+
gl.uniform3fv(this.locations.colorC, this.colors[2]);
|
|
312
|
+
gl.uniform3fv(this.locations.colorD, this.colors[3]);
|
|
313
|
+
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
dispose() {
|
|
317
|
+
this.disposed = true;
|
|
318
|
+
const target = this.eventTarget || this.canvas;
|
|
319
|
+
target.removeEventListener('pointermove', this.onPointerMove);
|
|
320
|
+
target.removeEventListener('pointerdown', this.onPointerMove);
|
|
321
|
+
target.removeEventListener('pointerleave', this.onPointerLeave);
|
|
322
|
+
this.canvas.removeEventListener('webglcontextlost', this.onContextLost, false);
|
|
323
|
+
this.canvas.removeEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
324
|
+
this.gl.deleteBuffer(this.buffer);
|
|
325
|
+
this.gl.deleteProgram(this.program);
|
|
326
|
+
const lose = this.gl.getExtension('WEBGL_lose_context');
|
|
327
|
+
if (lose) lose.loseContext();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function rgb(color, alpha = 1) {
|
|
332
|
+
const [r, g, b] = hexToRgb01(color).map((value) => Math.round(value * 255));
|
|
333
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
class FallbackRenderer {
|
|
337
|
+
constructor(canvas, preset, options = {}) {
|
|
338
|
+
this.canvas = canvas;
|
|
339
|
+
this.preset = preset;
|
|
340
|
+
this.context = canvas.getContext('2d');
|
|
341
|
+
this.visible = true;
|
|
342
|
+
this.timePhase = 0;
|
|
343
|
+
this.dprCap = options.dprCap || 1.5;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
resize() {
|
|
347
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
348
|
+
const dpr = Math.min(window.devicePixelRatio || 1, this.dprCap);
|
|
349
|
+
const width = Math.max(2, Math.round(rect.width * dpr));
|
|
350
|
+
const height = Math.max(2, Math.round(rect.height * dpr));
|
|
351
|
+
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
352
|
+
this.canvas.width = width;
|
|
353
|
+
this.canvas.height = height;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
drawNebula(time) {
|
|
358
|
+
const ctx = this.context;
|
|
359
|
+
const { width, height } = this.canvas;
|
|
360
|
+
const t = (time + this.timePhase) * (this.preset.speed || 1);
|
|
361
|
+
const phase = (this.preset.seed || 0) * 0.7;
|
|
362
|
+
const gradient = ctx.createLinearGradient(0, 0, width, height);
|
|
363
|
+
gradient.addColorStop(0, this.preset.colors[0]);
|
|
364
|
+
gradient.addColorStop(0.38, this.preset.colors[1]);
|
|
365
|
+
gradient.addColorStop(0.72, this.preset.colors[2]);
|
|
366
|
+
gradient.addColorStop(1, this.preset.colors[3]);
|
|
367
|
+
ctx.fillStyle = gradient;
|
|
368
|
+
ctx.fillRect(0, 0, width, height);
|
|
369
|
+
|
|
370
|
+
ctx.globalCompositeOperation = 'screen';
|
|
371
|
+
for (let index = 0; index < 6; index += 1) {
|
|
372
|
+
const x = (0.5 + 0.45 * Math.sin(t * 0.32 + index * 1.7 + phase)) * width;
|
|
373
|
+
const y = (0.5 + 0.4 * Math.cos(t * 0.25 + index + phase)) * height;
|
|
374
|
+
const radius = Math.max(width, height) * (0.08 + (index % 3) * 0.04);
|
|
375
|
+
const glow = ctx.createRadialGradient(x, y, 0, x, y, radius);
|
|
376
|
+
glow.addColorStop(0, rgb(this.preset.colors[(index + 1) % 4], 0.24));
|
|
377
|
+
glow.addColorStop(1, rgb(this.preset.colors[index % 4], 0));
|
|
378
|
+
ctx.fillStyle = glow;
|
|
379
|
+
ctx.fillRect(x - radius, y - radius, radius * 2, radius * 2);
|
|
380
|
+
}
|
|
381
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
draw(time) {
|
|
385
|
+
if (!this.visible) return;
|
|
386
|
+
this.drawNebula(time);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
setPreset(preset) {
|
|
390
|
+
this.preset = preset;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
setDprCap(cap) {
|
|
394
|
+
this.dprCap = cap;
|
|
395
|
+
this.resize();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
randomize() {
|
|
399
|
+
if (this.preset) {
|
|
400
|
+
this.preset.seed = Math.random() * 100;
|
|
401
|
+
this.timePhase = Math.random() * Math.PI * 2;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
setMouseColor() {}
|
|
405
|
+
dispose() {}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export { CosmicRenderer as C, FallbackRenderer as F };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
3
|
+
* future events (hover, click, custom) without breaking changes.
|
|
4
|
+
*/
|
|
5
|
+
function createEmitter() {
|
|
6
|
+
// Plain object storage (no Map/Set) so the legacy build has no API
|
|
7
|
+
// dependencies beyond what IE11 provides.
|
|
8
|
+
const listeners = Object.create(null);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
on(event, fn) {
|
|
12
|
+
if (!listeners[event]) listeners[event] = [];
|
|
13
|
+
listeners[event].push(fn);
|
|
14
|
+
return () => {
|
|
15
|
+
const current = listeners[event];
|
|
16
|
+
if (current) {
|
|
17
|
+
const index = current.indexOf(fn);
|
|
18
|
+
if (index !== -1) current.splice(index, 1);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
off(event, fn) {
|
|
23
|
+
const current = listeners[event];
|
|
24
|
+
if (!current) return false;
|
|
25
|
+
const index = current.indexOf(fn);
|
|
26
|
+
if (index === -1) return false;
|
|
27
|
+
current.splice(index, 1);
|
|
28
|
+
return true;
|
|
29
|
+
},
|
|
30
|
+
emit(event, ...args) {
|
|
31
|
+
const current = listeners[event];
|
|
32
|
+
if (!current) return;
|
|
33
|
+
for (const fn of current.slice()) fn(...args);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { createEmitter as c };
|