Skip to content

Commit a020119

Browse files
committed
update
1 parent d726230 commit a020119

File tree

1 file changed

+82
-8
lines changed

1 file changed

+82
-8
lines changed

static/web/lightbox.js

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
11
(function () {
2+
// ===== 1. 新增:主题判断与初始化核心函数 =====
3+
function getCurrentTheme() {
4+
const savedTheme = localStorage.getItem("meek_theme");
5+
// 手动设置为 light/dark 直接返回,auto/无设置则跟随系统
6+
if (savedTheme === 'light' || savedTheme === 'dark') {
7+
return savedTheme;
8+
}
9+
// 检测系统深色模式
10+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
11+
}
12+
13+
function initTheme() {
14+
const currentTheme = getCurrentTheme();
15+
document.documentElement.setAttribute('data-theme', currentTheme);
16+
}
17+
18+
// ===== 2. 初始化主题(先于样式创建)=====
19+
initTheme();
20+
221
class Lightbox {
322
constructor(options = {}) {
423
this.options = Object.assign({
@@ -18,21 +37,41 @@
1837
this.preloadedImages = {};
1938
this.init();
2039
}
40+
2141
init() {
2242
this.createStyles();
2343
this.createLightbox();
2444
this.bindEvents();
2545
}
46+
2647
createStyles() {
2748
const style = document.createElement('style');
49+
// ===== 关键修改:CSS 变量化 + 深浅色主题适配 =====
2850
style.textContent = `
51+
/* 基础变量(浅色默认) */
52+
:root {
53+
--lb-overlay-bg: transparent;
54+
--lb-button-bg: rgba(255, 255, 255, 0.8);
55+
--lb-button-color: #333;
56+
--lb-button-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
57+
--lb-image-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
58+
}
59+
60+
/* 深色主题变量(覆盖默认值) */
61+
:root[data-theme="dark"] {
62+
--lb-button-bg: rgba(45, 51, 59, 0.8);
63+
--lb-button-color: #adbac7;
64+
--lb-button-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
65+
--lb-image-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
66+
}
67+
2968
.lb-lightbox-overlay {
3069
position: fixed;
3170
top: 0;
3271
left: 0;
3372
width: 100%;
3473
height: 100%;
35-
background-color: transparent;
74+
background-color: var(--lb-overlay-bg);
3675
backdrop-filter: blur(5px);
3776
display: flex;
3877
justify-content: center;
@@ -42,10 +81,12 @@
4281
pointer-events: none;
4382
z-index: 10000;
4483
}
84+
4585
.lb-lightbox-overlay.active {
4686
pointer-events: auto;
4787
opacity: 1;
4888
}
89+
4990
.lb-lightbox-content-wrapper {
5091
position: relative;
5192
display: flex;
@@ -54,13 +95,15 @@
5495
width: 100%;
5596
height: 100%;
5697
}
98+
5799
.lb-lightbox-container {
58100
width: 100%;
59101
height: 100%;
60102
position: relative;
61103
transition: transform ${this.options.animationDuration}ms cubic-bezier(0.25, 0.1, 0.25, 1);
62104
overflow: hidden;
63105
}
106+
64107
.lb-lightbox-image-wrapper {
65108
display: flex;
66109
justify-content: center;
@@ -74,45 +117,52 @@
74117
bottom: 0;
75118
z-index: 1;
76119
}
120+
77121
.lb-lightbox-image {
78122
max-width: 100%;
79123
max-height: 100%;
80124
height: auto;
81125
object-fit: contain;
82126
border-radius: 16px;
83-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
127+
box-shadow: var(--lb-image-shadow);
84128
transition: transform ${this.options.animationDuration}ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity ${this.options.animationDuration}ms ease;
85129
opacity: 0;
86130
}
131+
87132
.lb-lightbox-nav, .lb-lightbox-close {
88133
position: absolute;
89-
background-color: rgba(255, 255, 255, 0.8);
90-
color: #333;
134+
background-color: var(--lb-button-bg);
135+
color: var(--lb-button-color);
91136
border: none;
92137
border-radius: 50%;
93138
cursor: pointer;
94-
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
139+
box-shadow: var(--lb-button-shadow);
95140
width: 50px;
96141
height: 50px;
97142
font-size: 30px;
98143
z-index: 2;
99144
transition: transform 0.2s ease;
100145
}
146+
101147
.lb-lightbox-nav:hover {
102148
transform: scale(1.1);
103149
}
150+
104151
.lb-lightbox-prev {
105152
left: 20px;
106153
top: calc(50% - 25px);
107154
}
155+
108156
.lb-lightbox-next {
109157
right: 20px;
110158
top: calc(50% - 25px);
111159
}
160+
112161
.lb-lightbox-close {
113162
top: 20px;
114163
right: 20px;
115164
}
165+
116166
@media (max-width: 768px) {
117167
.lb-lightbox-nav, .lb-lightbox-close {
118168
width: 40px;
@@ -123,6 +173,7 @@
123173
`;
124174
document.head.appendChild(style);
125175
}
176+
126177
createLightbox() {
127178
this.overlay = document.createElement('div');
128179
this.overlay.className = 'lb-lightbox-overlay';
@@ -153,6 +204,7 @@
153204
document.body.appendChild(this.overlay);
154205
this.closeButton.addEventListener('click', this.close.bind(this));
155206
}
207+
156208
bindEvents() {
157209
document.addEventListener('click', this.handleImageClick.bind(this), true);
158210
this.overlay.addEventListener('click', this.handleOverlayClick.bind(this));
@@ -165,6 +217,7 @@
165217
this.overlay.addEventListener('touchmove', this.handleTouchMove.bind(this));
166218
this.overlay.addEventListener('touchend', this.handleTouchEnd.bind(this));
167219
}
220+
168221
handleImageClick(event) {
169222
const clickedImage = event.target.closest('img');
170223
if (clickedImage && !this.isOpen) {
@@ -175,11 +228,13 @@
175228
this.open();
176229
}
177230
}
231+
178232
handleOverlayClick(event) {
179233
if (event.target === this.overlay && this.options.closeOnOverlayClick) {
180234
this.close();
181235
}
182236
}
237+
183238
handleKeyDown(event) {
184239
if (!this.isOpen) return;
185240
switch (event.key) {
@@ -194,6 +249,7 @@
194249
break;
195250
}
196251
}
252+
197253
handleWheel(event) {
198254
event.preventDefault();
199255

@@ -213,18 +269,22 @@
213269
}, 50);
214270
}
215271
}
272+
216273
handleTouchStart(event) {
217274
this.touchStartX = event.touches[0].clientX;
218275
}
276+
219277
handleTouchMove(event) {
220278
this.touchEndX = event.touches[0].clientX;
221279
}
280+
222281
handleTouchEnd() {
223282
const difference = this.touchStartX - this.touchEndX;
224283
if (Math.abs(difference) > 50) {
225284
difference > 0 ? this.showNextImage() : this.showPreviousImage();
226285
}
227286
}
287+
228288
open() {
229289
this.isOpen = true;
230290
this.overlay.classList.add('active');
@@ -234,6 +294,7 @@
234294
this.options.onOpen();
235295
}
236296
}
297+
237298
close() {
238299
document.body.style.overflow = '';
239300
this.overlay.classList.remove('active');
@@ -244,26 +305,30 @@
244305
}
245306
this.unbindEvents();
246307
}
308+
247309
showPreviousImage() {
248310
if (this.currentIndex > 0) {
249311
this.currentIndex--;
250312
this.showImage(this.images[this.currentIndex].src);
251313
this.resetButtonScale(this.prevButton);
252314
}
253315
}
316+
254317
showNextImage() {
255318
if (this.currentIndex < this.images.length - 1) {
256319
this.currentIndex++;
257320
this.showImage(this.images[this.currentIndex].src);
258321
this.resetButtonScale(this.nextButton);
259322
}
260323
}
324+
261325
resetButtonScale(button) {
262326
button.style.transform = 'scale(1.1)';
263327
setTimeout(() => {
264328
button.style.transform = 'scale(1)';
265329
}, 200);
266330
}
331+
267332
showImage(imgSrc) {
268333
const newImage = new Image();
269334
newImage.src = imgSrc;
@@ -280,6 +345,7 @@
280345
console.error('Failed to load image:', imgSrc);
281346
};
282347
}
348+
283349
preloadImages() {
284350
const preloadNext = this.currentIndex + 1;
285351
const preloadPrev = this.currentIndex - 1;
@@ -292,12 +358,14 @@
292358
this.preloadedImages[preloadPrev].src = this.images[preloadPrev].src;
293359
}
294360
}
361+
295362
clearPreloadedImages() {
296363
Object.keys(this.preloadedImages).forEach(key => {
297364
this.preloadedImages[key].src = '';
298365
});
299366
this.preloadedImages = {};
300367
}
368+
301369
unbindEvents() {
302370
document.removeEventListener('click', this.handleImageClick.bind(this), true);
303371
this.overlay.removeEventListener('click', this.handleOverlayClick.bind(this));
@@ -311,10 +379,16 @@
311379
this.overlay.removeEventListener('touchend', this.handleTouchEnd.bind(this));
312380
}
313381
}
382+
383+
// ===== 3. 新增:监听系统主题变化(仅auto模式生效)=====
384+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
385+
if (localStorage.getItem("meek_theme") === 'auto') {
386+
initTheme();
387+
}
388+
});
389+
314390
window.Lightbox = Lightbox;
315391
document.addEventListener('DOMContentLoaded', () => {
316392
new Lightbox();
317393
});
318-
})();
319-
320-
394+
})();

0 commit comments

Comments
 (0)