快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」

[[toc]]
[toc]
次功能来自《白木》大佬,感谢大佬。❤️❤️❤️
Teek-one开箱即用版仓库:https://cnb.cool/onedayxyy/vitepress-theme-teek-one-public
白木大佬美化了teek的图片查看器,那么我这里更新一篇文章出来哦,感谢白木大佬。💖💖💖
之前效果:

美化后效果:

(1)新建docs\.vitepress\theme\style\dd-image目录,再在此目录下新建如下2个文件:
docs\.vitepress\theme\style\dd-image\dd-image.scss文件:
1// 图片查看器样式 - 基于原版美化
2body .tk-image-viewer__wrapper {
3 position: fixed;
4 top: 0;
5 left: 0;
6 width: 100%;
7 height: 100%;
8 background-color: rgba(0, 0, 0, 0.9);
9 display: flex;
10 justify-content: center;
11 align-items: center;
12 z-index: 9999;
13 cursor: pointer;
14 animation: fadeIn 0.3s ease;
15}
16
17// 图片容器样式
18body .tk-image-viewer__wrapper .tk-image-viewer__canvas {
19 max-width: 90%;
20 max-height: 80%;
21 display: flex;
22 justify-content: center;
23 align-items: center;
24 cursor: grab;
25 border-radius: 16px;
26 overflow: visible;
27 position: relative;
28}
29
30// 拖拽时的光标样式
31body .tk-image-viewer__wrapper .tk-image-viewer__canvas:active {
32 cursor: grabbing;
33}
34
35// 图片样式
36body .tk-image-viewer__wrapper .tk-image-viewer__canvas img {
37 max-width: 100%;
38 max-height: 100%;
39 object-fit: contain;
40 transition:
41 opacity 0.2s ease,
42 transform 0.3s ease,
43 border-radius 0.3s ease;
44 transform: none;
45 border-radius: 16px;
46 position: relative;
47 cursor: inherit;
48}
49
50// 关闭按钮样式
51body .tk-image-viewer__wrapper .tk-image-viewer__close {
52 position: absolute;
53 top: 20px;
54 right: 20px;
55 background: rgba(0, 47, 255, 0.582);
56 border: 2px solid rgba(0, 255, 242, 0.3);
57 border-radius: 50%;
58 padding: 12px;
59 font-size: 20px;
60 color: white;
61 cursor: pointer;
62 transition: all 0.3s ease;
63 display: flex;
64 justify-content: center;
65 align-items: center;
66 z-index: 1000;
67}
68
69// 关闭按钮悬停效果
70body .tk-image-viewer__wrapper .tk-image-viewer__close:hover {
71 background: rgba(255, 0, 234, 0.5);
72 transform: scale(1.1);
73}
74
75// 关闭按钮聚焦效果
76body .tk-image-viewer__wrapper .tk-image-viewer__close:focus {
77 outline: none;
78 box-shadow: 0 0 0 3px rgba(255, 0, 234, 0.5);
79}
80
81// 关闭按钮图标样式
82body .tk-image-viewer__wrapper .tk-image-viewer__close .tk-icon {
83 color: rgb(255, 255, 255);
84 font-size: 20px;
85 line-height: 1;
86}
87
88// 图片缩放按钮容器样式
89body .tk-image-viewer__wrapper .tk-image-viewer__actions {
90 position: absolute;
91 left: 50%;
92 bottom: 30px;
93 transform: translateX(-50%);
94 background: rgba(0, 0, 0, 0.7);
95 border-radius: 30px;
96 padding: 10px 20px;
97 display: flex;
98 gap: 10px;
99 flex-wrap: nowrap;
100 justify-content: center;
101 align-items: center;
102 min-width: fit-content;
103 white-space: nowrap;
104 overflow: visible;
105 z-index: 100;
106}
107
108body .tk-image-viewer__wrapper .tk-image-viewer__actions::-webkit-scrollbar {
109 display: none;
110}
111
112// 底部的功能按钮样式
113body .tk-image-viewer__wrapper .tk-image-viewer__btn {
114 background: rgba(0, 38, 255, 0.1); // 背景色
115 border: 2px solid rgba(0, 204, 255, 0.295); // 边框颜色
116 border-radius: 50%;
117 padding: 8px;
118 width: 36px;
119 height: 36px;
120 font-size: 16px;
121 color: white;
122 cursor: pointer;
123 transition: all 0.3s ease;
124 display: flex;
125 align-items: center;
126 justify-content: center;
127 flex-shrink: 0;
128 position: relative;
129 z-index: 1;
130}
131
132// 缩放按钮样式
133body .tk-image-viewer__wrapper .tk-image-viewer__zoom {
134 @extend .tk-image-viewer__btn;
135}
136
137// 按钮悬停效果
138body .tk-image-viewer__wrapper .tk-image-viewer__btn:hover,
139body .tk-image-viewer__wrapper .tk-image-viewer__zoom:hover {
140 background: rgba(255, 0, 234, 0.5);
141 transform: scale(1.1);
142}
143
144// 按钮聚焦效果
145body .tk-image-viewer__wrapper .tk-image-viewer__btn:focus,
146body .tk-image-viewer__wrapper .tk-image-viewer__zoom:focus {
147 outline: none;
148 box-shadow: 0 0 0 3px rgba(255, 0, 234, 0.5);
149}
150
151// 按钮点击激活状态
152body .tk-image-viewer__wrapper .tk-image-viewer__btn--active {
153 transform: scale(0.95);
154 background: rgba(255, 0, 234, 0.5);
155}
156
157// 缩放按钮点击激活状态
158body .tk-image-viewer__wrapper .tk-image-viewer__zoom--active {
159 transform: scale(0.95);
160 background: rgba(255, 0, 234, 0.5);
161}
162
163// 缩放按钮激活状态图标样式
164body .tk-image-viewer__wrapper .tk-image-viewer__zoom--active .tk-icon {
165 color: #4caf50;
166}
167
168// 图标样式
169body .tk-image-viewer__wrapper .tk-icon {
170 font-size: inherit;
171 display: flex;
172 align-items: center;
173 justify-content: center;
174 font-style: normal !important;
175 color: white;
176 line-height: 1;
177 margin: 0;
178 padding: 0;
179 font-family: inherit;
180 font-weight: inherit;
181 text-align: center;
182 vertical-align: middle;
183 max-width: 100%;
184 max-height: 100%;
185 vertical-align: baseline;
186}
187
188// 图片计数样式
189body .tk-image-viewer__wrapper .tk-image-viewer__info {
190 position: absolute;
191 bottom: 100px;
192 left: 50%;
193 transform: translateX(-50%);
194 background: rgba(0, 0, 0, 0.7);
195 color: white;
196 padding: 8px 16px;
197 border-radius: 20px;
198 font-size: 14px;
199 font-family: Arial, sans-serif;
200 min-width: 60px;
201 text-align: center;
202}
203
204// 动画样式
205@keyframes fadeIn {
206 from {
207 opacity: 0;
208 }
209 to {
210 opacity: 1;
211 }
212}
213
214@keyframes fadeOut {
215 from {
216 opacity: 1;
217 }
218 to {
219 opacity: 0;
220 }
221}
222
223// 淡出动画类
224body .tk-image-viewer__wrapper--fade-out {
225 animation: fadeOut 0.3s ease;
226}
227
228// 响应式
229@media (max-width: 768px) {
230 body .tk-image-viewer__wrapper .tk-image-viewer__canvas {
231 cursor: grab;
232 }
233
234 body .tk-image-viewer__wrapper .tk-image-viewer__canvas:active {
235 cursor: grabbing;
236 }
237
238 body .tk-image-viewer__wrapper .tk-image-viewer__actions {
239 gap: 10px;
240 padding: 8px 15px;
241 bottom: 20px;
242 }
243
244 body .tk-image-viewer__wrapper .tk-image-viewer__btn,
245 body .tk-image-viewer__wrapper .tk-image-viewer__zoom {
246 padding: 8px;
247 font-size: 18px;
248 min-width: 36px;
249 min-height: 36px;
250 }
251
252 body .tk-image-viewer__wrapper .tk-image-viewer__close {
253 padding: 10px;
254 font-size: 18px;
255 top: 15px;
256 right: 15px;
257 }
258
259 body .tk-image-viewer__wrapper .tk-image-viewer__info {
260 bottom: 80px;
261 font-size: 12px;
262 padding: 6px 12px;
263 }
264}docs\.vitepress\theme\style\dd-image\dd-image.ts文件:
1// 图片查看器功能实现
2// 图片查看器类
3class ImageViewer {
4 private viewerWrapper: HTMLElement | null = null;
5 private canvas: HTMLElement | null = null;
6 private closeBtn: HTMLElement | null = null;
7 private rotateBtn: HTMLElement | null = null;
8 private prevBtn: HTMLElement | null = null;
9 private nextBtn: HTMLElement | null = null;
10 private fullScreenBtn: HTMLElement | null = null;
11 private originalSizeBtn: HTMLElement | null = null;
12 private zoomInBtn: HTMLElement | null = null;
13 private zoomOutBtn: HTMLElement | null = null;
14 private currentImg: HTMLImageElement | null = null;
15 private imgList: string[] = [];
16 private currentIndex: number = 0;
17 private scale: number = 1;
18 private rotation: number = 0;
19 private isFullScreen: boolean = false;
20 private isDragging: boolean = false;
21 private dragStartX: number = 0;
22 private dragStartY: number = 0;
23 private translateX: number = 0;
24 private translateY: number = 0;
25
26 constructor() {
27 this.init();
28 }
29
30 private init() {
31 if (typeof window === "undefined") return;
32
33 if (document.readyState === "loading") {
34 document.addEventListener("DOMContentLoaded", this.setupImageListeners.bind(this));
35 } else {
36 this.setupImageListeners();
37 }
38
39 this.observeDOMChanges();
40 }
41
42 private setupImageListeners() {
43 const vpDocElement = document.querySelector(".vp-doc");
44 if (vpDocElement) {
45 const images = vpDocElement.querySelectorAll("img:not(.tk-image-viewer__canvas img)");
46 images.forEach(img => {
47 const htmlImg = img as HTMLImageElement;
48 if (!htmlImg.dataset.imageViewerInitialized) {
49 htmlImg.dataset.imageViewerInitialized = "true";
50 htmlImg.style.cursor = "pointer";
51 htmlImg.addEventListener("click", (e: MouseEvent) => this.handleImageClick(e, htmlImg));
52 }
53 });
54 }
55 }
56
57 private observeDOMChanges() {
58 const observer = new MutationObserver(() => {
59 this.setupImageListeners();
60 });
61
62 observer.observe(document.body, {
63 childList: true,
64 subtree: true,
65 });
66 }
67
68 private handleImageClick(event: MouseEvent, img: HTMLImageElement) {
69 event.stopPropagation();
70
71 this.collectImages();
72 this.currentIndex = this.imgList.findIndex(src => src === img.src);
73
74 this.createViewer(img.src);
75 }
76
77 // 只收集内容区域中的图片
78 private collectImages() {
79 this.imgList = [];
80 const vpDocElement = document.querySelector(".vp-doc");
81 if (vpDocElement) {
82 const images = vpDocElement.querySelectorAll("img:not(.tk-image-viewer__canvas img)");
83 images.forEach(img => {
84 this.imgList.push((img as HTMLImageElement).src);
85 });
86 }
87 }
88
89 private createViewer(src: string) {
90 this.removeViewer();
91
92 this.viewerWrapper = document.createElement("div");
93 this.viewerWrapper.className = "tk-image-viewer__wrapper";
94
95 this.canvas = document.createElement("div");
96 this.canvas.className = "tk-image-viewer__canvas";
97
98 const viewerImg = document.createElement("img");
99 viewerImg.src = src;
100 viewerImg.style.transform = "none";
101 this.currentImg = viewerImg;
102
103 this.closeBtn = document.createElement("button");
104 this.closeBtn.className = "tk-image-viewer__close";
105 this.closeBtn.innerHTML = '<i class="tk-icon">❌</i>';
106
107 const actionsContainer = document.createElement("div");
108 actionsContainer.className = "tk-image-viewer__actions";
109
110 this.rotateBtn = document.createElement("button");
111 this.rotateBtn.className = "tk-image-viewer__btn";
112 this.rotateBtn.innerHTML = '<i class="tk-icon">🔄</i>';
113
114 this.prevBtn = document.createElement("button");
115 this.prevBtn.className = "tk-image-viewer__btn";
116 this.prevBtn.innerHTML = '<i class="tk-icon">⬅️</i>';
117
118 this.zoomOutBtn = document.createElement("button");
119 this.zoomOutBtn.className = "tk-image-viewer__btn";
120 this.zoomOutBtn.innerHTML = '<i class="tk-icon">➖</i>';
121
122 this.fullScreenBtn = document.createElement("button");
123 this.fullScreenBtn.className = "tk-image-viewer__btn";
124 this.fullScreenBtn.innerHTML = '<i class="tk-icon">🔳</i>';
125
126 this.originalSizeBtn = document.createElement("button");
127 this.originalSizeBtn.className = "tk-image-viewer__btn";
128 this.originalSizeBtn.innerHTML = '<i class="tk-icon">🔍</i>';
129
130 this.zoomInBtn = document.createElement("button");
131 this.zoomInBtn.className = "tk-image-viewer__btn";
132 this.zoomInBtn.innerHTML = '<i class="tk-icon">➕</i>';
133
134 this.nextBtn = document.createElement("button");
135 this.nextBtn.className = "tk-image-viewer__btn";
136 this.nextBtn.innerHTML = '<i class="tk-icon">➡️</i>';
137
138 // 🚀底部功能操作按钮排序
139 actionsContainer.appendChild(this.prevBtn);
140 actionsContainer.appendChild(this.nextBtn);
141 actionsContainer.appendChild(this.zoomInBtn);
142 actionsContainer.appendChild(this.zoomOutBtn);
143 actionsContainer.appendChild(this.fullScreenBtn);
144 actionsContainer.appendChild(this.rotateBtn);
145 actionsContainer.appendChild(this.originalSizeBtn);
146
147 const infoContainer = document.createElement("div");
148 infoContainer.className = "tk-image-viewer__info";
149 infoContainer.textContent = `${this.currentIndex + 1} / ${this.imgList.length}`;
150 (this.viewerWrapper as any).infoContainer = infoContainer;
151
152 this.canvas.appendChild(viewerImg);
153 this.viewerWrapper.appendChild(this.canvas);
154 this.viewerWrapper.appendChild(this.closeBtn);
155 this.viewerWrapper.appendChild(actionsContainer);
156 this.viewerWrapper.appendChild(infoContainer);
157
158 document.body.appendChild(this.viewerWrapper);
159
160 this.addViewerEventListeners(viewerImg);
161 }
162
163 private addViewerEventListeners(img: HTMLImageElement) {
164 if (!this.viewerWrapper || !this.canvas || !this.closeBtn) return;
165
166 this.scale = 1;
167 this.rotation = 0;
168 this.isFullScreen = false;
169
170 const scaleStep = 0.1;
171 const maxScale = 3;
172 const minScale = 0.5;
173 const rotateStep = 90;
174
175 const updateTransform = () => {
176 img.style.transform = `translate(${this.translateX}px, ${this.translateY}px) scale(${this.scale}) rotate(${this.rotation}deg)`;
177 };
178
179 img.addEventListener("click", (e: MouseEvent) => {
180 e.stopPropagation();
181 });
182
183 const handleDragStart = (e: MouseEvent) => {
184 e.stopPropagation();
185 this.isDragging = true;
186 this.dragStartX = e.clientX - this.translateX;
187 this.dragStartY = e.clientY - this.translateY;
188 document.body.style.userSelect = "none";
189 };
190
191 const handleDragMove = (e: MouseEvent) => {
192 if (!this.isDragging) return;
193 this.translateX = e.clientX - this.dragStartX;
194 this.translateY = e.clientY - this.dragStartY;
195 updateTransform();
196 };
197
198 const handleDragEnd = () => {
199 this.isDragging = false;
200 document.body.style.userSelect = "";
201 };
202
203 img.addEventListener("mousedown", handleDragStart);
204 document.addEventListener("mousemove", handleDragMove);
205 document.addEventListener("mouseup", handleDragEnd);
206 document.addEventListener("mouseleave", handleDragEnd);
207
208 const handleTouchStart = (e: TouchEvent) => {
209 const touch = e.touches[0];
210 e.stopPropagation();
211 this.isDragging = true;
212 this.dragStartX = touch.clientX - this.translateX;
213 this.dragStartY = touch.clientY - this.translateY;
214 document.body.style.userSelect = "none";
215 };
216
217 const handleTouchMove = (e: TouchEvent) => {
218 if (!this.isDragging || e.touches.length !== 1) return;
219 const touch = e.touches[0];
220 this.translateX = touch.clientX - this.dragStartX;
221 this.translateY = touch.clientY - this.dragStartY;
222 updateTransform();
223 };
224
225 const handleTouchEnd = () => {
226 this.isDragging = false;
227 document.body.style.userSelect = "";
228 };
229
230 img.addEventListener("touchstart", handleTouchStart, { passive: false });
231 document.addEventListener("touchmove", handleTouchMove, { passive: false });
232 document.addEventListener("touchend", handleTouchEnd);
233 document.addEventListener("touchcancel", handleTouchEnd);
234
235 this.viewerWrapper.addEventListener("click", () => {
236 this.removeViewer();
237 });
238
239 this.closeBtn.addEventListener("click", (e: MouseEvent) => {
240 e.stopPropagation();
241 this.removeViewer();
242 });
243
244 if (this.rotateBtn) {
245 const rotateBtnRef = this.rotateBtn;
246 this.rotateBtn.addEventListener("click", (e: MouseEvent) => {
247 e.stopPropagation();
248 this.rotation = (this.rotation + rotateStep) % 360;
249 updateTransform();
250 rotateBtnRef.classList.add("tk-image-viewer__btn--active");
251 setTimeout(() => {
252 rotateBtnRef.classList.remove("tk-image-viewer__btn--active");
253 }, 200);
254 });
255 }
256
257 this.prevBtn!.addEventListener("click", (e: MouseEvent) => {
258 e.stopPropagation();
259 if (this.imgList.length > 1) {
260 this.currentIndex = (this.currentIndex - 1 + this.imgList.length) % this.imgList.length;
261 this.switchImage(this.imgList[this.currentIndex]);
262 this.prevBtn!.classList.add("tk-image-viewer__btn--active");
263 setTimeout(() => {
264 this.prevBtn!.classList.remove("tk-image-viewer__btn--active");
265 }, 200);
266 }
267 });
268
269 this.nextBtn!.addEventListener("click", (e: MouseEvent) => {
270 e.stopPropagation();
271 if (this.imgList.length > 1) {
272 this.currentIndex = (this.currentIndex + 1) % this.imgList.length;
273 this.switchImage(this.imgList[this.currentIndex]);
274 this.nextBtn!.classList.add("tk-image-viewer__btn--active");
275 setTimeout(() => {
276 this.nextBtn!.classList.remove("tk-image-viewer__btn--active");
277 }, 200);
278 }
279 });
280
281 if (this.fullScreenBtn) {
282 const fullScreenBtnRef = this.fullScreenBtn;
283 this.fullScreenBtn.addEventListener("click", (e: MouseEvent) => {
284 e.stopPropagation();
285 this.isFullScreen = !this.isFullScreen;
286 if (this.isFullScreen) {
287 img.style.maxWidth = "none";
288 img.style.maxHeight = "none";
289 fullScreenBtnRef.innerHTML = '<i class="tk-icon">🔲</i>';
290 } else {
291 img.style.maxWidth = "100%";
292 img.style.maxHeight = "100%";
293 fullScreenBtnRef.innerHTML = '<i class="tk-icon">🔳</i>';
294 }
295 fullScreenBtnRef.classList.add("tk-image-viewer__btn--active");
296 setTimeout(() => {
297 fullScreenBtnRef.classList.remove("tk-image-viewer__btn--active");
298 }, 200);
299 });
300 }
301
302 if (this.originalSizeBtn) {
303 const originalSizeBtnRef = this.originalSizeBtn;
304 this.originalSizeBtn.addEventListener("click", (e: MouseEvent) => {
305 e.stopPropagation();
306 this.scale = 1;
307 this.rotation = 0;
308 this.translateX = 0;
309 this.translateY = 0;
310 updateTransform();
311 originalSizeBtnRef.classList.add("tk-image-viewer__btn--active");
312 setTimeout(() => {
313 originalSizeBtnRef.classList.remove("tk-image-viewer__btn--active");
314 }, 200);
315 });
316 }
317
318 if (this.zoomInBtn) {
319 const zoomInBtnRef = this.zoomInBtn;
320 this.zoomInBtn.addEventListener("click", (e: MouseEvent) => {
321 e.stopPropagation();
322 if (this.scale < maxScale) {
323 this.scale += scaleStep;
324 updateTransform();
325 zoomInBtnRef.classList.add("tk-image-viewer__btn--active");
326 setTimeout(() => {
327 zoomInBtnRef.classList.remove("tk-image-viewer__btn--active");
328 }, 200);
329 }
330 });
331 }
332
333 if (this.zoomOutBtn) {
334 const zoomOutBtnRef = this.zoomOutBtn;
335 this.zoomOutBtn.addEventListener("click", (e: MouseEvent) => {
336 e.stopPropagation();
337 if (this.scale > minScale) {
338 this.scale -= scaleStep;
339 updateTransform();
340 zoomOutBtnRef.classList.add("tk-image-viewer__btn--active");
341 setTimeout(() => {
342 zoomOutBtnRef.classList.remove("tk-image-viewer__btn--active");
343 }, 200);
344 }
345 });
346 }
347
348 const handleKeydown = (e: KeyboardEvent) => {
349 e.preventDefault();
350
351 switch (e.key) {
352 case "Escape":
353 this.removeViewer();
354 break;
355 case "+":
356 case "=":
357 if (this.scale < maxScale) {
358 this.scale += scaleStep;
359 updateTransform();
360 }
361 break;
362 case "-":
363 if (this.scale > minScale) {
364 this.scale -= scaleStep;
365 updateTransform();
366 }
367 break;
368 case "r":
369 case "R":
370 this.rotation = (this.rotation + rotateStep) % 360;
371 updateTransform();
372 break;
373 case "ArrowLeft":
374 if (this.imgList.length > 1) {
375 this.currentIndex = (this.currentIndex - 1 + this.imgList.length) % this.imgList.length;
376 this.switchImage(this.imgList[this.currentIndex]);
377 }
378 break;
379 case "ArrowRight":
380 if (this.imgList.length > 1) {
381 this.currentIndex = (this.currentIndex + 1) % this.imgList.length;
382 this.switchImage(this.imgList[this.currentIndex]);
383 }
384 break;
385 case "0":
386 this.scale = 1;
387 this.rotation = 0;
388 this.translateX = 0;
389 this.translateY = 0;
390 updateTransform();
391 break;
392 case "f":
393 case "F":
394 this.isFullScreen = !this.isFullScreen;
395 if (this.isFullScreen) {
396 img.style.maxWidth = "none";
397 img.style.maxHeight = "none";
398 if (this.fullScreenBtn) {
399 this.fullScreenBtn.innerHTML = '<i class="tk-icon">🔲</i>';
400 }
401 } else {
402 img.style.maxWidth = "100%";
403 img.style.maxHeight = "100%";
404 if (this.fullScreenBtn) {
405 this.fullScreenBtn.innerHTML = '<i class="tk-icon">🔳</i>';
406 }
407 }
408 break;
409 }
410 };
411
412 document.addEventListener("keydown", handleKeydown);
413
414 const handleWheel = (e: WheelEvent) => {
415 e.preventDefault();
416 if (e.deltaY < 0 && this.scale < maxScale) {
417 this.scale += scaleStep;
418 updateTransform();
419 } else if (e.deltaY > 0 && this.scale > minScale) {
420 this.scale -= scaleStep;
421 updateTransform();
422 }
423 };
424
425 this.viewerWrapper.addEventListener("wheel", handleWheel, { passive: false });
426
427 (this.viewerWrapper as any).keydownHandler = handleKeydown;
428 (this.viewerWrapper as any).wheelHandler = handleWheel;
429 (this.viewerWrapper as any).dragStartHandler = handleDragStart;
430 (this.viewerWrapper as any).dragMoveHandler = handleDragMove;
431 (this.viewerWrapper as any).dragEndHandler = handleDragEnd;
432 (this.viewerWrapper as any).touchStartHandler = handleTouchStart;
433 (this.viewerWrapper as any).touchMoveHandler = handleTouchMove;
434 (this.viewerWrapper as any).touchEndHandler = handleTouchEnd;
435 }
436
437 private switchImage(newSrc: string) {
438 if (!this.currentImg || !this.viewerWrapper) return;
439
440 this.currentImg.style.opacity = "0";
441
442 setTimeout(() => {
443 if (this.currentImg) {
444 this.currentImg.src = newSrc;
445 this.currentImg.style.opacity = "1";
446 this.currentImg.style.transform = `scale(${this.scale}) rotate(${this.rotation}deg)`;
447 if (this.isFullScreen) {
448 this.currentImg.style.maxWidth = "none";
449 this.currentImg.style.maxHeight = "none";
450 } else {
451 this.currentImg.style.maxWidth = "100%";
452 this.currentImg.style.maxHeight = "100%";
453 }
454 }
455
456 const infoContainer = (this.viewerWrapper as any).infoContainer;
457 if (infoContainer) {
458 infoContainer.textContent = `${this.currentIndex + 1} / ${this.imgList.length}`;
459 }
460 }, 200);
461 }
462
463 private removeViewer() {
464 if (this.viewerWrapper) {
465 const keydownHandler = (this.viewerWrapper as any).keydownHandler;
466 const wheelHandler = (this.viewerWrapper as any).wheelHandler;
467 const dragStartHandler = (this.viewerWrapper as any).dragStartHandler;
468 const dragMoveHandler = (this.viewerWrapper as any).dragMoveHandler;
469 const dragEndHandler = (this.viewerWrapper as any).dragEndHandler;
470 const touchStartHandler = (this.viewerWrapper as any).touchStartHandler;
471 const touchMoveHandler = (this.viewerWrapper as any).touchMoveHandler;
472 const touchEndHandler = (this.viewerWrapper as any).touchEndHandler;
473
474 if (keydownHandler) {
475 document.removeEventListener("keydown", keydownHandler);
476 }
477 if (wheelHandler) {
478 this.viewerWrapper.removeEventListener("wheel", wheelHandler);
479 }
480 if (dragStartHandler && this.currentImg) {
481 this.currentImg.removeEventListener("mousedown", dragStartHandler);
482 }
483 if (dragMoveHandler) {
484 document.removeEventListener("mousemove", dragMoveHandler);
485 }
486 if (dragEndHandler) {
487 document.removeEventListener("mouseup", dragEndHandler);
488 document.removeEventListener("mouseleave", dragEndHandler);
489 }
490 if (touchStartHandler && this.currentImg) {
491 this.currentImg.removeEventListener("touchstart", touchStartHandler);
492 }
493 if (touchMoveHandler) {
494 document.removeEventListener("touchmove", touchMoveHandler);
495 }
496 if (touchEndHandler) {
497 document.removeEventListener("touchend", touchEndHandler);
498 document.removeEventListener("touchcancel", touchEndHandler);
499 }
500 document.body.style.userSelect = "";
501
502 this.viewerWrapper.classList.add("tk-image-viewer__wrapper--fade-out");
503
504 setTimeout(() => {
505 if (this.viewerWrapper && this.viewerWrapper.parentNode) {
506 this.viewerWrapper.parentNode.removeChild(this.viewerWrapper);
507 }
508 this.viewerWrapper = null;
509 this.canvas = null;
510 this.closeBtn = null;
511 this.rotateBtn = null;
512 this.prevBtn = null;
513 this.nextBtn = null;
514 this.fullScreenBtn = null;
515 this.originalSizeBtn = null;
516 this.zoomInBtn = null;
517 this.zoomOutBtn = null;
518 this.currentImg = null;
519 this.imgList = [];
520 this.currentIndex = 0;
521 this.scale = 1;
522 this.rotation = 0;
523 this.isFullScreen = false;
524 this.isDragging = false;
525 this.translateX = 0;
526 this.translateY = 0;
527 }, 300);
528 }
529 }
530}
531
532// 所有样式已移至dd-image.scss
533
534export function initImageViewer() {
535 if (typeof window !== "undefined") {
536 new ImageViewer();
537 }
538}(2)引入
编辑docs\.vitepress\theme\index.ts文件:
1import { initImageViewer } from "./style/dd-image/dd-image.ts" // 引入图片查看器功能(替换原版
2
3 // 🔽 替换原版图片查看器
4 initImageViewer();具体文件,请查看开源库如下链接:
编辑docs\.vitepress\theme\style\index.scss文件:
1@use "./dd-image/dd-image.scss" as *; // 引入图片查看器样式(替换原版(3)验证

结束。
日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白