安知鱼主题魔改之index_img兼容视频展示

小桃妹のAI摘要
小桃妹酱-R1
小桃妹AI正在好好想想怎么总结主人的文章ING,请稍等片刻哦(*^▽^*)···
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
点击与桃妹聊天🍑
安知鱼主题魔改之index_img兼容视频展示
卖桃子的小女孩前言
因为看到别人的博客首页第一页就是视频,并且结合能导出的wallpaper-engine小红车的一些动态壁纸,手机端则静态壁纸用小米主题的Ai动态壁纸生成动态壁纸,然后代码检测浏览器宽度实现自适应选择性加载横竖屏壁纸
显示效果
更直观的预览效果可前往博客主页预览
实现效果以及原理
- 修改index_img相关pug自定义top / cover no-repeat默认为top 。这部分如需不同效果可自行修改
/static/index_media.css
的home-media-container
或home-media
元素 - 修改主题配置文件下的
index_img
增加path
和vpath
,横屏壁纸路径为path
,竖屏壁纸路径为vpath
,该功能实现横竖屏设备不同时加载不同横竖屏自定义壁纸,如无需区分可path
与vpath
这路径填同一个即可 - 增加主题配置文件下
index_video
,其中path
与vpath
与index_img
的填写方法类似,但增加多poster
与vposter
选项,这两个选项为视频未加载出来时的加载GIF动画,可自定义为GIF加载条或者趣味表情包加载,效果如下 path
与vpath
填对时,横屏与竖屏效果分别如下- 鼠标出现时壁纸或视频壁纸放大到105%并跟随鼠标动态放大的效果
- 首次加载主页动态壁纸或壁纸成功时壁纸从105%线性缩减为预览100%实现桌面返回时类似回弹效果
index_img
与index_video
的enable
不可同时为true
否则会报错。但可同时为false
表示关闭主页top图和动态壁纸。- 手机或竖屏状态下动态壁纸支持陀螺仪实现视差效果,但ios因系统权限获取暂不支持。
修改步骤
本次修改替换一个文件,添加两个文件,请注意备份
第一步:替换文件
- 直接覆盖
themes/anzhiyu/layout/includes/header/index.pug
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76// 优先级控制逻辑(独立作用域)
if !theme.disable_top_img && page.top_img !== false
if is_post()
- var top_img = page.top_img || page.cover || page.randomcover
else if is_page()
- var top_img = page.top_img || theme.default_top_img
else if is_home()
// 首页专用媒体声明(网页5)
- var home_index_img = theme.index_img?.enable ? theme.index_img.path : false
- var home_index_video = theme.index_video?.enable ? theme.index_video.path : false
- var top_img = home_index_img || home_index_video || theme.default_top_img
else
- var top_img = page.top_img || theme.default_top_img
if top_img !== false
// 路径处理(保留原有逻辑)
- var imgSource = top_img && top_img.indexOf('/') !== -1 ? url_for(top_img) : top_img
// 首页专用路径(网页3)
- var homeImg = home_index_img ? url_for(home_index_img) : ''
- var homeVideo = home_index_video ? url_for(home_index_video) : ''
- var bg_img = is_home() ? (home_index_img || home_index_video) : imgSource
- var site_title = page.title || page.tag || page.category || config.title
- var isHomeClass = is_home() ? 'full_page' : 'not-home-page'
- is_post() ? isHomeClass = 'post-bg' : isHomeClass
else
- var isHomeClass = 'not-top-img'
else
- var top_img = false
- var isHomeClass = 'not-top-img'
header#page-header(class=`${isHomeClass}`)
!=partial('includes/header/nav', {}, {cache: true})
if top_img !== false
if is_post()
if page.bilibili_bg
!=partial('includes/bili-banner/index')
else
include ./post-info.pug
if theme.dynamicEffect && theme.dynamicEffect.postTopWave
section.main-hero-waves-area.waves-area
svg.waves-svg(xmlns='http://www.w3.org/2000/svg', xlink='http://www.w3.org/1999/xlink', viewBox='0 24 150 28', preserveAspectRatio='none', shape-rendering='auto')
defs
path#gentle-wave(d='M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z')
g.parallax
use(href='#gentle-wave', x='48', y='0')
use(href='#gentle-wave', x='48', y='3')
use(href='#gentle-wave', x='48', y='5')
use(href='#gentle-wave', x='48', y='7')
#post-top-cover
img#post-top-bg(class='nolazyload' src=bg_img)
else if is_home()
// 媒体容器(继承原主题背景参数)
#home-media-container(
data-landscape-img=home_index_img ? homeImg : ''
data-portrait-img=home_index_img && theme.index_img.vpath ? url_for(theme.index_img.vpath) : ''
data-landscape-video=home_index_video ? homeVideo : ''
data-portrait-video=home_index_video && theme.index_video.vpath ? url_for(theme.index_video.vpath) : ''
data-landscape-poster=home_index_video && theme.index_video.poster ? url_for(theme.index_video.poster) : ''
data-portrait-poster=home_index_video && theme.index_video.vposter ? url_for(theme.index_video.vposter) : ''
style="height:100%;background-attachment:fixed;z-index:0"
)
#site-info
h1#site-title=site_title
if theme.subtitle.enable
- var loadSubJs = true
#site-subtitle
span#subtitle
if(theme.social)
#site_social_icons
!=fragment_cache('social', function(){return partial('includes/header/social')})
#scroll-down
i.anzhiyufont.anzhiyu-icon-angle-down.scroll-down-effects
else
#page-site-info(style=`background-image: url(${imgSource})`)
h1#site-title=site_title
第二步:添加样式与JS文件
- 在
source/static/css
目录添加index_media.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62/* index */
#home-media-container {
position: fixed; /* 改为固定定位 */
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
/* 添加底部向上渐变遮罩 */
-webkit-mask-image: linear-gradient(to top, transparent 0%, black 0%);
mask-image: linear-gradient(to top, transparent 0%, black 0%);
}
.home-media {
position: fixed; /* 同步改为固定定位 */
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
/* 添加透明度过渡 */
transition: opacity 0.5s ease;
opacity: 1;
}
/* 自定义加载动画容器 */
.custom-loader {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 10; /* 确保在视频上方 */
pointer-events: none; /* 防止阻挡视频交互 */
transition: opacity 0.5s ease; /* 淡出动画 */
}
/* 加载动画元素 */
.loader-animation {
width: 18%;
height: 18%;
min-width: 128px;
min-height: 128px;
background-size: contain; /* 保持比例 */
background-position: center;
background-repeat: no-repeat;
animation: pulse 1.5s infinite ease-in-out;
}
/* 呼吸动画效果 */
@keyframes pulse {
0% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.1); opacity: 1; }
100% { transform: scale(1); opacity: 0.8; }
} - 在
source/static/js
目录添加index_media.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543// ======================= 横竖屏自适应背景媒体加载器 =======================
let lastOrientation = null; // 记录上一次的方向状态
// ================= 新增滚动渐变效果函数 =================
function initScrollFadeEffect() {
const mediaContainer = document.getElementById('home-media-container');
if (!mediaContainer) return;
const mediaElement = mediaContainer.querySelector('.home-media');
if (!mediaElement) return;
// 节流函数优化性能
function throttle(func, limit) {
let lastFunc, lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
}
}
// 处理滚动时的透明度变化
function handleScrollFade() {
const scrollY = window.scrollY;
const windowHeight = window.innerHeight;
// 计算透明度:从1(完全不透明)到0(完全透明)
// 当滚动到一屏高度时,透明度变为0
let opacity = 1 - (scrollY / windowHeight);
opacity = Math.max(0, Math.min(1, opacity)); // 限制在0-1范围
mediaElement.style.opacity = opacity;
}
// 节流处理滚动事件(每50ms检查一次)
const throttledScrollHandler = throttle(handleScrollFade, 50);
// 添加滚动监听
window.addEventListener('scroll', throttledScrollHandler);
// 初始化时执行一次
handleScrollFade();
// 存储当前滚动处理器以便后续移除
return throttledScrollHandler;
}
// ================= 滚动渐变效果函数结束 =================
// ================= 新增底部遮罩层控制函数 =================
function initScrollMaskEffect() {
const mediaContainer = document.getElementById('home-media-container');
if (!mediaContainer) return;
// 节流函数优化性能
function throttle(func, limit) {
let lastFunc, lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
}
}
// 处理滚动时的遮罩变化
function handleScrollMask() {
const scrollY = window.scrollY;
const windowHeight = window.innerHeight;
// 计算遮罩高度(0-100%)
let maskHeight = (scrollY / windowHeight) * 100;
maskHeight = Math.min(100, Math.max(0, maskHeight));
// 动态设置遮罩层高度
mediaContainer.style.setProperty('--mask-height', `${maskHeight}%`);
}
// 节流处理滚动事件(每50ms检查一次)
const throttledScrollHandler = throttle(handleScrollMask, 50);
// 添加滚动监听
window.addEventListener('scroll', throttledScrollHandler);
// 初始化时执行一次
handleScrollMask();
// 返回处理器以便后续移除
return throttledScrollHandler;
}
function initResponsiveBackground() {
const mediaContainer = document.getElementById('home-media-container');
if (!mediaContainer) {
console.error('[背景加载器] 未找到媒体容器元素');
return;
}
// 检测当前屏幕方向
const currentIsPortrait = window.innerHeight > window.innerWidth;
const currentOrientation = currentIsPortrait ? 'portrait' : 'landscape';
// 如果方向未改变,则直接返回
if (lastOrientation === currentOrientation) {
console.log('[背景加载器] 方向未改变,无需重新加载');
return;
}
// 更新方向记录
lastOrientation = currentOrientation;
console.log(`[背景加载器] 方向变化: ${currentOrientation}`);
// 清除现有媒体元素和加载动画
const existingMedia = mediaContainer.querySelector('.home-media');
const existingLoader = mediaContainer.querySelector('.custom-loader');
if (existingMedia) existingMedia.remove();
if (existingLoader) existingLoader.remove();
// 根据方向选择资源
let mediaSrc, posterSrc, mediaType;
if (currentIsPortrait) {
mediaSrc = mediaContainer.dataset.portraitVideo || mediaContainer.dataset.portraitImg;
posterSrc = mediaContainer.dataset.portraitPoster;
mediaType = mediaContainer.dataset.portraitVideo ? 'video' : 'img';
} else {
mediaSrc = mediaContainer.dataset.landscapeVideo || mediaContainer.dataset.landscapeImg;
posterSrc = mediaContainer.dataset.landscapePoster;
mediaType = mediaContainer.dataset.landscapeVideo ? 'video' : 'img';
}
if (!mediaSrc) {
console.error('[背景加载器] 未找到有效媒体资源');
return;
}
console.log(`[背景加载器] 使用资源: ${mediaSrc} (类型: ${mediaType})`);
// 创建媒体元素
const mediaElement = document.createElement(mediaType);
mediaElement.className = 'home-media';
mediaElement.style.cssText = 'width:100%;height:100%;object-fit:cover';
// ================= 设置初始透明度 =================
mediaElement.style.opacity = '1';
mediaElement.style.transition = 'opacity 0.5s ease';
// ================================================
// 在媒体容器添加媒体元素后调用效果函数
mediaContainer.appendChild(mediaElement);
addMediaEffects(mediaElement, mediaType); // 添加新功能
console.log('[背景加载器] 媒体元素已创建');
// 创建自定义加载动画容器
const loaderContainer = document.createElement('div');
loaderContainer.className = 'custom-loader';
mediaContainer.prepend(loaderContainer);
// 创建加载动画元素
const loaderElement = document.createElement('div');
loaderElement.className = 'loader-animation';
// 设置加载动画样式(使用GIF)
loaderElement.style.backgroundImage = `url(${posterSrc})`;
loaderContainer.appendChild(loaderElement);
// 视频特殊处理
if (mediaType === 'video') {
mediaElement.autoplay = true;
mediaElement.muted = true;
mediaElement.loop = true;
mediaElement.playsInline = true;
mediaElement.setAttribute('playsinline', '');
mediaElement.setAttribute('webkit-playsinline', '');
// 多源支持
const source = document.createElement('source');
source.src = mediaSrc;
source.type = 'video/mp4';
mediaElement.appendChild(source);
// 处理自动播放限制
const playPromise = mediaElement.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.warn('[背景加载器] 自动播放被阻止:', error);
mediaElement.muted = true;
mediaElement.play();
});
}
// 视频加载完成后移除加载动画
mediaElement.addEventListener('loadeddata', () => {
loaderContainer.style.opacity = '0';
setTimeout(() => {
if (loaderContainer.parentNode) {
loaderContainer.parentNode.removeChild(loaderContainer);
}
}, 500); // 淡出动画持续时间
});
} else {
mediaElement.src = mediaSrc;
mediaElement.loading = 'eager';
// 图片加载完成后移除加载动画
mediaElement.addEventListener('load', () => {
loaderContainer.style.opacity = '0';
setTimeout(() => {
if (loaderContainer.parentNode) {
loaderContainer.parentNode.removeChild(loaderContainer);
}
}, 500);
});
}
// 错误处理
mediaElement.onerror = function() {
console.error(`[背景加载器] 资源加载失败: ${mediaSrc}`);
this.style.display = 'none';
// 尝试回退到备用类型
console.warn('[背景加载器] 尝试回退到备用媒体');
const fallbackType = mediaType === 'video' ? 'img' : 'video';
const fallbackSrc = currentIsPortrait ?
(mediaContainer.dataset.portraitImg || mediaContainer.dataset.portraitVideo) :
(mediaContainer.dataset.landscapeImg || mediaContainer.dataset.landscapeVideo);
if (fallbackSrc && fallbackSrc !== mediaSrc) {
console.log(`[背景加载器] 使用备用资源: ${fallbackSrc}`);
mediaElement.src = fallbackSrc;
mediaElement.style.display = 'block';
}
};
mediaContainer.appendChild(mediaElement);
console.log('[背景加载器] 媒体元素已创建');
// ================= 初始化滚动渐变效果 =================
initScrollFadeEffect();
}
function addMediaEffects(mediaElement, mediaType) {
if (mediaType === 'video') {
// 获取当前方向
const currentIsPortrait = window.innerHeight > window.innerWidth;
// 竖屏模式下固定放大105%
const baseScale = currentIsPortrait ? 1.05 : 1.2;
mediaElement.style.transform = `scale(${baseScale})`;
// 检测是否为iOS设备
function isIOS() {
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}
// 如果是iOS设备,直接禁用所有视差效果
if (isIOS()) {
console.log('[视差效果] 在iOS设备上,禁用所有视差效果');
return; // 直接返回,不初始化任何视差效果
}
// 1. 添加缩放动画效果
mediaElement.style.transform = 'scale(1.2)'; // 初始放大110%
mediaElement.style.transition = 'transform 0.5s ease-out';
// 在视频加载完成后触发缩放动画
mediaElement.addEventListener('loadeddata', () => {
// 竖屏模式保持105%缩放,不需要动画
if (currentIsPortrait) {
mediaElement.style.transform = 'scale(1.05)';
}
// 横屏模式执行缩放动画到正常大小
else {
setTimeout(() => {
mediaElement.style.transform = 'scale(1)';
}, 100);
}
});
// 2. 添加视差效果(鼠标/陀螺仪)
const mediaContainer = document.getElementById('page-header');
mediaContainer.style.overflow = 'hidden';
mediaElement.style.transformOrigin = 'center center';
// 视差效果参数
const parallaxIntensity = 0.05;
const scaleIntensity = 0.05;
let isGyroActive = false;
// ================= 新增陀螺仪支持 =================
// 检测陀螺仪支持
function initGyroParallax() {
if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {
// iOS 13+ 需要权限
DeviceOrientationEvent.requestPermission()
.then(permissionState => {
if (permissionState === 'granted') {
setupGyroListeners();
isGyroActive = true;
}
})
.catch(console.error);
} else if ('DeviceOrientationEvent' in window) {
// Android和其他支持设备
setupGyroListeners();
isGyroActive = true;
}
return isGyroActive;
}
// 设置陀螺仪监听
function setupGyroListeners() {
window.addEventListener('deviceorientation', handleOrientation);
}
// 处理陀螺仪数据
function handleOrientation(event) {
// 竖屏模式使用105%基础缩放
const baseScaleValue = currentIsPortrait ? 1.05 : 1;
if (!isGyroActive) return;
// 获取陀螺仪数据(beta: 前后倾斜, gamma: 左右倾斜)
const beta = event.beta || 0; // 前后倾斜(-180到180)
const gamma = event.gamma || 0; // 左右倾斜(-90到90)
// 将角度转换为百分比偏移(归一化处理)
const moveX = (gamma / 90) * parallaxIntensity * 100; // -100% 到 100%
const moveY = (beta / 180) * parallaxIntensity * 100;
// 应用视差效果
mediaElement.style.transform = `
translate(${moveX}%, ${moveY}%)
scale(${baseScaleValue + scaleIntensity})
`;
}
// ================= 鼠标视差效果 =================
function initMouseParallax() {
mediaContainer.addEventListener('mousemove', (e) => {
const rect = mediaContainer.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
const moveX = (x - 0.5) * parallaxIntensity * 100;
const moveY = (y - 0.5) * parallaxIntensity * 100;
mediaElement.style.transform = `
translate(${moveX}%, ${moveY}%)
scale(${1 + scaleIntensity})
`;
});
mediaContainer.addEventListener('mouseleave', () => {
mediaElement.style.transform = 'scale(1)';
});
}
// ================= 根据设备类型初始化 =================
// 检测移动设备
const isMobile = /Mobi|Android/i.test(navigator.userAgent);
if (isMobile) {
// 移动设备优先使用陀螺仪
if (!initGyroParallax()) {
// 不支持陀螺仪则回退到触摸事件
initTouchParallax();
}
} else {
// PC设备使用鼠标事件
initMouseParallax();
}
// ================= 触摸事件回退方案 =================
function initTouchParallax() {
mediaContainer.addEventListener('touchmove', (e) => {
e.preventDefault();
const touch = e.touches[0];
const rect = mediaContainer.getBoundingClientRect();
const x = (touch.clientX - rect.left) / rect.width;
const y = (touch.clientY - rect.top) / rect.height;
const moveX = (x - 0.5) * parallaxIntensity * 50; // 移动强度减半
const moveY = (y - 0.5) * parallaxIntensity * 50;
mediaElement.style.transform = `
translate(${moveX}%, ${moveY}%)
scale(${1 + scaleIntensity * 0.5}) // 缩放强度减半
`;
});
mediaContainer.addEventListener('touchend', () => {
mediaElement.style.transform = 'scale(1)';
});
}
// ================= 性能优化 =================
// 页面不可见时暂停陀螺仪
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
isGyroActive = false;
} else if (isMobile) {
isGyroActive = initGyroParallax();
}
});
}
}
// 在initMedia函数中调用新功能
function initMedia() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
initResponsiveBackground();
initScrollFadeEffect(); // 添加调用
});
} else {
initResponsiveBackground();
initScrollFadeEffect(); // 添加调用
}
}
// ======================= 执行入口 =======================
initMedia();
// 防抖处理窗口变化
let resizeTimer;
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
// 计算当前方向状态
const currentIsPortrait = window.innerHeight > window.innerWidth;
const currentOrientation = currentIsPortrait ? 'portrait' : 'landscape';
// 只有方向实际改变时才执行重载
if (lastOrientation !== currentOrientation) {
console.log('[背景加载器] 窗口大小变化,重新加载媒体');
initResponsiveBackground();
} else {
console.log('[背景加载器] 窗口大小变化但方向未改变');
// ================= 方向未变时重置透明度 =================
initScrollFadeEffect();
}
}, 500);
});
// 页面可见性变化处理
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
const video = document.querySelector('#home-media-container video');
if (video && video.paused) {
console.log('[背景加载器] 页面恢复可见,重新播放视频');
video.play().catch(e => console.warn('视频恢复播放失败:', e));
}
// ================= 页面恢复可见时重置透明度 =================
initScrollFadeEffect();
}
});
// ========== 新增修复代码(直接加在现有代码后面) ========== //
// 1. 缓存恢复检测(核心修复)
window.addEventListener('pageshow', event => {
if (event.persisted && location.pathname === '/') {
console.log('[修复] 检测到缓存恢复主页,强制重置');
lastOrientation = null;
initResponsiveBackground();
// ================= 缓存恢复时重置透明度 =================
setTimeout(initScrollFadeEffect, 300);
}
});
// 2. 路由变化监听(SPA兼容)
window.addEventListener('popstate', () => {
if (location.pathname === '/') {
console.log('[修复] 检测到返回主页');
setTimeout(() => {
// 检查媒体元素是否存在
const container = document.getElementById('home-media-container');
if (!container?.querySelector('.home-media')) {
lastOrientation = null;
initResponsiveBackground();
}
// ================= 返回主页时重置透明度 =================
initScrollFadeEffect();
}, 300); // 延迟确保DOM更新
}
});
// 3. 媒体状态自检(兜底方案)
function checkMediaStatus() {
if (location.pathname !== '/') return;
const container = document.getElementById('home-media-container');
if (!container) return;
const hasMedia = container.querySelector('.home-media');
if (!hasMedia) {
console.log('[修复] 自检发现媒体丢失');
lastOrientation = null;
initResponsiveBackground();
}
// ================= 媒体自检时重置透明度 =================
initScrollFadeEffect();
}
// 每0.5秒检查一次(轻量级检测)
setInterval(checkMediaStatus, 500);
// 4. 增强错误处理(在initResponsiveBackground函数内修改)
// 在mediaElement.onerror函数内添加:
setTimeout(() => {
if (!mediaElement.parentNode) {
console.warn('[修复] 尝试完全重建');
lastOrientation = null;
initResponsiveBackground();
// ================= 错误重建时重置透明度 =================
setTimeout(initScrollFadeEffect, 500);
}
}, 1000);
第三步:插入样式
在
_config.anzhiyu.yml
文件中搜索index_img
配置项替换新的配置项- 替换前
1
2
3# The banner image of home page
index_img: false # "background: url() top / cover no-repeat"- 替换后,其中两个
path
与vpath
为我临时演示效果路径,不介意也可直接使用。注意两个enable
只能打开其一为true
,两者都为false
时关闭Top壁纸为安知鱼默认效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# The banner image of home page
# 首页媒体配置
index_img:
enable: false
path: https://tc.ayakasuki.com/a/2025/06/11/biji684950edcabc4.png
vpath: https://tc.ayakasuki.com/a/2025/06/11/biji684950efea626.png
index_video:
enable: true # 视频总开关
path: https://yun.ayakasuki.com/index.php?explorer/share/file&hash=f97fiWtCSKo12h0pq2dKR5w2QEFNZA3UamrI9ZLGp22ZV6NoEITHrMMyPAKTkXlOktdVLA
poster: https://tc.ayakasuki.com/a/2025/06/11/biji68495015b3481.gif # 视频加载时动画
vpath: https://yun.ayakasuki.com/index.php?explorer/share/file&hash=9f25EPDmi9bScfWMCm_r061iw-lKwpKEaT6OZzv7dUyBSh75x_4KrNHSuaD6VW2ehSl-xw # 新增竖屏视频
vposter: https://tc.ayakasuki.com/a/2025/06/11/biji68495015b3481.gif # 竖屏视频加载时动画在
_config.anzhiyu.yml
文件中搜索inject
配置项,在head
中插入CSS和JS
static
是我在source
文件夹下创建的文件夹,如需自行配置则修改相关目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 # Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
# 自定义css
- <script src="/static/js/index_media.js"></script> #index_img和index_video自适应入口文件
- <link rel="stylesheet" href="/static/css/index_media.css"> #index_img和index_video入口文件配套css
写在最后
博主也是一个马虎蛋,文章结构是引用一篇同美化库大佬文章结构模仿然后改成自己的主页动态壁纸效果代码,如果文章有不对或者不严谨亦或者有朋友优化之后的建议与新分支,欢迎在下方评论引入新建议或新分支代码~!!
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果