@anglefeint/astro-theme 0.1.10 → 0.1.12
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 +3 -1
- package/public/styles/theme-ai.css +2 -52
- package/src/config/about.ts +1 -1
- package/src/layouts/BlogPost.astro +5 -63
- package/src/layouts/shells/MatrixShell.astro +6 -1
- package/{public → src}/scripts/about-effects.js +2 -10
- package/{public → src}/scripts/blogpost-effects.js +114 -10
- package/{public → src}/scripts/home-matrix.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anglefeint/astro-theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Anglefeint core theme package for Astro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"src/config",
|
|
12
12
|
"src/components",
|
|
13
13
|
"src/layouts",
|
|
14
|
+
"src/scripts",
|
|
14
15
|
"src/i18n",
|
|
15
16
|
"src/styles",
|
|
16
17
|
"src/assets/theme",
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
".": "./src/index.ts",
|
|
27
28
|
"./components/*": "./src/components/*",
|
|
28
29
|
"./layouts/*": "./src/layouts/*",
|
|
30
|
+
"./scripts/*": "./src/scripts/*",
|
|
29
31
|
"./i18n/*": "./src/i18n/*",
|
|
30
32
|
"./styles/*": "./src/styles/*",
|
|
31
33
|
"./assets/*": "./src/assets/*",
|
|
@@ -216,12 +216,13 @@ body.ai-page::-webkit-scrollbar-thumb {
|
|
|
216
216
|
opacity: 0.7;
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
|
-
.ai-network {
|
|
219
|
+
.ai-network-canvas {
|
|
220
220
|
position: absolute;
|
|
221
221
|
inset: -8%;
|
|
222
222
|
width: 116%;
|
|
223
223
|
height: 116%;
|
|
224
224
|
opacity: 1;
|
|
225
|
+
pointer-events: none;
|
|
225
226
|
filter: brightness(1.28) saturate(1.08);
|
|
226
227
|
animation: ai-drift 25s ease-in-out infinite;
|
|
227
228
|
}
|
|
@@ -240,57 +241,6 @@ body.ai-page::-webkit-scrollbar-thumb {
|
|
|
240
241
|
transform: translate(0.5%, -0.8%) scale(1.005);
|
|
241
242
|
}
|
|
242
243
|
}
|
|
243
|
-
.ai-network .ai-dots circle {
|
|
244
|
-
transform-origin: center;
|
|
245
|
-
animation:
|
|
246
|
-
ai-dot-float 8s ease-in-out infinite,
|
|
247
|
-
ai-dot-breathe 5s ease-in-out infinite;
|
|
248
|
-
}
|
|
249
|
-
.ai-network .ai-dots circle:nth-child(odd) {
|
|
250
|
-
animation-delay: -3s;
|
|
251
|
-
}
|
|
252
|
-
.ai-network .ai-dots circle:nth-child(3n) {
|
|
253
|
-
animation-delay: -5s;
|
|
254
|
-
}
|
|
255
|
-
.ai-network .ai-dots circle:nth-child(5n) {
|
|
256
|
-
animation-duration: 10s;
|
|
257
|
-
}
|
|
258
|
-
.ai-network .ai-dots circle:nth-child(4n) {
|
|
259
|
-
animation-delay: -1s;
|
|
260
|
-
}
|
|
261
|
-
.ai-network .ai-lines line {
|
|
262
|
-
stroke-dasharray: 6 12;
|
|
263
|
-
animation: ai-line-pulse 4s linear infinite;
|
|
264
|
-
}
|
|
265
|
-
.ai-network .ai-lines line:nth-child(odd) {
|
|
266
|
-
animation-delay: -2s;
|
|
267
|
-
}
|
|
268
|
-
@keyframes ai-line-pulse {
|
|
269
|
-
to {
|
|
270
|
-
stroke-dashoffset: -18;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
@keyframes ai-dot-float {
|
|
274
|
-
0%,
|
|
275
|
-
100% {
|
|
276
|
-
transform: translate(0, 0);
|
|
277
|
-
}
|
|
278
|
-
33% {
|
|
279
|
-
transform: translate(1.5px, -2px);
|
|
280
|
-
}
|
|
281
|
-
66% {
|
|
282
|
-
transform: translate(-1px, 1.5px);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
@keyframes ai-dot-breathe {
|
|
286
|
-
0%,
|
|
287
|
-
100% {
|
|
288
|
-
opacity: 1;
|
|
289
|
-
}
|
|
290
|
-
50% {
|
|
291
|
-
opacity: 0.75;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
244
|
body.ai-page .ai-content,
|
|
295
245
|
body.ai-page footer {
|
|
296
246
|
position: relative;
|
package/src/config/about.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* About page content and runtime behavior configuration.
|
|
3
|
-
* Used by src/pages/[lang]/about.astro and
|
|
3
|
+
* Used by src/pages/[lang]/about.astro and packages/theme/src/scripts/about-effects.js.
|
|
4
4
|
*/
|
|
5
5
|
export const ABOUT_CONFIG = {
|
|
6
6
|
metaLine: '$ profile booted | mode: builder',
|
|
@@ -48,29 +48,6 @@ const hasSystemMeta = Boolean(aiModel || aiMode || aiState);
|
|
|
48
48
|
const hasResponseMeta = aiLatencyMs !== undefined || aiConfidence !== undefined;
|
|
49
49
|
const hasStats = aiModel || wordCount !== undefined || tokenCount !== undefined;
|
|
50
50
|
const confidenceText = aiConfidence !== undefined ? aiConfidence.toFixed(2) : undefined;
|
|
51
|
-
|
|
52
|
-
// 点云:全屏分散但不过于稀疏
|
|
53
|
-
const w = 1200; const h = 800;
|
|
54
|
-
const pts: { x: number; y: number; r: number; depth: number }[] = [];
|
|
55
|
-
const pad = 50;
|
|
56
|
-
for (let i = 0; i < 58; i++) {
|
|
57
|
-
const x = pad + Math.random() * (w - pad * 2);
|
|
58
|
-
const y = pad + Math.random() * (h - pad * 2);
|
|
59
|
-
const depth = Math.random();
|
|
60
|
-
pts.push({
|
|
61
|
-
x, y,
|
|
62
|
-
r: 1.1 + depth * 1.3,
|
|
63
|
-
depth,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
const connectDist = 138;
|
|
67
|
-
const edges: [number, number][] = [];
|
|
68
|
-
for (let i = 0; i < pts.length; i++) {
|
|
69
|
-
for (let j = i + 1; j < pts.length; j++) {
|
|
70
|
-
const d = Math.hypot(pts[i].x - pts[j].x, pts[i].y - pts[j].y);
|
|
71
|
-
if (d < connectDist) edges.push([i, j]);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
51
|
---
|
|
75
52
|
|
|
76
53
|
<AiShell
|
|
@@ -99,45 +76,7 @@ for (let i = 0; i < pts.length; i++) {
|
|
|
99
76
|
<span class="ai-particle" style={`--x: ${20 + (i * 7) % 60}%; --y: ${10 + (i * 11) % 70}%; --d: ${3 + (i % 4)}s`}></span>
|
|
100
77
|
))}
|
|
101
78
|
</div>
|
|
102
|
-
<
|
|
103
|
-
<defs>
|
|
104
|
-
<linearGradient id="ai-line-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
105
|
-
<stop offset="0%" stop-color="rgba(180,235,255,0.26)" />
|
|
106
|
-
<stop offset="50%" stop-color="rgba(236,252,255,0.74)" />
|
|
107
|
-
<stop offset="100%" stop-color="rgba(180,235,255,0.26)" />
|
|
108
|
-
</linearGradient>
|
|
109
|
-
<filter id="ai-dot-glow">
|
|
110
|
-
<feGaussianBlur stdDeviation="2.2" result="blur" />
|
|
111
|
-
<feMerge>
|
|
112
|
-
<feMergeNode in="blur" />
|
|
113
|
-
<feMergeNode in="SourceGraphic" />
|
|
114
|
-
</feMerge>
|
|
115
|
-
</filter>
|
|
116
|
-
</defs>
|
|
117
|
-
<g class="ai-lines">
|
|
118
|
-
{edges.map(([i, j]) => (
|
|
119
|
-
<line
|
|
120
|
-
x1={pts[i].x}
|
|
121
|
-
y1={pts[i].y}
|
|
122
|
-
x2={pts[j].x}
|
|
123
|
-
y2={pts[j].y}
|
|
124
|
-
stroke="url(#ai-line-grad)"
|
|
125
|
-
stroke-width="0.4"
|
|
126
|
-
/>
|
|
127
|
-
))}
|
|
128
|
-
</g>
|
|
129
|
-
<g class="ai-dots">
|
|
130
|
-
{pts.map((p) => (
|
|
131
|
-
<circle
|
|
132
|
-
cx={p.x}
|
|
133
|
-
cy={p.y}
|
|
134
|
-
r={p.r}
|
|
135
|
-
fill={`rgba(232,255,255,${0.72 + p.depth * 0.48})`}
|
|
136
|
-
filter="url(#ai-dot-glow)"
|
|
137
|
-
/>
|
|
138
|
-
))}
|
|
139
|
-
</g>
|
|
140
|
-
</svg>
|
|
79
|
+
<canvas class="ai-network-canvas" aria-hidden="true"></canvas>
|
|
141
80
|
</div>
|
|
142
81
|
<aside class="rq-tv rq-tv-collapsed">
|
|
143
82
|
<div class="rq-tv-stage" data-rq-src={themeRedqueen1.src} data-rq-src2={themeRedqueen2.src}></div>
|
|
@@ -257,6 +196,9 @@ for (let i = 0; i < pts.length; i++) {
|
|
|
257
196
|
</a>
|
|
258
197
|
</nav>
|
|
259
198
|
<Fragment slot="body-end">
|
|
260
|
-
<script
|
|
199
|
+
<script>
|
|
200
|
+
import { initBlogpostEffects } from '../scripts/blogpost-effects.js';
|
|
201
|
+
initBlogpostEffects();
|
|
202
|
+
</script>
|
|
261
203
|
</Fragment>
|
|
262
204
|
</AiShell>
|
|
@@ -14,6 +14,11 @@ const { locale, title, description } = Astro.props as Props;
|
|
|
14
14
|
<ThemeFrame locale={locale} title={title} description={description} bodyClass="page-home" mainClass="page-main home-content">
|
|
15
15
|
<link slot="head" rel="stylesheet" href="/styles/home-page.css" />
|
|
16
16
|
<canvas slot="body-start" id="matrix-bg" aria-hidden="true"></canvas>
|
|
17
|
-
<
|
|
17
|
+
<Fragment slot="body-end">
|
|
18
|
+
<script>
|
|
19
|
+
import { initHomeMatrix } from '../../scripts/home-matrix.js';
|
|
20
|
+
initHomeMatrix();
|
|
21
|
+
</script>
|
|
22
|
+
</Fragment>
|
|
18
23
|
<slot />
|
|
19
24
|
</ThemeFrame>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function init() {
|
|
1
|
+
export function initAboutEffects() {
|
|
3
2
|
var runtimeConfig = {};
|
|
4
3
|
var runtimeConfigEl = document.getElementById('hacker-runtime-config');
|
|
5
4
|
if (runtimeConfigEl && runtimeConfigEl.textContent) {
|
|
@@ -551,11 +550,4 @@
|
|
|
551
550
|
}, 1200);
|
|
552
551
|
});
|
|
553
552
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (document.readyState === 'loading') {
|
|
557
|
-
document.addEventListener('DOMContentLoaded', init);
|
|
558
|
-
} else {
|
|
559
|
-
init();
|
|
560
|
-
}
|
|
561
|
-
})();
|
|
553
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function init() {
|
|
1
|
+
export function initBlogpostEffects() {
|
|
3
2
|
var prefersReducedMotion = false;
|
|
4
3
|
try {
|
|
5
4
|
prefersReducedMotion = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
|
|
@@ -54,6 +53,118 @@
|
|
|
54
53
|
window.scrollTo({ top: 0, behavior: prefersReducedMotion ? 'auto' : 'smooth' });
|
|
55
54
|
});
|
|
56
55
|
}
|
|
56
|
+
function initNetworkCanvas() {
|
|
57
|
+
var canvas = document.querySelector('.ai-network-canvas');
|
|
58
|
+
if (!canvas) return;
|
|
59
|
+
var ctx = canvas.getContext('2d');
|
|
60
|
+
if (!ctx) return;
|
|
61
|
+
var MAX_DPR = 2;
|
|
62
|
+
var rafId = 0;
|
|
63
|
+
var start = 0;
|
|
64
|
+
var last = 0;
|
|
65
|
+
var fps = prefersReducedMotion ? 1 : 30;
|
|
66
|
+
var frameMs = 1000 / fps;
|
|
67
|
+
var points = [];
|
|
68
|
+
var edges = [];
|
|
69
|
+
|
|
70
|
+
function seededRandom(seed) {
|
|
71
|
+
var s = seed >>> 0;
|
|
72
|
+
return function() {
|
|
73
|
+
s = (1664525 * s + 1013904223) >>> 0;
|
|
74
|
+
return s / 4294967296;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function resize() {
|
|
79
|
+
var rect = canvas.getBoundingClientRect();
|
|
80
|
+
var dpr = Math.min(MAX_DPR, window.devicePixelRatio || 1);
|
|
81
|
+
canvas.width = Math.max(2, Math.round(rect.width * dpr));
|
|
82
|
+
canvas.height = Math.max(2, Math.round(rect.height * dpr));
|
|
83
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
84
|
+
|
|
85
|
+
var w = rect.width;
|
|
86
|
+
var h = rect.height;
|
|
87
|
+
var rand = seededRandom(0xA13F09);
|
|
88
|
+
var count = Math.max(20, Math.min(36, Math.round((w * h) / 32000)));
|
|
89
|
+
var connectDist = Math.min(160, Math.max(90, Math.min(w, h) * 0.18));
|
|
90
|
+
var maxEdges = 120;
|
|
91
|
+
points = [];
|
|
92
|
+
for (var i = 0; i < count; i++) {
|
|
93
|
+
points.push({
|
|
94
|
+
x: 20 + rand() * Math.max(20, w - 40),
|
|
95
|
+
y: 20 + rand() * Math.max(20, h - 40),
|
|
96
|
+
r: 1 + rand() * 1.6,
|
|
97
|
+
p: rand() * Math.PI * 2,
|
|
98
|
+
a: 0.5 + rand() * 0.5,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
edges = [];
|
|
102
|
+
for (var a = 0; a < points.length; a++) {
|
|
103
|
+
for (var b = a + 1; b < points.length; b++) {
|
|
104
|
+
if (edges.length >= maxEdges) break;
|
|
105
|
+
var dx = points[a].x - points[b].x;
|
|
106
|
+
var dy = points[a].y - points[b].y;
|
|
107
|
+
var d = Math.sqrt(dx * dx + dy * dy);
|
|
108
|
+
if (d < connectDist) edges.push([a, b, d / connectDist]);
|
|
109
|
+
}
|
|
110
|
+
if (edges.length >= maxEdges) break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function render(ts) {
|
|
115
|
+
if (!start) start = ts;
|
|
116
|
+
if (!prefersReducedMotion && ts - last < frameMs) {
|
|
117
|
+
rafId = requestAnimationFrame(render);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
last = ts;
|
|
121
|
+
var t = (ts - start) * 0.001;
|
|
122
|
+
var w = canvas.clientWidth;
|
|
123
|
+
var h = canvas.clientHeight;
|
|
124
|
+
ctx.clearRect(0, 0, w, h);
|
|
125
|
+
|
|
126
|
+
for (var i = 0; i < edges.length; i++) {
|
|
127
|
+
var e = edges[i];
|
|
128
|
+
var p1 = points[e[0]];
|
|
129
|
+
var p2 = points[e[1]];
|
|
130
|
+
var alpha = (1 - e[2]) * (prefersReducedMotion ? 0.2 : (0.18 + 0.06 * Math.sin(t * 0.9 + i)));
|
|
131
|
+
ctx.strokeStyle = 'rgba(190, 236, 255,' + Math.max(0.06, alpha).toFixed(3) + ')';
|
|
132
|
+
ctx.lineWidth = 0.6;
|
|
133
|
+
ctx.beginPath();
|
|
134
|
+
ctx.moveTo(p1.x, p1.y);
|
|
135
|
+
ctx.lineTo(p2.x, p2.y);
|
|
136
|
+
ctx.stroke();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for (var j = 0; j < points.length; j++) {
|
|
140
|
+
var p = points[j];
|
|
141
|
+
var pulse = prefersReducedMotion ? 1 : (1 + 0.18 * Math.sin(t * 1.5 + p.p));
|
|
142
|
+
ctx.fillStyle = 'rgba(228, 251, 255,' + (0.58 * p.a).toFixed(3) + ')';
|
|
143
|
+
ctx.beginPath();
|
|
144
|
+
ctx.arc(p.x, p.y, p.r * pulse, 0, Math.PI * 2);
|
|
145
|
+
ctx.fill();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!prefersReducedMotion) rafId = requestAnimationFrame(render);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function stop() {
|
|
152
|
+
if (!rafId) return;
|
|
153
|
+
cancelAnimationFrame(rafId);
|
|
154
|
+
rafId = 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
resize();
|
|
158
|
+
render(performance.now());
|
|
159
|
+
window.addEventListener('resize', resize, { passive: true });
|
|
160
|
+
document.addEventListener('visibilitychange', function() {
|
|
161
|
+
if (prefersReducedMotion) return;
|
|
162
|
+
if (document.hidden) stop();
|
|
163
|
+
else if (!rafId) rafId = requestAnimationFrame(render);
|
|
164
|
+
});
|
|
165
|
+
window.addEventListener('beforeunload', stop, { once: true });
|
|
166
|
+
}
|
|
167
|
+
initNetworkCanvas();
|
|
57
168
|
function initHeroCanvas() {
|
|
58
169
|
var shell = document.querySelector('.hero-shell');
|
|
59
170
|
if (!shell) return;
|
|
@@ -972,11 +1083,4 @@
|
|
|
972
1083
|
}, 1200);
|
|
973
1084
|
});
|
|
974
1085
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
if (document.readyState === 'loading') {
|
|
978
|
-
document.addEventListener('DOMContentLoaded', init);
|
|
979
|
-
} else {
|
|
980
|
-
init();
|
|
981
|
-
}
|
|
982
|
-
})();
|
|
1086
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(
|
|
1
|
+
export function initHomeMatrix() {
|
|
2
2
|
const chars =
|
|
3
3
|
'!"#$%&\'()*+,-./:;<=>?[\\]^_{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
4
4
|
const matrixFont =
|
|
@@ -114,4 +114,4 @@
|
|
|
114
114
|
document.body.style.setProperty('--matrix-mx', `${event.clientX}px`);
|
|
115
115
|
document.body.style.setProperty('--matrix-my', `${event.clientY}px`);
|
|
116
116
|
});
|
|
117
|
-
}
|
|
117
|
+
}
|