fluid 全屏背景图随日夜模式切换和正文底页毛玻璃效果

本文最后更新于:2024年10月28日 凌晨

fluid 全屏背景图随日夜模式切换和正文底页毛玻璃效果

实现背景图全屏效果

设置背景图为全屏效果,可以使用 fluid 提供的注入代码功能,可以将代码无侵入式加入到主题里。

在根目录下新建一个 scripts 目录,在目录内新建:injector.js

1
2
3
const { root: siteRoot = "/" } = hexo.config;
hexo.extend.injector.register("body_begin", `<div id="web_bg"></div>`);
hexo.extend.injector.register("body_end",`<script src="${siteRoot}js/backgroundize.js"></script>`);

名字其实可以随意。

该文件不需要在_config.fluid.yml 中进行引用,hexo 自动执行调用里面的 js 文件

其实到这一步就可以了,因为我们其实一般会在_config.fluid.yml 中自己指定背景图。但如果你想实现点击日夜模式切换按钮背景图也跟着切换的话,还需要写一个自定义 js 文件。

实现背景图切换效果

source/js 目录中新建背景修改 backgroundize.js 文件,我的代码文件如下:backgroundize.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
/**
 * 返回当前的主题模式(dark或light)
 * @returns {string} 当前的主题模式
 */
function getThemeMode() {
  const theme = localStorage.getItem('Fluid_Color_Scheme');
  console.log('当前主题模式为:', theme || 'dark');
  return theme === 'light' ? 'light' : 'dark';
}

/**
 * 根据主题模式和设备类型设置背景图片
 * @param {String} themeMode - 'light' 或 'dark'
 */
function setBackgroundImage(themeMode) {
  const isMobile = window.innerWidth < 768;
  const webBgElement = document.querySelector('#web_bg');

  if (isMobile) {
    webBgElement.style.backgroundImage = `var(--mobile-bg-image)`;
  } else if (themeMode === 'dark') {
    webBgElement.style.backgroundImage = `var(--desktop-bg-image-night)`;
  } else {
    webBgElement.style.backgroundImage = `var(--desktop-bg-image-normal)`;
  }
}

/**
 * 初始化背景图片设置
 * @returns {void}
 */
function initBackground() {
  const theme = getThemeMode();
  setBackgroundImage(theme);
}

/**
 * 重置Banner样式,隐藏背景图片和遮罩层
 * @returns {void}
 */
function resetBannerStyles() {
  document.querySelector("#banner").setAttribute('style', 'background-image: none');
  document.querySelector("#banner .mask").setAttribute('style', 'background-color: rgba(0,0,0,0)');
}

// 监听主题切换按钮点击事件
const themeBtn = document.querySelector('#color-toggle-btn');
if (themeBtn) {
  themeBtn.addEventListener('click', () => {
    const theme = getThemeMode();
    setBackgroundImage(theme);
    console.log(`切换到${theme === 'light' ? '日间' : '夜间'}模式`);
  });
}

// 初始化背景和样式
initBackground();
resetBannerStyles();

// 监听窗口大小变化,做防抖处理调整背景
let resizeTimeout;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    setBackgroundImage(getThemeMode());
  }, 200);
}, {
  passive: true // 防止默认事件
});

/**
 * 如果你想实现不同的文章为不同的背景图片,
 * 可以定义一个数组用于存放不同文章的路径,通过pathname判断当前文章路径,设置对应的背景图片。
 * 例如:
 * --------分割线--------
 * const articleBgMap = {
 *   '/article1': 'url(https://example.com/bg1.jpg)',
 *   '/article2': 'url(https://example.com/bg2.jpg)',
 *   '/article3': 'url(https://example.com/bg3.jpg)',
 * };
 * const currentPathname = window.location.pathname;
 * const bgUrl = articleBgMap[currentPathname] || 'url(https://example.com/bg-default.jpg)';
 * document.querySelector('#web_bg').style.backgroundImage = bgUrl;
 * ……略
 * --------分割线--------
 * 诚然,这样做会增加代码量,但可以满足不同文章的背景图片需求。
 * 我不否认会有更好的实现方式,以上仅作参考。
 */

该代码文件还需要结合一个自定义的 css 文件使用(稍后解释用途):source/css/backgroundize.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:root {
  --mobile-bg-image: url('https://userName.github.io/img/bg/eva_mobile.jpg');
  --desktop-bg-image-normal: url('https://userName.github.io/img/bg/eva.jpg');
  --desktop-bg-image-night: url('https://userName.github.io/img/bg/Mei.jpg');
}

#web_bg {
  background-image: var(--desktop-bg-image-normal);
  position: fixed;
  width: 100%;
  height: 100%;
  z-index: -1;
  background-size: cover;
  /* 添加过渡效果 */
  transition: all 0.5s;
}

你只需要将 --mobile-bg-imageurl 链接替换成你需要的即可。

别忘记在_config.fluid.yml 文件中的 custom_jscustom_css 中进行引用

例如:

1
2
3
4
5
custom_js:
  - /js/backgroundize.js
  
custom_css:
  - /css/backgroundize.css

为什么要新建一个 css?

主要是为了更好的实现图片切换效果。

如果直接在 js 文件中进行背景图的替换操作,实际上是发出了图片请求,这样一来你的图片切换效果全看网络情况,体验是比较不好的(这样也会造成闪屏效果,晚上很刺眼)。而通过 css 变量的方式,所操作的只是变量的切换,不需要重新设置背景图。

另一个可能的思路是使用预加载,但我对现在的方式比较满意,也就没有去探究。

毛玻璃底页效果

  1. 修改_config.fluid.yml 文件的主面板背景色

    1
    2
    3
    4
    # 主面板背景色
    # Color of main board
    board_color: "#ffffff80"
    board_color_dark: "#00000080"
  2. source/css 目录下新建 glassBg.css 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* 正文底页毛玻璃效果 */
    #board {
      -webkit-backdrop-filter: blur(10px);
      backdrop-filter: blur(10px);
    }
    /* 侧边目录毛玻璃效果 */
    #toc {
      padding: 10px;
      top: 4rem;
      background-color: var(--board-bg-color);
      border-radius: 10px;
      -webkit-backdrop-filter: blur(var(--background-blur));
      backdrop-filter: blur(var(--background-blur));
    }

侧边的目录区域毛玻璃效果如果不需要可以删除。

一些好用的插件

Hexo 官方推荐插件就足够:https://fluid-dev.github.io/hexo-fluid-docs/advance/#hexo - 插件


fluid 全屏背景图随日夜模式切换和正文底页毛玻璃效果
https://4rozen.github.io/archives/Hexo/60191.html
作者
4rozeN
发布于
2024年10月5日
许可协议