@anglefeint/astro-theme 0.1.19 → 0.1.21
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
CHANGED
|
@@ -4,13 +4,17 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
4
4
|
|
|
5
5
|
var canvas = shell.querySelector('.hero-canvas');
|
|
6
6
|
var wrap = shell.querySelector('.hero-canvas-wrap');
|
|
7
|
-
|
|
7
|
+
var heroStack = shell.querySelector('.hero-stack');
|
|
8
|
+
if (!canvas || !wrap || !heroStack) return;
|
|
9
|
+
var ctx = canvas.getContext('2d');
|
|
10
|
+
if (!ctx) return;
|
|
8
11
|
|
|
9
12
|
var src = canvas.getAttribute('data-hero-src');
|
|
10
13
|
if (!src) return;
|
|
11
14
|
|
|
12
15
|
var heroStart = 0;
|
|
13
16
|
var heroRaf = 0;
|
|
17
|
+
var resizeTimer = 0;
|
|
14
18
|
var baseCanvas = document.createElement('canvas');
|
|
15
19
|
var baseCtx = baseCanvas.getContext('2d');
|
|
16
20
|
var pixelCanvas = document.createElement('canvas');
|
|
@@ -19,14 +23,17 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
19
23
|
var noiseCtx = noiseCanvas.getContext('2d');
|
|
20
24
|
var edgeCanvas = document.createElement('canvas');
|
|
21
25
|
var edgeCtx = edgeCanvas.getContext('2d');
|
|
26
|
+
var edgeWorkCanvas = document.createElement('canvas');
|
|
27
|
+
var edgeWorkCtx = edgeWorkCanvas.getContext('2d');
|
|
22
28
|
var edgeReady = false;
|
|
29
|
+
var frameCount = 0;
|
|
23
30
|
|
|
24
31
|
var EDGE_PHASE = 1.8;
|
|
25
32
|
var REVEAL_PHASE = 2.5;
|
|
26
33
|
var INTRO_END = EDGE_PHASE + REVEAL_PHASE;
|
|
27
34
|
|
|
28
35
|
function sizeCanvas() {
|
|
29
|
-
var rect =
|
|
36
|
+
var rect = heroStack.getBoundingClientRect();
|
|
30
37
|
var dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
31
38
|
canvas.width = Math.max(2, Math.round(rect.width * dpr));
|
|
32
39
|
canvas.height = Math.max(2, Math.round(rect.height * dpr));
|
|
@@ -55,28 +62,44 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
55
62
|
baseCanvas.width = w;
|
|
56
63
|
baseCanvas.height = h;
|
|
57
64
|
drawBase(baseCtx, img, w, h);
|
|
58
|
-
|
|
65
|
+
var workW = Math.max(2, Math.round(w * 0.5));
|
|
66
|
+
var workH = Math.max(2, Math.round(h * 0.5));
|
|
67
|
+
edgeWorkCanvas.width = workW;
|
|
68
|
+
edgeWorkCanvas.height = workH;
|
|
69
|
+
drawBase(edgeWorkCtx, img, workW, workH);
|
|
59
70
|
|
|
60
|
-
var srcImage =
|
|
71
|
+
var srcImage = edgeWorkCtx.getImageData(0, 0, workW, workH);
|
|
61
72
|
var d = srcImage.data;
|
|
62
|
-
var out =
|
|
73
|
+
var out = edgeWorkCtx.createImageData(workW, workH);
|
|
63
74
|
var od = out.data;
|
|
75
|
+
var rowStride = workW * 4;
|
|
64
76
|
|
|
65
|
-
for (var y = 1; y <
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var i =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
for (var y = 1; y < workH - 1; y++) {
|
|
78
|
+
var row = y * rowStride;
|
|
79
|
+
var rowAbove = row - rowStride;
|
|
80
|
+
var rowBelow = row + rowStride;
|
|
81
|
+
for (var x = 1; x < workW - 1; x++) {
|
|
82
|
+
var i = row + x * 4;
|
|
83
|
+
var iLeft = i - 4;
|
|
84
|
+
var iRight = i + 4;
|
|
85
|
+
var iAbove = rowAbove + x * 4;
|
|
86
|
+
var iAboveLeft = iAbove - 4;
|
|
87
|
+
var iAboveRight = iAbove + 4;
|
|
88
|
+
var iBelow = rowBelow + x * 4;
|
|
89
|
+
var iBelowLeft = iBelow - 4;
|
|
90
|
+
var iBelowRight = iBelow + 4;
|
|
91
|
+
|
|
92
|
+
var lumAboveLeft = d[iAboveLeft] * 0.299 + d[iAboveLeft + 1] * 0.587 + d[iAboveLeft + 2] * 0.114;
|
|
93
|
+
var lumAbove = d[iAbove] * 0.299 + d[iAbove + 1] * 0.587 + d[iAbove + 2] * 0.114;
|
|
94
|
+
var lumAboveRight = d[iAboveRight] * 0.299 + d[iAboveRight + 1] * 0.587 + d[iAboveRight + 2] * 0.114;
|
|
95
|
+
var lumLeft = d[iLeft] * 0.299 + d[iLeft + 1] * 0.587 + d[iLeft + 2] * 0.114;
|
|
96
|
+
var lumRight = d[iRight] * 0.299 + d[iRight + 1] * 0.587 + d[iRight + 2] * 0.114;
|
|
97
|
+
var lumBelowLeft = d[iBelowLeft] * 0.299 + d[iBelowLeft + 1] * 0.587 + d[iBelowLeft + 2] * 0.114;
|
|
98
|
+
var lumBelow = d[iBelow] * 0.299 + d[iBelow + 1] * 0.587 + d[iBelow + 2] * 0.114;
|
|
99
|
+
var lumBelowRight = d[iBelowRight] * 0.299 + d[iBelowRight + 1] * 0.587 + d[iBelowRight + 2] * 0.114;
|
|
75
100
|
|
|
76
|
-
var gx = -
|
|
77
|
-
|
|
78
|
-
var gy = -luma(x - 1, y - 1) - 2 * luma(x, y - 1) - luma(x + 1, y - 1)
|
|
79
|
-
+ luma(x - 1, y + 1) + 2 * luma(x, y + 1) + luma(x + 1, y + 1);
|
|
101
|
+
var gx = -lumAboveLeft - 2 * lumLeft - lumBelowLeft + lumAboveRight + 2 * lumRight + lumBelowRight;
|
|
102
|
+
var gy = -lumAboveLeft - 2 * lumAbove - lumAboveRight + lumBelowLeft + 2 * lumBelow + lumBelowRight;
|
|
80
103
|
var mag = Math.min(255, Math.sqrt(gx * gx + gy * gy));
|
|
81
104
|
|
|
82
105
|
od[i] = Math.min(255, mag * 0.4);
|
|
@@ -86,15 +109,18 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
86
109
|
}
|
|
87
110
|
}
|
|
88
111
|
|
|
89
|
-
|
|
112
|
+
edgeWorkCtx.putImageData(out, 0, 0);
|
|
113
|
+
edgeCtx.clearRect(0, 0, w, h);
|
|
114
|
+
edgeCtx.imageSmoothingEnabled = true;
|
|
115
|
+
edgeCtx.drawImage(edgeWorkCanvas, 0, 0, workW, workH, 0, 0, w, h);
|
|
90
116
|
edgeReady = true;
|
|
91
117
|
}
|
|
92
118
|
|
|
93
119
|
function heroRender(t) {
|
|
94
120
|
if (!heroStart) heroStart = t;
|
|
95
121
|
var elapsed = (t - heroStart) * 0.001;
|
|
96
|
-
|
|
97
|
-
if (!
|
|
122
|
+
frameCount++;
|
|
123
|
+
if (!canvas.img) {
|
|
98
124
|
heroRaf = requestAnimationFrame(heroRender);
|
|
99
125
|
return;
|
|
100
126
|
}
|
|
@@ -161,7 +187,7 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
161
187
|
ctx.fillStyle = barGrad;
|
|
162
188
|
ctx.fillRect(0, scanPos - 30, w, 60);
|
|
163
189
|
|
|
164
|
-
if (Math.random() < 0.08) {
|
|
190
|
+
if ((frameCount % 2) === 0 && Math.random() < 0.08) {
|
|
165
191
|
var glitchY = Math.random() * h;
|
|
166
192
|
var glitchH = 2 + Math.random() * 12;
|
|
167
193
|
var shiftX = (Math.random() - 0.5) * 12;
|
|
@@ -171,14 +197,14 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
171
197
|
ctx.restore();
|
|
172
198
|
}
|
|
173
199
|
|
|
174
|
-
if (elapsed >= 6 && Math.random() < 0.025) {
|
|
200
|
+
if ((frameCount % 3) === 0 && elapsed >= 6 && Math.random() < 0.025) {
|
|
175
201
|
var dropoutY = Math.floor(Math.random() * h);
|
|
176
202
|
var dropoutH = 2 + Math.floor(Math.random() * 2);
|
|
177
203
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.85)';
|
|
178
204
|
ctx.fillRect(0, dropoutY, w, dropoutH);
|
|
179
205
|
}
|
|
180
206
|
|
|
181
|
-
if (Math.random() < 0.03) {
|
|
207
|
+
if ((frameCount % 3) === 0 && Math.random() < 0.03) {
|
|
182
208
|
var burstY = Math.random() * h * 0.8;
|
|
183
209
|
var burstH = 4 + Math.random() * 20;
|
|
184
210
|
if (noiseCanvas.width !== w) {
|
|
@@ -221,8 +247,7 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
221
247
|
buildEdge(img);
|
|
222
248
|
wrap.classList.add('ready');
|
|
223
249
|
if (prefersReducedMotion) {
|
|
224
|
-
|
|
225
|
-
if (staticCtx) staticCtx.drawImage(baseCanvas, 0, 0);
|
|
250
|
+
ctx.drawImage(baseCanvas, 0, 0);
|
|
226
251
|
return;
|
|
227
252
|
}
|
|
228
253
|
heroRaf = requestAnimationFrame(heroRender);
|
|
@@ -230,10 +255,13 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
230
255
|
img.src = new URL(src, window.location.href).href;
|
|
231
256
|
|
|
232
257
|
window.addEventListener('resize', function() {
|
|
233
|
-
if (canvas.img)
|
|
258
|
+
if (!canvas.img) return;
|
|
259
|
+
if (resizeTimer) clearTimeout(resizeTimer);
|
|
260
|
+
resizeTimer = setTimeout(function() {
|
|
261
|
+
resizeTimer = 0;
|
|
234
262
|
sizeCanvas();
|
|
235
263
|
buildEdge(canvas.img);
|
|
236
|
-
}
|
|
264
|
+
}, 180);
|
|
237
265
|
}, { passive: true });
|
|
238
266
|
|
|
239
267
|
function onHeroVisibilityChange() {
|
|
@@ -248,6 +276,7 @@ export function initHeroCanvas(prefersReducedMotion) {
|
|
|
248
276
|
|
|
249
277
|
document.addEventListener('visibilitychange', onHeroVisibilityChange);
|
|
250
278
|
window.addEventListener('beforeunload', function() {
|
|
279
|
+
if (resizeTimer) clearTimeout(resizeTimer);
|
|
251
280
|
cancelAnimationFrame(heroRaf);
|
|
252
281
|
}, { once: true });
|
|
253
282
|
}
|
|
@@ -124,67 +124,40 @@ export function initRedQueenTv(prefersReducedMotion) {
|
|
|
124
124
|
preloadRetryTimers.add(id);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
function
|
|
127
|
+
function preloadDecoderData(item, token, attempt, done) {
|
|
128
128
|
if (token !== playToken || !isPlaying) return;
|
|
129
129
|
var tryCount = typeof attempt === 'number' ? attempt : 0;
|
|
130
130
|
var cachedData = mediaDataCache[item.url];
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
done(true);
|
|
131
|
+
function retryOrFail() {
|
|
132
|
+
if (tryCount >= PRELOAD_RETRY_MAX) {
|
|
133
|
+
done(false);
|
|
135
134
|
return;
|
|
136
135
|
}
|
|
137
|
-
var
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
var retryDelay = Math.min(1800, RETRY_BASE_MS * (tryCount + 1));
|
|
137
|
+
schedulePreloadRetry(function() {
|
|
138
|
+
preloadDecoderData(item, token, tryCount + 1, done);
|
|
139
|
+
}, retryDelay);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function verifyBuffer(buffer) {
|
|
143
|
+
mediaDataCache[item.url] = buffer;
|
|
144
|
+
var decoder = new ImageDecoder({ data: buffer, type: item.type });
|
|
145
|
+
decoder.tracks.ready.then(async function() {
|
|
146
|
+
var result = await decoder.decode({ frameIndex: 0 });
|
|
140
147
|
if (result && result.image && result.image.close) result.image.close();
|
|
141
148
|
done(true);
|
|
142
|
-
}).catch(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
var retryDelay = Math.min(1800, RETRY_BASE_MS * (tryCount + 1));
|
|
148
|
-
schedulePreloadRetry(function() {
|
|
149
|
-
preloadGif(item, token, tryCount + 1, done);
|
|
150
|
-
}, retryDelay);
|
|
151
|
-
});
|
|
149
|
+
}).catch(retryOrFail);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (cachedData instanceof ArrayBuffer) {
|
|
153
|
+
verifyBuffer(cachedData);
|
|
152
154
|
return;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
fetch(resolveItemUrl(item))
|
|
156
158
|
.then(function(response) { return response.arrayBuffer(); })
|
|
157
|
-
.then(
|
|
158
|
-
|
|
159
|
-
if (typeof ImageDecoder === 'undefined') {
|
|
160
|
-
done(true);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
var decoder = new ImageDecoder({ data: buffer, type: item.type });
|
|
164
|
-
decoder.tracks.ready.then(async function() {
|
|
165
|
-
var result = await decoder.decode({ frameIndex: 0 });
|
|
166
|
-
if (result && result.image && result.image.close) result.image.close();
|
|
167
|
-
done(true);
|
|
168
|
-
}).catch(function() {
|
|
169
|
-
if (tryCount >= PRELOAD_RETRY_MAX) {
|
|
170
|
-
done(false);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
var retryDelay = Math.min(1800, RETRY_BASE_MS * (tryCount + 1));
|
|
174
|
-
schedulePreloadRetry(function() {
|
|
175
|
-
preloadGif(item, token, tryCount + 1, done);
|
|
176
|
-
}, retryDelay);
|
|
177
|
-
});
|
|
178
|
-
}).catch(function() {
|
|
179
|
-
if (tryCount >= PRELOAD_RETRY_MAX) {
|
|
180
|
-
done(false);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
var retryDelay = Math.min(1800, RETRY_BASE_MS * (tryCount + 1));
|
|
184
|
-
schedulePreloadRetry(function() {
|
|
185
|
-
preloadGif(item, token, tryCount + 1, done);
|
|
186
|
-
}, retryDelay);
|
|
187
|
-
});
|
|
159
|
+
.then(verifyBuffer)
|
|
160
|
+
.catch(retryOrFail);
|
|
188
161
|
}
|
|
189
162
|
|
|
190
163
|
function preloadImage(item, token, attempt, done) {
|
|
@@ -235,8 +208,9 @@ export function initRedQueenTv(prefersReducedMotion) {
|
|
|
235
208
|
if (left <= 0) finish(!failed);
|
|
236
209
|
}
|
|
237
210
|
|
|
211
|
+
var hasImageDecoder = typeof ImageDecoder !== 'undefined';
|
|
238
212
|
playlist.forEach(function(item) {
|
|
239
|
-
if (
|
|
213
|
+
if (hasImageDecoder) preloadDecoderData(item, token, 0, markDone);
|
|
240
214
|
else preloadImage(item, token, 0, markDone);
|
|
241
215
|
});
|
|
242
216
|
}
|
package/src/styles/ai/prose.css
CHANGED
|
@@ -50,6 +50,7 @@ body.ai-page .ai-content .prose {
|
|
|
50
50
|
/* 加载扫描线 */
|
|
51
51
|
.ai-load-scan {
|
|
52
52
|
position: fixed;
|
|
53
|
+
top: 0;
|
|
53
54
|
left: 0;
|
|
54
55
|
right: 0;
|
|
55
56
|
height: 2px;
|
|
@@ -64,14 +65,15 @@ body.ai-page .ai-content .prose {
|
|
|
64
65
|
animation: ai-scan 0.8s ease-out forwards;
|
|
65
66
|
pointer-events: none;
|
|
66
67
|
z-index: 20;
|
|
68
|
+
will-change: transform, opacity;
|
|
67
69
|
}
|
|
68
70
|
@keyframes ai-scan {
|
|
69
71
|
0% {
|
|
70
|
-
|
|
72
|
+
transform: translateY(0);
|
|
71
73
|
opacity: 1;
|
|
72
74
|
}
|
|
73
75
|
100% {
|
|
74
|
-
|
|
76
|
+
transform: translateY(100vh);
|
|
75
77
|
opacity: 0.2;
|
|
76
78
|
}
|
|
77
79
|
}
|
package/src/styles/blog-post.css
CHANGED
|
@@ -150,11 +150,11 @@
|
|
|
150
150
|
inset 0 1px 0 rgba(220, 242, 255, 0.22);
|
|
151
151
|
overflow: hidden;
|
|
152
152
|
backdrop-filter: blur(1.5px);
|
|
153
|
+
transform: translate3d(0, 0, 0);
|
|
154
|
+
will-change: transform, opacity;
|
|
153
155
|
transition:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
padding 320ms ease,
|
|
157
|
-
border-radius 320ms ease,
|
|
156
|
+
transform 320ms ease,
|
|
157
|
+
opacity 220ms ease,
|
|
158
158
|
box-shadow 320ms ease,
|
|
159
159
|
background 320ms ease;
|
|
160
160
|
}
|
|
@@ -243,10 +243,10 @@
|
|
|
243
243
|
outline-offset: -2px;
|
|
244
244
|
}
|
|
245
245
|
.rq-tv.rq-tv-collapsed {
|
|
246
|
-
top: 27vh;
|
|
247
246
|
width: 34px;
|
|
248
247
|
padding: 0;
|
|
249
248
|
border-radius: 6px;
|
|
249
|
+
transform: translate3d(0, 2vh, 0);
|
|
250
250
|
background: linear-gradient(165deg, rgba(34, 58, 78, 0.9), rgba(10, 19, 30, 0.92));
|
|
251
251
|
box-shadow:
|
|
252
252
|
0 10px 20px rgba(4, 10, 18, 0.42),
|
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
position: absolute;
|
|
339
339
|
top: 0;
|
|
340
340
|
bottom: 0;
|
|
341
|
-
left:
|
|
341
|
+
left: 0;
|
|
342
342
|
width: 35%;
|
|
343
343
|
background: linear-gradient(
|
|
344
344
|
90deg,
|
|
@@ -346,11 +346,13 @@
|
|
|
346
346
|
rgba(164, 228, 255, 0.88),
|
|
347
347
|
rgba(132, 214, 255, 0)
|
|
348
348
|
);
|
|
349
|
+
transform: translateX(-100%);
|
|
350
|
+
will-change: transform;
|
|
349
351
|
animation: ai-title-flow-run 3.8s linear infinite;
|
|
350
352
|
}
|
|
351
353
|
@keyframes ai-title-flow-run {
|
|
352
354
|
to {
|
|
353
|
-
|
|
355
|
+
transform: translateX(285%);
|
|
354
356
|
}
|
|
355
357
|
}
|
|
356
358
|
.ai-stage-toast {
|