• V2 版本和 V1 版本没有区别,只是规范一下写法和保留原有功能
  • 使用本教程需要考虑到图片链接是否支持跨域

V1版本

配置

  • 主题配置文件_config.butterfly.yml相关配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 主色调相关配置
mainTone:
enable: true # true or false 文章是否启用获取图片主色调
mode: local # cdn/api/both/local cdn模式为图片url+imageAve参数获取主色调,api模式为请求API获取主色调,both模式会先请求cdn参数,无法获取的情况下将请求API获取,可以在文章内配置main_color: '#3e5658',使用十六进制颜色,则不会请求both/cdn/api获取主色调,而是直接使用配置的颜色
# 项目地址:https://github.com/anzhiyu-c/img2color-go
api: # mode为api时可填写
cover_change: true # 整篇文章跟随cover修改主色调

# ------------------------------------------

# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
# 自定义css

bottom:
# 自定义js
- <script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.4.0/color-thief.umd.min.js"></script>

增加本地模式

  • 在路径 themes/anzhiyu/source/js/main.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

//封面纯色
const coverColor = async () => {
······
// 文章内
if (GLOBAL_CONFIG.mainTone) {
if (GLOBAL_CONFIG_SITE.postMainColor) {
······
- } else {
+ } else if (GLOBAL_CONFIG.mainTone.mode == "local") {
+ const handleImageLoad = async () => {
+ try {
+ const colorThief = new ColorThief();
+ const img = new Image();
+ img.crossOrigin = "anonymous";
+ img.src = path;
+ await new Promise((resolve) => { img.onload = resolve; });
+ const ImgColorRGB = await colorThief.getColor(img);
+ const ImgColorHex = colorHex(`rgb(${ImgColorRGB})`);
+ let adjustedColor = ImgColorHex;
+ if (getContrastYIQ(ImgColorHex) === "light") {
+ adjustedColor = LightenDarkenColor(ImgColorHex, -40);
+ }
+ root.style.setProperty("--anzhiyu-bar-background", adjustedColor);
+ requestAnimationFrame(() => anzhiyu.initThemeColor());
+ if (GLOBAL_CONFIG.mainTone.cover_change) {
+ document.documentElement.style.setProperty("--anzhiyu-main", adjustedColor);
+ const mainColor = getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main");
+ document.documentElement.style.setProperty("--anzhiyu-theme-op", `${mainColor}23`);
+ document.documentElement.style.setProperty("--anzhiyu-theme-op-deep", `${mainColor}dd`);
+ }
+ } catch (err) {
+ console.error("Error fetching data:", err);
+ const fallbackValue = "var(--anzhiyu-theme)";
+ root.style.setProperty("--anzhiyu-bar-background", fallbackValue);
+ requestAnimationFrame(() => anzhiyu.initThemeColor());
+ document.documentElement.style.setProperty("--anzhiyu-main", fallbackValue);
+ }
+ };
+ handleImageLoad();
+ } else {
······
// cdn/api模式请求
······
}
}
};

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

} else if (GLOBAL_CONFIG.mainTone.mode == "local") {
// 定义一个异步函数 handleImageLoad,用于处理图片加载并根据图片颜色动态设置页面样式
const handleImageLoad = async () => {
try {
// 创建一个新的 ColorThief 实例,用于从图像中提取主色调
const colorThief = new ColorThief();

// 创建一个新的 Image 对象,并允许跨域访问以加载图片资源
const img = new Image();
img.crossOrigin = "anonymous";

// 设置图片的路径
img.src = path;

// 等待图片加载完成。这里通过创建 Promise 并在 onload 回调中 resolve 来实现异步等待
await new Promise((resolve) => { img.onload = resolve; });

// 使用 ColorThief 从加载的图片中获取 RGB 格式的主色调值
const ImgColorRGB = await colorThief.getColor(img);

// 将 RGB 格式转换为十六进制格式
const ImgColorHex = colorHex(`rgb(${ImgColorRGB})`);

// 根据获取的颜色判断是否需要调整色调(如果是浅色则变暗)
let adjustedColor = ImgColorHex;
if (getContrastYIQ(ImgColorHex) === "light") {
adjustedColor = LightenDarkenColor(ImgColorHex, -40);
}

// 设置顶部栏背景颜色为提取或调整后的颜色
root.style.setProperty("--anzhiyu-bar-background", adjustedColor);

// 在下一帧渲染时初始化主题颜色
requestAnimationFrame(() => anzhiyu.initThemeColor());

// 如果全局配置中 mainTone.cover_change 为真,则根据图片颜色更新文档元素的主要颜色以及相关主题属性
if (GLOBAL_CONFIG.mainTone.cover_change) {
document.documentElement.style.setProperty("--anzhiyu-main", adjustedColor);

// 获取当前 --anzhiyu-main 的计算样式值(即:已设置的颜色值)
const mainColor = getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main");

// 更新其他依赖于主要颜色的主题操作 CSS 自定义属性
document.documentElement.style.setProperty("--anzhiyu-theme-op", `${mainColor}23`);
document.documentElement.style.setProperty("--anzhiyu-theme-op-deep", `${mainColor}dd`);
}
} catch (err) {
// 如果在处理过程中发生错误,记录错误信息并使用默认主题颜色进行回退
console.error("Error fetching data:", err);

const fallbackValue = "var(--anzhiyu-theme)";

// 设置顶部栏背景颜色为默认主题颜色
root.style.setProperty("--anzhiyu-bar-background", fallbackValue);

// 初始化主题颜色(即使出错也要执行,以便应用回退颜色)
requestAnimationFrame(() => anzhiyu.initThemeColor());

// 同样将文档元素的主要颜色设置为默认主题颜色
document.documentElement.style.setProperty("--anzhiyu-main", fallbackValue);
}
};
// 执行图片加载和颜色处理的异步操作
handleImageLoad();
} else {