hexo-theme-stellar 1.42.1 → 1.43.1
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/.claude/skills/stellar-theme-dev/SKILL.md +1 -0
- package/CHANGELOG.md +41 -0
- package/THIRD-PARTY-NOTICES.md +28 -0
- package/_config.yml +17 -7
- package/_data/icons.yml +10 -9
- package/languages/en.yml +11 -0
- package/languages/zh-CN.yml +11 -0
- package/languages/zh-TW.yml +11 -0
- package/layout/_partial/comments/artalk/layout.ejs +1 -1
- package/layout/_partial/comments/beaudar/layout.ejs +1 -1
- package/layout/_partial/comments/giscus/layout.ejs +1 -1
- package/layout/_partial/comments/twikoo/layout.ejs +1 -1
- package/layout/_partial/comments/utterances/layout.ejs +1 -1
- package/layout/_partial/comments/waline/layout.ejs +1 -1
- package/layout/_partial/components/collection-item.ejs +44 -0
- package/layout/_partial/components/collection.ejs +26 -0
- package/layout/_partial/components/widget-frame.ejs +35 -0
- package/layout/_partial/cover/wiki_cover.ejs +82 -26
- package/layout/_partial/dropdown.ejs +62 -0
- package/layout/_partial/head.ejs +9 -0
- package/layout/_partial/main/navbar/breadcrumb/blog.ejs +1 -1
- package/layout/_partial/main/post_list/archive_item.ejs +12 -0
- package/layout/_partial/main/post_list/topic_card.ejs +21 -9
- package/layout/_partial/main/post_list/wiki_card.ejs +49 -10
- package/layout/_partial/scripts/defines.ejs +2 -8
- package/layout/_partial/scripts/lazyload.ejs +0 -3
- package/layout/_partial/scripts.ejs +1 -0
- package/layout/_partial/sidebar/index_leftbar.ejs +12 -2
- package/layout/_partial/sidebar/logo.ejs +1 -1
- package/layout/_partial/sidebar/menu.ejs +21 -23
- package/layout/_partial/widgets/components/linklist.ejs +23 -21
- package/layout/_partial/widgets/linklist.ejs +7 -12
- package/layout/_partial/widgets/recent.ejs +52 -41
- package/layout/_partial/widgets/related.ejs +47 -36
- package/layout/_partial/widgets/tagtree.ejs +70 -54
- package/layout/_partial/widgets/toc.ejs +37 -62
- package/layout/_partial/widgets/tree.ejs +38 -51
- package/layout/_plugins/mermaid.ejs +3 -4
- package/layout/archive.ejs +11 -20
- package/layout/collection-preview.ejs +60 -0
- package/layout/index_topic.ejs +12 -6
- package/layout/index_wiki.ejs +49 -3
- package/layout/layout.ejs +4 -3
- package/package.json +1 -1
- package/scripts/events/index.js +0 -2
- package/scripts/generators/stellar-icons.js +1 -1
- package/scripts/lib/subtitle.js +5 -1
- package/scripts/tags/index.js +1 -0
- package/scripts/tags/lib/about.js +1 -1
- package/scripts/tags/lib/albums.js +1 -1
- package/scripts/tags/lib/banner.js +1 -1
- package/scripts/tags/lib/dropdown.js +64 -0
- package/scripts/tags/lib/friends.js +1 -1
- package/scripts/tags/lib/gallery.js +3 -3
- package/scripts/tags/lib/image.js +1 -1
- package/scripts/tags/lib/posters.js +1 -1
- package/scripts/tags/lib/sites.js +8 -4
- package/source/css/_common/base.styl +4 -4
- package/source/css/_common/blockquote.styl +2 -2
- package/source/css/_common/dropdown.styl +132 -0
- package/source/css/_common/html.styl +1 -1
- package/source/css/_common/loading.styl +5 -2
- package/source/css/_common/title.styl +8 -8
- package/source/css/_components/collection.styl +188 -0
- package/source/css/_components/layout.styl +1 -1
- package/source/css/_components/list.styl +44 -46
- package/source/css/_components/md.styl +3 -3
- package/source/css/_components/page-transition.styl +22 -0
- package/source/css/_components/pages/archives.styl +19 -18
- package/source/css/_components/pages/article-indent.styl +2 -2
- package/source/css/_components/pages/article-story.styl +9 -5
- package/source/css/_components/pages/collection-preview.styl +68 -0
- package/source/css/_components/pages/notebook.styl +11 -9
- package/source/css/_components/partial/article-footer.styl +7 -4
- package/source/css/_components/partial/cover.styl +280 -1
- package/source/css/_components/partial/related.styl +10 -6
- package/source/css/_components/sidebar/footer.styl +66 -12
- package/source/css/_components/sidebar/nav-area.styl +6 -1
- package/source/css/_components/sidebar/search.styl +6 -2
- package/source/css/_components/tag-plugins/chat.styl +1 -1
- package/source/css/_components/tag-plugins/folders.styl +4 -4
- package/source/css/_components/tag-plugins/folding.styl +3 -3
- package/source/css/_components/tag-plugins/hashtag.styl +2 -3
- package/source/css/_components/tag-plugins/mdrender.styl +1 -1
- package/source/css/_components/tag-plugins/note.styl +4 -4
- package/source/css/_components/tag-plugins/poetry.styl +5 -5
- package/source/css/_components/tag-plugins/quot.styl +1 -2
- package/source/css/_components/tag-plugins/quote.styl +1 -1
- package/source/css/_components/tag-plugins/tabs.styl +2 -2
- package/source/css/_components/tag-plugins/timeline.styl +4 -4
- package/source/css/_components/widgets/markdown.styl +1 -14
- package/source/css/_components/widgets/timeline.styl +2 -2
- package/source/css/_components/widgets/toc.styl +22 -20
- package/source/css/_components/widgets/widgets.styl +13 -1
- package/source/css/_components/wiki-card.styl +209 -0
- package/source/css/_custom.styl +22 -20
- package/source/css/_plugins/lazyload.styl +8 -5
- package/source/css/comments/utterances.styl +2 -2
- package/source/css/plugins/mermaid.styl +31 -12
- package/source/js/icons.js +1 -1
- package/source/js/main.js +62 -6
- package/source/js/plugins/adaptive-text.js +46 -2
- package/source/js/plugins/dropdown.js +435 -0
- package/source/js/plugins/galaxy.js +423 -0
- package/source/js/search/algolia-search.js +1 -1
- package/source/js/search/local-search.js +1 -1
- package/source/js/services/ghinfo.js +31 -3
- package/source/js/services/siteinfo.js +26 -0
- package/source/js/services/sites.js +6 -2
- package/source/js/services.js +5 -2
- package/source/js/tagtree.js +7 -7
- package/source/js/utils.js +1 -1
- package/layout/_partial/widgets/components/link.ejs +0 -21
- package/source/css/_components/sidebar/menu.styl +0 -77
- package/source/css/_components/widgets/components.styl +0 -68
- package/source/css/_components/widgets/list.styl +0 -46
- package/source/css/_components/widgets/related.styl +0 -40
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Wiki Galaxy WebGL background.
|
|
3
|
+
* Shader adapted from React Bits Galaxy: https://github.com/DavidHDev/react-bits
|
|
4
|
+
* React Bits is MIT licensed; see THIRD-PARTY-NOTICES.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function () {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const vertexShader = `
|
|
11
|
+
attribute vec2 position;
|
|
12
|
+
|
|
13
|
+
varying vec2 vUv;
|
|
14
|
+
|
|
15
|
+
void main() {
|
|
16
|
+
vUv = position * 0.5 + 0.5;
|
|
17
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const fragmentShader = `
|
|
22
|
+
precision highp float;
|
|
23
|
+
|
|
24
|
+
uniform float uTime;
|
|
25
|
+
uniform vec3 uResolution;
|
|
26
|
+
uniform vec2 uFocal;
|
|
27
|
+
uniform vec2 uRotation;
|
|
28
|
+
uniform float uStarSpeed;
|
|
29
|
+
uniform float uDensity;
|
|
30
|
+
uniform float uHueShift;
|
|
31
|
+
uniform float uSpeed;
|
|
32
|
+
uniform vec2 uMouse;
|
|
33
|
+
uniform float uGlowIntensity;
|
|
34
|
+
uniform float uSaturation;
|
|
35
|
+
uniform bool uMouseRepulsion;
|
|
36
|
+
uniform float uTwinkleIntensity;
|
|
37
|
+
uniform float uRotationSpeed;
|
|
38
|
+
uniform float uRepulsionStrength;
|
|
39
|
+
uniform float uMouseActiveFactor;
|
|
40
|
+
uniform float uAutoCenterRepulsion;
|
|
41
|
+
uniform bool uTransparent;
|
|
42
|
+
|
|
43
|
+
varying vec2 vUv;
|
|
44
|
+
|
|
45
|
+
#define NUM_LAYER 4.0
|
|
46
|
+
#define STAR_COLOR_CUTOFF 0.2
|
|
47
|
+
#define MAT45 mat2(0.7071, -0.7071, 0.7071, 0.7071)
|
|
48
|
+
#define PERIOD 3.0
|
|
49
|
+
|
|
50
|
+
float Hash21(vec2 p) {
|
|
51
|
+
p = fract(p * vec2(123.34, 456.21));
|
|
52
|
+
p += dot(p, p + 45.32);
|
|
53
|
+
return fract(p.x * p.y);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
float tri(float x) {
|
|
57
|
+
return abs(fract(x) * 2.0 - 1.0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
float tris(float x) {
|
|
61
|
+
float t = fract(x);
|
|
62
|
+
return 1.0 - smoothstep(0.0, 1.0, abs(2.0 * t - 1.0));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
float trisn(float x) {
|
|
66
|
+
float t = fract(x);
|
|
67
|
+
return 2.0 * (1.0 - smoothstep(0.0, 1.0, abs(2.0 * t - 1.0))) - 1.0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
vec3 hsv2rgb(vec3 c) {
|
|
71
|
+
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
72
|
+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
73
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
float Star(vec2 uv, float flare) {
|
|
77
|
+
float d = length(uv);
|
|
78
|
+
float m = (0.05 * uGlowIntensity) / d;
|
|
79
|
+
float rays = smoothstep(0.0, 1.0, 1.0 - abs(uv.x * uv.y * 1000.0));
|
|
80
|
+
m += rays * flare * uGlowIntensity;
|
|
81
|
+
uv *= MAT45;
|
|
82
|
+
rays = smoothstep(0.0, 1.0, 1.0 - abs(uv.x * uv.y * 1000.0));
|
|
83
|
+
m += rays * 0.3 * flare * uGlowIntensity;
|
|
84
|
+
m *= smoothstep(1.0, 0.2, d);
|
|
85
|
+
return m;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
vec3 StarLayer(vec2 uv) {
|
|
89
|
+
vec3 col = vec3(0.0);
|
|
90
|
+
vec2 gv = fract(uv) - 0.5;
|
|
91
|
+
vec2 id = floor(uv);
|
|
92
|
+
|
|
93
|
+
for (int y = -1; y <= 1; y++) {
|
|
94
|
+
for (int x = -1; x <= 1; x++) {
|
|
95
|
+
vec2 offset = vec2(float(x), float(y));
|
|
96
|
+
vec2 si = id + offset;
|
|
97
|
+
float seed = Hash21(si);
|
|
98
|
+
float size = fract(seed * 345.32);
|
|
99
|
+
float glossLocal = tri(uStarSpeed / (PERIOD * seed + 1.0));
|
|
100
|
+
float flareSize = smoothstep(0.9, 1.0, size) * glossLocal;
|
|
101
|
+
|
|
102
|
+
float red = smoothstep(STAR_COLOR_CUTOFF, 1.0, Hash21(si + 1.0)) + STAR_COLOR_CUTOFF;
|
|
103
|
+
float blu = smoothstep(STAR_COLOR_CUTOFF, 1.0, Hash21(si + 3.0)) + STAR_COLOR_CUTOFF;
|
|
104
|
+
float grn = min(red, blu) * seed;
|
|
105
|
+
vec3 base = vec3(red, grn, blu);
|
|
106
|
+
|
|
107
|
+
float hue = atan(base.g - base.r, base.b - base.r) / (2.0 * 3.14159) + 0.5;
|
|
108
|
+
hue = fract(hue + uHueShift / 360.0);
|
|
109
|
+
float sat = length(base - vec3(dot(base, vec3(0.299, 0.587, 0.114)))) * uSaturation;
|
|
110
|
+
float val = max(max(base.r, base.g), base.b);
|
|
111
|
+
base = hsv2rgb(vec3(hue, sat, val));
|
|
112
|
+
|
|
113
|
+
vec2 pad = vec2(
|
|
114
|
+
tris(seed * 34.0 + uTime * uSpeed / 10.0),
|
|
115
|
+
tris(seed * 38.0 + uTime * uSpeed / 30.0)
|
|
116
|
+
) - 0.5;
|
|
117
|
+
|
|
118
|
+
float star = Star(gv - offset - pad, flareSize);
|
|
119
|
+
float twinkle = trisn(uTime * uSpeed + seed * 6.2831) * 0.5 + 1.0;
|
|
120
|
+
twinkle = mix(1.0, twinkle, uTwinkleIntensity);
|
|
121
|
+
star *= twinkle;
|
|
122
|
+
col += star * size * base;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return col;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
void main() {
|
|
130
|
+
vec2 focalPx = uFocal * uResolution.xy;
|
|
131
|
+
vec2 uv = (vUv * uResolution.xy - focalPx) / uResolution.y;
|
|
132
|
+
vec2 mouseNorm = uMouse - vec2(0.5);
|
|
133
|
+
|
|
134
|
+
if (uAutoCenterRepulsion > 0.0) {
|
|
135
|
+
vec2 centerUV = vec2(0.0, 0.0);
|
|
136
|
+
float centerDist = length(uv - centerUV);
|
|
137
|
+
vec2 repulsion = normalize(uv - centerUV) * (uAutoCenterRepulsion / (centerDist + 0.1));
|
|
138
|
+
uv += repulsion * 0.05;
|
|
139
|
+
} else if (uMouseRepulsion) {
|
|
140
|
+
vec2 mousePosUV = (uMouse * uResolution.xy - focalPx) / uResolution.y;
|
|
141
|
+
float mouseDist = length(uv - mousePosUV);
|
|
142
|
+
vec2 repulsion = normalize(uv - mousePosUV) * (uRepulsionStrength / (mouseDist + 0.1));
|
|
143
|
+
uv += repulsion * 0.05 * uMouseActiveFactor;
|
|
144
|
+
} else {
|
|
145
|
+
vec2 mouseOffset = mouseNorm * 0.1 * uMouseActiveFactor;
|
|
146
|
+
uv += mouseOffset;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
float autoRotAngle = uTime * uRotationSpeed;
|
|
150
|
+
mat2 autoRot = mat2(cos(autoRotAngle), -sin(autoRotAngle), sin(autoRotAngle), cos(autoRotAngle));
|
|
151
|
+
uv = autoRot * uv;
|
|
152
|
+
uv = mat2(uRotation.x, -uRotation.y, uRotation.y, uRotation.x) * uv;
|
|
153
|
+
|
|
154
|
+
vec3 col = vec3(0.0);
|
|
155
|
+
for (float i = 0.0; i < 1.0; i += 1.0 / NUM_LAYER) {
|
|
156
|
+
float depth = fract(i + uStarSpeed * uSpeed);
|
|
157
|
+
float scale = mix(20.0 * uDensity, 0.5 * uDensity, depth);
|
|
158
|
+
float fade = depth * smoothstep(1.0, 0.9, depth);
|
|
159
|
+
col += StarLayer(uv * scale + i * 453.32) * fade;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (uTransparent) {
|
|
163
|
+
float alpha = smoothstep(0.0, 0.3, length(col));
|
|
164
|
+
gl_FragColor = vec4(col, min(alpha, 1.0));
|
|
165
|
+
} else {
|
|
166
|
+
gl_FragColor = vec4(col, 1.0);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
const params = {
|
|
172
|
+
focal: [0.5, 0.5],
|
|
173
|
+
rotation: [1.0, 0.0],
|
|
174
|
+
starSpeed: 2.0,
|
|
175
|
+
density: 2.0,
|
|
176
|
+
hueShift: 140.0,
|
|
177
|
+
speed: 0.5,
|
|
178
|
+
glowIntensity: 0.2,
|
|
179
|
+
saturation: 0.1,
|
|
180
|
+
mouseRepulsion: true,
|
|
181
|
+
twinkleIntensity: 0.1,
|
|
182
|
+
rotationSpeed: 0.1,
|
|
183
|
+
repulsionStrength: 0.1,
|
|
184
|
+
autoCenterRepulsion: 0.0,
|
|
185
|
+
transparent: true
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
function createShader(gl, type, source) {
|
|
189
|
+
const shader = gl.createShader(type);
|
|
190
|
+
gl.shaderSource(shader, source);
|
|
191
|
+
gl.compileShader(shader);
|
|
192
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
193
|
+
const message = gl.getShaderInfoLog(shader) || 'Unknown shader compilation error';
|
|
194
|
+
gl.deleteShader(shader);
|
|
195
|
+
throw new Error(message);
|
|
196
|
+
}
|
|
197
|
+
return shader;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function createProgram(gl) {
|
|
201
|
+
const vertex = createShader(gl, gl.VERTEX_SHADER, vertexShader);
|
|
202
|
+
const fragment = createShader(gl, gl.FRAGMENT_SHADER, fragmentShader);
|
|
203
|
+
const program = gl.createProgram();
|
|
204
|
+
gl.attachShader(program, vertex);
|
|
205
|
+
gl.attachShader(program, fragment);
|
|
206
|
+
gl.linkProgram(program);
|
|
207
|
+
gl.deleteShader(vertex);
|
|
208
|
+
gl.deleteShader(fragment);
|
|
209
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
210
|
+
const message = gl.getProgramInfoLog(program) || 'Unknown WebGL program link error';
|
|
211
|
+
gl.deleteProgram(program);
|
|
212
|
+
throw new Error(message);
|
|
213
|
+
}
|
|
214
|
+
return program;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function uniformLocations(gl, program) {
|
|
218
|
+
const names = [
|
|
219
|
+
'uTime', 'uResolution', 'uFocal', 'uRotation', 'uStarSpeed', 'uDensity',
|
|
220
|
+
'uHueShift', 'uSpeed', 'uMouse', 'uGlowIntensity', 'uSaturation',
|
|
221
|
+
'uMouseRepulsion', 'uTwinkleIntensity', 'uRotationSpeed',
|
|
222
|
+
'uRepulsionStrength', 'uMouseActiveFactor', 'uAutoCenterRepulsion',
|
|
223
|
+
'uTransparent'
|
|
224
|
+
];
|
|
225
|
+
const result = {};
|
|
226
|
+
names.forEach(function (name) {
|
|
227
|
+
result[name] = gl.getUniformLocation(program, name);
|
|
228
|
+
});
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function mount(canvas) {
|
|
233
|
+
if (!canvas || canvas.dataset.galaxyMounted === 'true') return;
|
|
234
|
+
|
|
235
|
+
const background = canvas.parentElement;
|
|
236
|
+
const interactionTarget = canvas.closest('.wiki-hero') || background;
|
|
237
|
+
if (!background || !interactionTarget) return;
|
|
238
|
+
|
|
239
|
+
let gl;
|
|
240
|
+
try {
|
|
241
|
+
gl = canvas.getContext('webgl', {
|
|
242
|
+
alpha: params.transparent,
|
|
243
|
+
antialias: false,
|
|
244
|
+
premultipliedAlpha: false,
|
|
245
|
+
powerPreference: 'high-performance'
|
|
246
|
+
});
|
|
247
|
+
} catch (e) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (!gl) return;
|
|
251
|
+
|
|
252
|
+
let program;
|
|
253
|
+
try {
|
|
254
|
+
program = createProgram(gl);
|
|
255
|
+
} catch (e) {
|
|
256
|
+
const loseContext = gl.getExtension('WEBGL_lose_context');
|
|
257
|
+
if (loseContext) loseContext.loseContext();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
canvas.dataset.galaxyMounted = 'true';
|
|
262
|
+
const locations = uniformLocations(gl, program);
|
|
263
|
+
const position = gl.getAttribLocation(program, 'position');
|
|
264
|
+
const buffer = gl.createBuffer();
|
|
265
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
266
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
267
|
+
-1.0, -1.0,
|
|
268
|
+
3.0, -1.0,
|
|
269
|
+
-1.0, 3.0
|
|
270
|
+
]), gl.STATIC_DRAW);
|
|
271
|
+
gl.enableVertexAttribArray(position);
|
|
272
|
+
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
|
|
273
|
+
gl.useProgram(program);
|
|
274
|
+
|
|
275
|
+
gl.enable(gl.BLEND);
|
|
276
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
277
|
+
gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
|
278
|
+
|
|
279
|
+
gl.uniform2f(locations.uFocal, params.focal[0], params.focal[1]);
|
|
280
|
+
gl.uniform2f(locations.uRotation, params.rotation[0], params.rotation[1]);
|
|
281
|
+
gl.uniform1f(locations.uDensity, params.density);
|
|
282
|
+
gl.uniform1f(locations.uHueShift, params.hueShift);
|
|
283
|
+
gl.uniform1f(locations.uSpeed, params.speed);
|
|
284
|
+
gl.uniform1f(locations.uGlowIntensity, params.glowIntensity);
|
|
285
|
+
gl.uniform1f(locations.uSaturation, params.saturation);
|
|
286
|
+
gl.uniform1i(locations.uMouseRepulsion, params.mouseRepulsion ? 1 : 0);
|
|
287
|
+
gl.uniform1f(locations.uTwinkleIntensity, params.twinkleIntensity);
|
|
288
|
+
gl.uniform1f(locations.uRotationSpeed, params.rotationSpeed);
|
|
289
|
+
gl.uniform1f(locations.uRepulsionStrength, params.repulsionStrength);
|
|
290
|
+
gl.uniform1f(locations.uAutoCenterRepulsion, params.autoCenterRepulsion);
|
|
291
|
+
gl.uniform1i(locations.uTransparent, params.transparent ? 1 : 0);
|
|
292
|
+
|
|
293
|
+
const targetMouse = { x: 0.5, y: 0.5 };
|
|
294
|
+
const smoothMouse = { x: 0.5, y: 0.5 };
|
|
295
|
+
let targetMouseActive = 0.0;
|
|
296
|
+
let smoothMouseActive = 0.0;
|
|
297
|
+
let animationFrame = null;
|
|
298
|
+
let isInViewport = true;
|
|
299
|
+
let isDestroyed = false;
|
|
300
|
+
|
|
301
|
+
function resize() {
|
|
302
|
+
const rect = background.getBoundingClientRect();
|
|
303
|
+
const width = Math.max(1, Math.round(rect.width));
|
|
304
|
+
const height = Math.max(1, Math.round(rect.height));
|
|
305
|
+
if (canvas.width !== width || canvas.height !== height) {
|
|
306
|
+
canvas.width = width;
|
|
307
|
+
canvas.height = height;
|
|
308
|
+
gl.viewport(0, 0, width, height);
|
|
309
|
+
gl.uniform3f(locations.uResolution, width, height, width / height);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function shouldRender() {
|
|
314
|
+
return !isDestroyed && isInViewport && !document.hidden;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function render(time) {
|
|
318
|
+
animationFrame = null;
|
|
319
|
+
if (!shouldRender()) return;
|
|
320
|
+
|
|
321
|
+
const seconds = time * 0.001;
|
|
322
|
+
const lerpFactor = 0.05;
|
|
323
|
+
smoothMouse.x += (targetMouse.x - smoothMouse.x) * lerpFactor;
|
|
324
|
+
smoothMouse.y += (targetMouse.y - smoothMouse.y) * lerpFactor;
|
|
325
|
+
smoothMouseActive += (targetMouseActive - smoothMouseActive) * lerpFactor;
|
|
326
|
+
|
|
327
|
+
gl.uniform1f(locations.uTime, seconds);
|
|
328
|
+
gl.uniform1f(locations.uStarSpeed, seconds * params.starSpeed / 10.0);
|
|
329
|
+
gl.uniform2f(locations.uMouse, smoothMouse.x, smoothMouse.y);
|
|
330
|
+
gl.uniform1f(locations.uMouseActiveFactor, smoothMouseActive);
|
|
331
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
332
|
+
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
333
|
+
animationFrame = window.requestAnimationFrame(render);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function start() {
|
|
337
|
+
if (shouldRender() && animationFrame === null) {
|
|
338
|
+
animationFrame = window.requestAnimationFrame(render);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function stop() {
|
|
343
|
+
if (animationFrame !== null) {
|
|
344
|
+
window.cancelAnimationFrame(animationFrame);
|
|
345
|
+
animationFrame = null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function handleMouseMove(event) {
|
|
350
|
+
const rect = background.getBoundingClientRect();
|
|
351
|
+
if (rect.width <= 0 || rect.height <= 0) return;
|
|
352
|
+
targetMouse.x = (event.clientX - rect.left) / rect.width;
|
|
353
|
+
targetMouse.y = 1.0 - (event.clientY - rect.top) / rect.height;
|
|
354
|
+
targetMouseActive = 1.0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function handleMouseLeave() {
|
|
358
|
+
targetMouseActive = 0.0;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function handleVisibilityChange() {
|
|
362
|
+
if (document.hidden) {
|
|
363
|
+
stop();
|
|
364
|
+
} else {
|
|
365
|
+
start();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
interactionTarget.addEventListener('mousemove', handleMouseMove);
|
|
370
|
+
interactionTarget.addEventListener('mouseleave', handleMouseLeave);
|
|
371
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
372
|
+
|
|
373
|
+
let resizeObserver = null;
|
|
374
|
+
if (window.ResizeObserver) {
|
|
375
|
+
resizeObserver = new window.ResizeObserver(resize);
|
|
376
|
+
resizeObserver.observe(background);
|
|
377
|
+
} else {
|
|
378
|
+
window.addEventListener('resize', resize);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
let viewportObserver = null;
|
|
382
|
+
if (window.IntersectionObserver) {
|
|
383
|
+
viewportObserver = new window.IntersectionObserver(function (entries) {
|
|
384
|
+
isInViewport = entries[0].isIntersecting;
|
|
385
|
+
if (isInViewport) {
|
|
386
|
+
start();
|
|
387
|
+
} else {
|
|
388
|
+
stop();
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
viewportObserver.observe(background);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function destroy() {
|
|
395
|
+
if (isDestroyed) return;
|
|
396
|
+
isDestroyed = true;
|
|
397
|
+
stop();
|
|
398
|
+
interactionTarget.removeEventListener('mousemove', handleMouseMove);
|
|
399
|
+
interactionTarget.removeEventListener('mouseleave', handleMouseLeave);
|
|
400
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
401
|
+
window.removeEventListener('resize', resize);
|
|
402
|
+
window.removeEventListener('pagehide', destroy);
|
|
403
|
+
if (resizeObserver) resizeObserver.disconnect();
|
|
404
|
+
if (viewportObserver) viewportObserver.disconnect();
|
|
405
|
+
gl.deleteBuffer(buffer);
|
|
406
|
+
gl.deleteProgram(program);
|
|
407
|
+
const loseContext = gl.getExtension('WEBGL_lose_context');
|
|
408
|
+
if (loseContext) loseContext.loseContext();
|
|
409
|
+
delete canvas.dataset.galaxyMounted;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
window.addEventListener('pagehide', destroy);
|
|
413
|
+
resize();
|
|
414
|
+
start();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
window.stellar = window.stellar || {};
|
|
418
|
+
window.stellar.galaxy = {
|
|
419
|
+
mountAll: function (canvases) {
|
|
420
|
+
Array.prototype.forEach.call(canvases || [], mount);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
})();
|
|
@@ -17,7 +17,7 @@ utils.js(window.searchConfig.js).then(() => {
|
|
|
17
17
|
|
|
18
18
|
function displayResults(hits) {
|
|
19
19
|
var resultList = document.createElement("ul");
|
|
20
|
-
resultList.classList.add("search-result-list");
|
|
20
|
+
resultList.classList.add("search-result-list", "ui-collection-adapter");
|
|
21
21
|
if (hits.length === 0) {
|
|
22
22
|
searchWrapper.classList.add('noresult');
|
|
23
23
|
} else {
|
|
@@ -276,7 +276,7 @@ var searchFunc = function(path, filter, wrapperId, searchId, contentId) {
|
|
|
276
276
|
});
|
|
277
277
|
|
|
278
278
|
const ul = document.createElement('ul');
|
|
279
|
-
ul.className = 'search-result-list';
|
|
279
|
+
ul.className = 'search-result-list ui-collection-adapter';
|
|
280
280
|
resultList.forEach(function(item) {
|
|
281
281
|
ul.appendChild(item.element);
|
|
282
282
|
});
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
if (api == null) {
|
|
7
7
|
continue;
|
|
8
8
|
}
|
|
9
|
+
const isWikiStars = el.classList.contains('wiki-stars');
|
|
10
|
+
const isWikiRelease = el.classList.contains('wiki-cover-release');
|
|
9
11
|
// layout
|
|
10
|
-
utils.request(null, api, async resp => {
|
|
12
|
+
utils.request(isWikiStars ? el : null, api, async resp => {
|
|
11
13
|
const data = await resp.json();
|
|
12
14
|
function fill(data) {
|
|
13
15
|
for (let key of Object.keys(data)) {
|
|
@@ -17,8 +19,8 @@
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
const idx = el.getAttribute('index');
|
|
22
|
+
const arr = data.content || data;
|
|
20
23
|
if (idx != undefined) {
|
|
21
|
-
const arr = data.content || data;
|
|
22
24
|
if (arr && arr.length > idx) {
|
|
23
25
|
let obj = arr[idx];
|
|
24
26
|
obj['latest-tag-name'] = obj['name'];
|
|
@@ -27,6 +29,32 @@
|
|
|
27
29
|
} else {
|
|
28
30
|
fill(data);
|
|
29
31
|
}
|
|
30
|
-
|
|
32
|
+
if (isWikiStars && data.stargazers_count != null) {
|
|
33
|
+
el.classList.add('loaded');
|
|
34
|
+
}
|
|
35
|
+
if (isWikiRelease) {
|
|
36
|
+
const tag = el.querySelector('#latest-tag-name');
|
|
37
|
+
if (tag && tag.textContent) {
|
|
38
|
+
const value = el.querySelector('.wiki-cover-release-value');
|
|
39
|
+
const item = arr && arr.length > idx ? arr[idx] : data;
|
|
40
|
+
const repo = el.dataset.repo;
|
|
41
|
+
const url = item && item.html_url || repo && 'https://github.com/' + repo.split('/').map(encodeURIComponent).join('/') + '/tree/' + encodeURIComponent(tag.textContent);
|
|
42
|
+
if (!url) {
|
|
43
|
+
el.remove();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
value.textContent = el.dataset.projectName + ' ' + tag.textContent;
|
|
47
|
+
el.href = url;
|
|
48
|
+
el.classList.remove('is-loading');
|
|
49
|
+
el.classList.add('loaded');
|
|
50
|
+
} else {
|
|
51
|
+
el.remove();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, () => {
|
|
55
|
+
if (isWikiStars || isWikiRelease) {
|
|
56
|
+
el.remove();
|
|
57
|
+
}
|
|
58
|
+
}).catch(() => {});
|
|
31
59
|
}
|
|
32
60
|
})();
|
|
@@ -34,3 +34,29 @@ function setCardLink(nodes) {
|
|
|
34
34
|
}, undefined, { service: 'siteinfo' });
|
|
35
35
|
})
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
function setSiteCardIcon(nodes) {
|
|
39
|
+
nodes = 'forEach' in (nodes || {}) ? nodes : document.querySelectorAll('.site-card .card-link[data-siteinfo-api]')
|
|
40
|
+
nodes.forEach((el) => {
|
|
41
|
+
if (el.nodeType !== 1) return;
|
|
42
|
+
const api = el.dataset.siteinfoApi;
|
|
43
|
+
if (api == null) return;
|
|
44
|
+
utils.request(null, api, function(response) {
|
|
45
|
+
return response.json().then(function(data) {
|
|
46
|
+
if (data.icon && data.icon.length > 0) {
|
|
47
|
+
const icon = el.querySelector('.siteinfo-icon');
|
|
48
|
+
if (icon) {
|
|
49
|
+
icon.src = data.icon;
|
|
50
|
+
icon.setAttribute('data-src', data.icon);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}).catch(function(error) {
|
|
54
|
+
console.error(error);
|
|
55
|
+
});
|
|
56
|
+
}, undefined, { service: 'siteinfo' });
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
window.addEventListener('stellar:sites-ready', function() {
|
|
61
|
+
setSiteCardIcon();
|
|
62
|
+
});
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
utils.request(el, api, async resp => {
|
|
13
13
|
const data = await resp.json();
|
|
14
14
|
for (let item of data.content) {
|
|
15
|
+
const siteinfoApi = !item.icon && !item.avatar && ctx.services.siteinfo?.api
|
|
16
|
+
? ctx.services.siteinfo.api.replace('{href}', item.url)
|
|
17
|
+
: '';
|
|
15
18
|
var cell = `<div class="grid-cell site-card">`;
|
|
16
|
-
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`;
|
|
19
|
+
cell += `<a class="card-link"${siteinfoApi ? ` data-siteinfo-api="${siteinfoApi}"` : ''} target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`;
|
|
17
20
|
cell += `<img src="${item.cover || item.snapshot || item.screenshot}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_cover}\';"/>`;
|
|
18
21
|
cell += `<div class="info">`;
|
|
19
|
-
cell += `<img src="${item.icon || item.avatar || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
|
22
|
+
cell += `<img class="siteinfo-icon" src="${item.icon || item.avatar || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
|
20
23
|
cell += `<span class="title">${item.title}</span>`;
|
|
21
24
|
cell += `<span class="desc">${item.description || item.url}</span>`;
|
|
22
25
|
cell += `</div>`;
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
utils.dom(el).find('.grid-box').append(cell);
|
|
37
40
|
}
|
|
38
41
|
window.wrapLazyloadImages(el);
|
|
42
|
+
window.dispatchEvent(new Event('stellar:sites-ready'));
|
|
39
43
|
});
|
|
40
44
|
}
|
|
41
45
|
})();
|
package/source/js/services.js
CHANGED
|
@@ -6,9 +6,12 @@ const initServices = () => {
|
|
|
6
6
|
const js = ctx.services[id].js;
|
|
7
7
|
if (id == 'siteinfo') {
|
|
8
8
|
const cardlinks = document.querySelectorAll('a.link-card[cardlink]');
|
|
9
|
-
|
|
9
|
+
const siteCards = document.querySelectorAll('.ds-sites, .site-card .card-link[data-siteinfo-api]');
|
|
10
|
+
if (cardlinks?.length > 0 || siteCards?.length > 0) {
|
|
10
11
|
utils.js(js, { defer: true }).then(function () {
|
|
11
|
-
|
|
12
|
+
if (cardlinks?.length > 0) {
|
|
13
|
+
setCardLink(cardlinks);
|
|
14
|
+
}
|
|
12
15
|
});
|
|
13
16
|
}
|
|
14
17
|
} else if (id == 'ghinfo') {
|
package/source/js/tagtree.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
const tagtreeConf = window.__STELLAR_TAGTREE__ || {};
|
|
3
3
|
|
|
4
|
-
const tagSwitchers = document.querySelectorAll('.tag-subtree.parent
|
|
4
|
+
const tagSwitchers = document.querySelectorAll('.tag-subtree.is-parent > a > .tag-switcher-wrapper')
|
|
5
5
|
for (const tagSwitcher of tagSwitchers) {
|
|
6
6
|
tagSwitcher.addEventListener('click', (e) => {
|
|
7
|
-
const parent = e.target.closest('.tag-subtree.parent
|
|
8
|
-
parent.classList.toggle('expanded')
|
|
7
|
+
const parent = e.target.closest('.tag-subtree.is-parent')
|
|
8
|
+
parent.classList.toggle('is-expanded')
|
|
9
9
|
e.preventDefault()
|
|
10
10
|
})
|
|
11
11
|
}
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
if (activeTag) {
|
|
17
17
|
let tag = document.querySelector(`.tag-subtree[data-tag="${activeTag}"]`)
|
|
18
18
|
if (tag) {
|
|
19
|
-
tag.querySelector('a').classList.add('active')
|
|
19
|
+
tag.querySelector('a').classList.add('is-active')
|
|
20
20
|
if (!tagtreeConf.expand_active) {
|
|
21
|
-
tag = tag.parentElement.closest('.tag-subtree.parent
|
|
21
|
+
tag = tag.parentElement.closest('.tag-subtree.is-parent')
|
|
22
22
|
}
|
|
23
23
|
while (tag) {
|
|
24
|
-
tag.classList.add('expanded')
|
|
25
|
-
tag = tag.parentElement.closest('.tag-subtree.parent
|
|
24
|
+
tag.classList.add('is-expanded')
|
|
25
|
+
tag = tag.parentElement.closest('.tag-subtree.is-parent')
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
package/source/js/utils.js
CHANGED
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
onLoading: (el) => {
|
|
300
300
|
if (el) {
|
|
301
301
|
if (el.querySelector('.loading-wrap') === null) {
|
|
302
|
-
el.insertAdjacentHTML('beforeend', `<div class="loading-wrap"
|
|
302
|
+
el.insertAdjacentHTML('beforeend', `<div class="loading-wrap"><div class="lazy-icon"></div></div>`);
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
},
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<%
|
|
2
|
-
function layoutDiv() {
|
|
3
|
-
var el = ''
|
|
4
|
-
const isActive = pretty_url(item.url) == pretty_url(page.path)
|
|
5
|
-
el += `<a class="link${isActive ? ' active' : ''}" title="${item.title}" href="${item.url}">`
|
|
6
|
-
el += `<div class="flex">`
|
|
7
|
-
if (item.icon) {
|
|
8
|
-
el += icon(item.icon)
|
|
9
|
-
}
|
|
10
|
-
if (columns <= 2) {
|
|
11
|
-
el += `<span>${item.title}</span>`
|
|
12
|
-
}
|
|
13
|
-
el += `</div>`
|
|
14
|
-
if (columns == 1 && isActive) {
|
|
15
|
-
el += '<span class="active-dot"></span>'
|
|
16
|
-
}
|
|
17
|
-
el += `</a>`
|
|
18
|
-
return el
|
|
19
|
-
}
|
|
20
|
-
%>
|
|
21
|
-
<%- layoutDiv() %>
|