优缺点

  • 优点:反应快、延迟低、无需服务器搭建
  • 缺点:需要改动原文件、需要消耗一定性能、需要考虑到图片链接是否支持跨域

参考文章

参考文章

魔改过程

  1. 主题配置文件_config.butterfly.yml 相关配置
1
2
3
4
5
6
7
8
# 主色调相关配置
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修改主色调
color_thief_js: https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.4.0/color-thief.umd.min.js
  1. 在路径themes/anzhiyu/layout/includes/additional-js.pug 添加
1
2
3
//- 获取图片主色调
if theme.mainTone.enable && theme.mainTone.mode == 'local' && theme.mainTone.color_thief_js
script(src=url_for(theme.mainTone.color_thief_js))
  1. 在路径themes/anzhiyu/source/js/main.js if (GLOBAL_CONFIG.mainTone.mode == "both") { ······ } else { }
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 (GLOBAL_CONFIG.mainTone.mode == "both") {
// both继续请求
try {
const response = await fetch(GLOBAL_CONFIG.mainTone.api + path);
if (response.ok && response.headers.get("content-type")?.includes("application/json")) {
const obj = await response.json();
let value = obj.RGB;

if (getContrastYIQ(value) === "light") {
value = LightenDarkenColor(colorHex(value), -40);
}

root.style.setProperty("--anzhiyu-bar-background", value);
requestAnimationFrame(() => {
anzhiyu.initThemeColor();
});

if (GLOBAL_CONFIG.mainTone.cover_change) {
document.documentElement.style.setProperty("--anzhiyu-main", value);
document.documentElement.style.setProperty(
"--anzhiyu-theme-op",
getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main") + "23"
);
document.documentElement.style.setProperty(
"--anzhiyu-theme-op-deep",
getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main") + "dd"
);
}
} else {
root.style.setProperty("--anzhiyu-bar-background", fallbackValue);
requestAnimationFrame(() => {
anzhiyu.initThemeColor();
});
document.documentElement.style.setProperty("--anzhiyu-main", fallbackValue);
}
} catch {
root.style.setProperty("--anzhiyu-bar-background", fallbackValue);
requestAnimationFrame(() => {
anzhiyu.initThemeColor();
});
document.documentElement.style.setProperty("--anzhiyu-main", fallbackValue);
}
} else {
- root.style.setProperty("--anzhiyu-bar-background", fallbackValue);
- requestAnimationFrame(() => {
- anzhiyu.initThemeColor();
- });
- document.documentElement.style.setProperty("--anzhiyu-main", fallbackValue);
+ const colorThief = new ColorThief();
+ const img = new Image();
+ img.crossOrigin = "Anonymous";
+ img.src = path;
+ img.onload = () => {
+ let ItemColor = 'rgb(' + colorThief.getColor(img) + ')';
+ ItemColor = colorHex(ItemColor);
+ if (getContrastYIQ(ItemColor) === "light") {
+ ItemColor = LightenDarkenColor(colorHex(ItemColor), -40);
+ }
+ root.style.setProperty("--anzhiyu-bar-background", ItemColor);
+ requestAnimationFrame(() => {
+ anzhiyu.initThemeColor();
+ });
+ if (GLOBAL_CONFIG.mainTone.cover_change) {
+ document.documentElement.style.setProperty("--anzhiyu-main", ItemColor);
+ document.documentElement.style.setProperty(
+ "--anzhiyu-theme-op",
+ getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main") + "23"
+ );
+ document.documentElement.style.setProperty(
+ "--anzhiyu-theme-op-deep",
+ getComputedStyle(document.documentElement).getPropertyValue("--anzhiyu-main") + "dd"
+ );
+ }
+ // console.info(ItemColor);
+ }
}