周天记 - Hexo
type: channel
link: https://zhoutian.com/tag/Hexo/
items: 给博客添加一个时钟效果
items: 博客应用部署历程
items: 博客页脚获取随机友联
items: Gulp进行静态资源压缩
items: 深色模式添加粒子背景效果
items: 推荐hexo主题solitude
items: 在中控台添加帧率显示功能
items: 博客添加波浪效果
items: Twikoo自定义邮件模板
items: 通过RGB提取主题色

给博客添加一个时钟效果
type: item
date: 2024-03-22T09:41:00+08:00
description: 由于我准备把侧边栏时钟功能移除掉了，但是之前魔改的代码还是想留着，所以有了本文，爱折腾，有兴趣的可以尝试一下！效果预览魔改步骤1.新建 card_clock.pug，添加如下内容if theme.aside.card_clock.enable style. .clock_frame { background: var(--Jay-main); display: flex; justify-content: center; align-content: center; box-shadow: var(--Jay-shadow-border); background: var(--Jay-card-bg); border: var(--style-border); border-radius: 12px; transition: .3s; position: relative; overflow: hidden; margin-top: 1rem; } .clock { width: 256px; height: 256px; border-radius: 50%; background-color: #fff; position: relative; overflow: hidden; } .clock::after { content: ""; width: calc(256px - 80px); height: calc(256px - 80px); background-color: inherit; border-radius: 50%; display: block; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } .clock .marker { height: calc(100% - 25px); width: 3.2px; background-color: rgb(52 73 94 / 40%); position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } .clock .marker:nth-of-type(3n + 1) { background: rgb(52 73 94); } .clock .marker:nth-of-type(2) { transform: rotate(30deg); } .clock .marker:nth-of-type(3) { transform: rotate(60deg); } .clock .marker:nth-of-type(4) { transform: rotate(90deg); } .clock .marker:nth-of-type(5) { transform: rotate(120deg); } .clock .marker:nth-of-type(6) { transform: rotate(150deg); } .clock .hand { transform-origin: center bottom; position: absolute; z-index: 3; bottom: 50%; left: 50%; width: 5.12px; transition: transform 1s linear; } .clock .hand.second { height: 85.3333333333px; width: 1.3837837838px; left: calc(50% - 1.5px); border-radius: 1.5px; background-color: #ec231e; box-shadow: 4px 6px 0 0 rgba(0, 0, 0, 0.15); transform: rotate(40deg); z-index: 9; } .clock .hand.second::before, .clock .hand.second::after { content: ""; background-color: inherit; position: absolute; border-radius: 50%; left: 50%; } .clock .hand.second::before { width: 12.8px; height: 12.8px; bottom: 0; transform: translate(-50%, 50%); box-shadow: 2px 2px 2px 0 rgba(0, 0, 0, 0.15); }…

博客应用部署历程
type: item
date: 2023-11-10T08:32:00+08:00
description: 这篇文章与其说是分享，不如直接说是我部署过程的记录，虽然文中写到的东西在其他博客都能找到，但是我仍然还是记录下我使用到的部署流程，方便我以后换服务器，或是其他特殊原因，需要重新部署时查阅前言昨天心血来潮，把服务器又折腾了一番，之前采用Nginx + Docker方式部署，所有映射及转发都采用手动配置，当然这些对于我来说并没什么难度，而现在采用baota + Nginx + Docker方式部署，目前使用的是静态博客，以及fcircle + twikoo部署都更为便捷，下面分享内容主要以文字为主，可能不会截图，这部分部署相信大家都会安装由于我的服务器并不是纯净系统，所以不能直接安装宝塔，当然网络上也有人说可以通过 docker 安装 centos 方式来安装，但是我没试，而采用粗暴方式，重装系统（记得备份），我这里选择宝塔专享版的镜像直接安装安装完后，发现这个专享版什么也不带，需要自己安装Apache、Nginx，当然php也不能少部署部署 hexo源代码拉到服务器，然后hexo g编译，宝塔配置目录绑定即可，eg：/www/wwwroot/hexo_blog/public部署 fcircle 鱼塘之前部署在vercle上，总感觉不太稳定，现改为私有部署，我这里采用 docker 部署，官网部署docker安装 Docker CE 之前需要删除 Docker 旧版本yum remove docker docker-common docker-selinux docker-engine安装 Docker 所需的软件包yum install -y yum-utils device-mapper-persistent-data lvm2设置 docker yum 源yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo安装 DOCKER CEyum install docker-ce yum list docker-ce --showduplicates | sort -r #要安装特定版本的Docker CE，请列出repo中的可用版本启动 Dockersystemctl start docker systemctl status docker安装gityum install -y git宝塔中自带python，在软件商店直接安装即可，我这里采用服务器安装模式安装依赖yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel yum vim gcc安装 pythonwget https://www.python.org/ftp/python/3.8.8/Python-3.8.8.tgz tar -zxf Python-3.8.8.tgz && cd Python-3.8.8 ./configure --prefix=/usr/local/python3 make && make install建立软连接ln -s /usr/local/python3/bin/python3.8 /usr/bin/python3 ln -s /usr/local/python3/bin/pip3.8 /usr/bin/pip3验证(出现版本号即安装成功)python3 --version安装 yamlpip3 install pyyaml停止运行找到进程号，杀掉即可ps auxkill 掉 PID 即可，也可通过fcircle项目中python3 deploy.py脚本一键取消运行部署后端克隆仓库git clone https://github.com/Rock-Candy-Tea/hexo-circle-of-friends拉取镜像docker pull yyyzyyyz/fcircle:latest运行部署脚本 进入hexo-circle-of-friends根目录，运行一下脚本，选择docker -> 部署即可python3 deploy.py尝试访问：curl 127.0.0.1:8000/all，有数据即为部署成功，再使用域名反向代理即可部署前端官网、heo、akilar、安知鱼部署 twikoo官网拉取镜像docker pull imaegoo/twikoo运行容器docker run --name twikoo -e TWIKOO_THROTTLE=1000 -p 8…

博客页脚获取随机友联
type: item
date: 2023-05-11T14:16:00+08:00
description: 博客页脚之前使用的是友联朋友圈部署随机获取的，前段时间突然发现无法访问了，重启才恢复正常，所以想将这部分独立出来，不再依赖友联朋友圈，废话不多说，开整介绍两种魔改方案，一种是通过json方式来读取，另一种是通过hexo内置过滤器来实现通过json方式实现此方式就是需要手动创建json，每次添加友联补充进json文件即可【新建】butterfly/source/frendlink.json[{ "class_name": "推荐", "class_desc": "参与本站开发、提供设计灵感、捐助本站的优秀博主，综合排序", "class_mode": "MxBlog", "link_list": [ { "name": "满心", "link": "https://zhoutian.com" }, { "name": "Jayhrn", "link": "https://blog.jayhrn.com" } ] }, { "class_name": "资源", "class_desc": "寻找资源不迷路", "class_mode": "MxBlog", "link_list": [ { "name": "steven安", "link": "https://chenjunan.top/" }, { "name": "MacApp分享", "link": "https://macapp.org.cn/" }, { "name": "精品MAC", "link": "https://pomac.cc/" } ] } ]js中添加如下var mx = { addFriendLinksInFooter: function () { var fetchUrl = "/mx/friendlink.json"; fetch(fetchUrl) .then((res) => res.json()) .then((json) => { var result = []; var prevIndex = -1; for (const item of json) { const links = item.link_list; for (let i = 0; i < Math.min(links.length, 1); i++) { let index = Math.floor(Math.random() * links.length); while (index === prevIndex && links.length > 1) { index = Math.floor(Math.random() * links.length); } prevIndex = index; result.push({ name: links[index].name, link: links[index].link, }); links.splice(index, 1); } } //删除result中最后一个元素 result.pop(); var htmlText = ""; for (let i = 0; i < result.length; ++i) { var item = result[i]; htmlText += `${item.name}`; } htmlText += `更多`; document.getElementById("friend-links-in-footer").innerHTML = htmlText; }); } }【修改】butterfly/layout/includes/additional-js.pug//- 初步进入需要加载的函数 .js-pjax script. mx.addFriendLinksInFooter()该方法，每天添加友联后，在json文件对应类别中添加即可方案二（推荐）此方式较为简单，无需json文件，直接读取，此方案来源于jayhrn【新建】butterfly/scripts/helpers/random.jshexo.extend.filter.register('after_render:html', function (data) { const flinks = [] hexo.locals.get('data').link.map(function (list) { list.link_list.map(function (flink) { flinks.push(flink) }) }) data += ` ` return data })jsaddFriendLinksInFooter: function() { let randomFriendLinks = getRandomFli…

Gulp进行静态资源压缩
type: item
date: 2023-04-14T11:14:00+08:00
description: 网站打开速度，一直是博主所关心的问题，那么除了优化系统本身、CDN等方式，还可以采用 gulp 来压缩资源，从而提升效率Gulp是什么Gulp 是一个基于 Node.js 的自动化构建工具，通过编写 JavaScript 脚本来定义任务，从而实现自动化构建。简单易用：Gulp 的 API 简单易用，不需要很多配置就能够快速上手。插件系统：Gulp 的插件系统丰富，几乎可以处理各种开发任务，包括文件压缩、合并、图片压缩、CSS 预处理器等。自动化构建：Gulp 可以自动监视文件变化，并自动执行相应的任务，大大提高了开发效率。流式处理：Gulp 使用流式处理，可以大大降低内存使用，提高构建速度。易于扩展：Gulp 使用 Node.js 开发，开发者可以自行编写插件来扩展其功能。综上所述，Gulp 是一个功能强大、易于使用和扩展的自动化构建工具，可以大大提高前端开发的效率。资源压缩静态资源：指在 Web 应用程序中，不需要动态生成内容的资源，例如 HTML、CSS、JavaScript、图片、字体等等。这些资源的特点是不会随着请求而发生变化，通常存储在服务器的文件系统中，并通过 HTTP 协议向客户端传输对于多媒体文件，很多资源都可以被压缩。尽管压缩多少会有一些失真（有损压缩），但只要失真程度不影响用户体验，我们也不必计较这些损失。最常见的压缩方式包括但不限于：使用webp格式、降低图片分辨率等。字体文件对于英文网站不会有特别严重的负担，但是中文字符数量非常庞大，如果把所有字符都囊括进来，一个字体文件动辄4MB，甚至有些能够超过20MB。因此，对字体文件进行压缩也是必要的。压缩字体文件有两种方案：从字体文件中提取出常用的文字或仅保留我们需要用到的文字。第二种方案的压缩率通常更高，同时也更安全，不会出现有些生僻字我们用到了却给删掉了的情况。但是，第二种方案每当更新网站内容时，就要生成新的字体文件，这就需要考虑客户端缓存的影响。教程下面我们使用 gulp 来压缩静态资源。注：我并没有通过gulp压缩多媒体资源，多媒体资源我是通过netlify插件，如果你需要压缩多媒体资源，可以自行去网上查找相应的插件。根目录执行，安装gulpnpm install --global gulp-cli npm install gulp --save安装插件，按需安装# 压缩HTML npm install gulp-htmlclean --save-dev npm install gulp-html-minifier-terser --save-dev # 压缩CSS npm install gulp-cssnano --save-dev # 压缩JS npm install gulp-terser --save-dev # 压缩TTF npm install gulp-fontmin --save-dev新建gulpfile.jsconst gulp = require("gulp") //用到的各个插件 const htmlMin = require('gulp-html-minifier-terser') const htmlClean = require('gulp-htmlclean') const terser = require('gulp-terser') const cssnano = require('gulp-cssnano') const fontmin = require('gulp-fontmin') // 压缩js gulp.task('minify-js', () => gulp.src(['./public/**/*.js', '!./public/**/*.min.js']) .pipe(terser({})) .pipe(gulp.dest('./public')) ) //压缩css gulp.task('minify-css', () => gulp.src(['./public/**/*.css']) .pipe(cssnano({ mergeIdents: false, reduceIdents: false, discardUnused: false, zIndex: false })).pipe(gulp.dest('./public')) ) //压缩html gulp.task('minify-html', () => gulp.src('./public/**/*.html') .pipe(htmlClean()) .pipe(htmlMin({ removeComments: true, //清除html注释 collapseWhitespace: true, //压缩html collapseI…

深色模式添加粒子背景效果
type: item
date: 2023-04-03T17:34:00+08:00
description: 深色模式下，总感觉背景有点单调，也考虑过添加背景图，还是太花了，看到安知鱼的深色模式，感觉这就是我想要的效果，果断整上效果预览魔改步骤主题中添加配置项(butterfly.yml)# 深色模式粒子效果 darkCanvas: enable: true引入 js(additional-js.pug)//- 黑色模式粒子效果canvas if theme.universe.enable canvas(id="universe") script(async src="/mx/js/dark.js")dark.js文件function dark() { window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; var n, e, i, h, t = 0.05, s = document.getElementById("universe"), o = !0, a = "180,184,240", r = "226,225,142", d = "226,225,224", c = []; function f() { (n = window.innerWidth), (e = window.innerHeight), (i = 0.216 * n), s.setAttribute("width", n), s.setAttribute("height", e); } function u() { h.clearRect(0, 0, n, e); for (var t = c.length, i = 0; i < t; i++) { var s = c[i]; s.move(), s.fadeIn(), s.fadeOut(), s.draw(); } } function y() { (this.reset = function () { (this.giant = m(3)), (this.comet = !this.giant && !o && m(10)), (this.x = l(0, n - 10)), (this.y = l(0, e)), (this.r = l(1.1, 2.6)), (this.dx = l(t, 6 * t) + (this.comet + 1 - 1) * t * l(50, 120) + 2 * t), (this.dy = -l(t, 6 * t) - (this.comet + 1 - 1) * t * l(50, 120)), (this.fadingOut = null), (this.fadingIn = !0), (this.opacity = 0), (this.opacityTresh = l(0.2, 1 - 0.4 * (this.comet + 1 - 1))), (this.do = l(5e-4, 0.002) + 0.001 * (this.comet + 1 - 1)); }), (this.fadeIn = function () { this.fadingIn && ((this.fadingIn = !(this.opacity > this.opacityTresh)), (this.opacity += this.do)); }), (this.fadeOut = function () { this.fadingOut && ((this.fadingOut = !(this.opacity < 0)), (this.opacity -= this.do / 2), (this.x > n || this.y < 0) && ((this.fadingOut = !1), this.reset())); }), (this.draw = function () { if ((h.beginPath(), this.giant)) (h.fillStyle = "rgba(" + a + "," + this.opacity + ")"), h.arc(this.x, this.y, 2, 0, 2 * Math.PI, !1); else if (this.comet) { (h.fillStyle = "rgba(" + d + "," + this.opacity + ")"), h.arc(this.x, this.y, 1.5, 0, 2 * Math.PI, !1); for…

推荐hexo主题solitude
type: item
date: 2023-03-23T10:00:00+08:00
description: 前言由于Heo主题元素的版面和流畅度都不错，很多人都想拥有，也包括满心，但是Heo没有开放主题的计划，所以想拥有该主题只能自己动手了，在此之前我对hexo使用的技术并不熟悉，但奈何实在喜欢这个主题，那么只能靠自己，所以大概花费了半年多的时间把，才有了现在的满心记，目前乃至以后仍然会跟随Heo更新，当然也不是所有元素都照搬，满心觉得不错的，而且不影响效率的，以及不依赖第三方组件条件下，满心会酌情考虑将其加入满心记当中关于满心记源码满心记源码为满心一步步魔改至此，其中花费的精力可想而知，再加上我也尊重原创，所以并未开源主题的打算，不过针对有些非常喜欢heo主题的朋友来说，可以选择使用hexo-theme-solitude这款主题，这款是目前与Heo相似度较高的主题，可以试试演示地址该主题目前也在持续更新，我也在此项目中，不过主要修复一些显示问题，并未实际参与功能开发

在中控台添加帧率显示功能
type: item
date: 2023-01-28T13:35:00+08:00
description: 针对不同博客，改动略有不同，本文仅供参考，我这里把fps开关放到了中控台修改 themes/butterfly/layout/includes/header/nav.pug#page-name-mask #page-name a#page-name-text(onclick= 'btf.scrollToDest(0,500)')=navTitleName #menus !=partial('includes/header/menu_item', {}, {cache: true}) #nav-left #fps-group #fps span.fpsText=_p('FPS')修改 themes/butterfly/layout/includes/console.pugif theme.console.keyboard.enable .console-btn-item#consoleKeyboard(onclick='manxin.keyboardToggle()', title='快捷键开关') a.keyboard-switch i.fas.fa-keyboard .console-btn-item#consoleCommentBarrage(onclick='manxin.switchCommentBarrage()', title='热评开关') a.commentBarrage i.fa-solid.fa-message .console-btn-item#consoleFPS(onclick='manxin.FPSToggle()', title='帧率显示开关') a.FPS-switch i.fas.fa-gauge新建 themes/butterfly/source/manxin/fps.js（引入js略）let Jay_showFPS = !1; "true" === localStorage.getItem("showFPS") ? ((Jay_showFPS = !0), document.querySelector("#fps-group").classList.add("show"), document.querySelector("#consoleFPS").classList.add("on")) : ((Jay_showFPS = !1), document.querySelector("#fps-group").classList.remove("show"), document.querySelector("#consoleFPS").classList.remove("on")); var showFPS = (function() { let e, t, o, n, a, i = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(e) { window.setTimeout(e, 1e3 / 60); }; (e = 0), (t = Date.now()), (n = function() { (o = Date.now() - t), (e += 1), o >= 1e3 && ((t += o), a(e), (e = 0)), i(n); }), (a = function(e) { $("#fps").html(e); }), n(); })(); var manxin = { FPSToggle: function() { Jay_showFPS ? ((Jay_showFPS = !1), document.querySelector("#fps-group").classList.remove("show"), document.querySelector("#consoleFPS").classList.remove("on"), localStorage.setItem("showFPS", "false")) : ((Jay_showFPS = !0), document.querySelector("#fps-group").classList.add("show"), document.querySelector("#consoleFPS").classList.add("on"), localStorage.setItem("showFPS", "tr…

博客添加波浪效果
type: item
date: 2022-12-26T11:21:00+08:00
description: 修改 themes/butterfly/layout/includes/header/index.pug 大概第 38 行左右if top_img !== false if is_post() include ./post-info.pug 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() #site-info h1#site-title=site_title if theme.subtitle.enable为了方便复制，提供一份需要修改的部分: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')然后在_config.butterfly.yml的 [inject.head] 或者自定义 css 中 引入以下 css, 不会的同学参考Hexo 博客添加自定义 css 和 js 文件/* 波浪css */ .main-hero-waves-area { width: 100%; position: absolute; left: 0; bottom: -11px; z-index: 5; } .waves-area .waves-svg { width: 100%; height: 5rem; } /* Animation */ .parallax > use { animation: move-forever 25s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite; } .parallax > use:nth-child(1) { animation-delay: -2s; animation-duration: 7s; fill: #f7f9febd; } .parallax > use:nth-child(2) { animation-delay: -3s; animation-duration: 10s; fill: #f7f9fe82; } .parallax > use:nth-child(3) { animation-delay: -4s; animation-duration: 13s; fill: #f7f9fe36; } .parallax > use:nth-child(4) { animation-delay: -5s; animation-duration: 20s; fill: #f7…

Twikoo自定义邮件模板
type: item
date: 2022-12-21T15:20:00+08:00
description: twikoo邮件通知自带模板，不忍直视，还是决定调整一下，自己写了一个简约模板，同时借鉴了Akilar、Heo邮件模板，并做了一些微调，统一放出来，方便切换使用方案一(简约模板)预览效果代码 Dear ${PARENT_NICK} 来自 ${NICK} 的回复 您在 ${SITE_NAME} 上发表的评论： ${PARENT_COMMENT} ${NICK} 给您回复啦： ${COMMENT} 欢迎再次光临${SITE_NAME}！ 点击去原文查看>> © 2022 lovelu.top 方案二(基于Akilar的模板)作者Akilar效果预览MAIL_TEMPLATE代码 <div style="position: relative;overflow: visible;height: 1500px;width: 500px;margin: 0px auto;transition: all 1s ease-in-out .3s;padding-top:200px;" ${PARENT_NICK}，见信安： 您在${SITE_NAME}上发表的评论: ${PARENT_COMMENT} 收到了来自${NICK}的回复： ${COMMENT} ${SITE_NAME}｜请您签收~ 自动书记人偶竭诚为您服务！ ©2023${SITE_NAME} MAIL_TEMPLATE_ADMIN代码 来自${NICK}的留言: ${COMMENT} ${SITE_NAME}｜请您过目~ 自动书记人偶竭诚为您服务！ ©2020${SITE_NAME} 方案三(基于heo模板)作者Heo在原作者基础上，进行了微调，并添加了头像呼吸效果，在电脑QQ邮箱无效，手机邮箱可正常预览效果预览MAIL_TEMPLATE代码 嘿！你在 ${SITE_NAME} 博客中收到一条新回复。 你之前的评论 在 ${SITE_NAME} 博客中收到来自 ${NICK} 的回复 ${PARENT_NICK} ${PARENT_COMMENT} ${NICK} ${COMMENT} 查看详情 此邮件由评论服务自动发出，直接回复无效。 前往博客 MAIL_TEMPLATE_ADMIN 嘿！你在 ${SITE_NAME} 博客中收到一条消息。 ${NICK} ${COMMENT} 查看详情 此邮件由评论服务自动发出，直接回复无效。 前往博客 如何使用在Twikoo后台进入邮件通知，将以上html代码，复制到MAIL_TEMPLATE和MAIL_TEMPLATE_ADMIN中，保存即可Twikoo邮件自定义字段Twikoo文档不提供邮件模板的参数含义，方便魔改，这里附上。|参数|释义||:-:|:-:||${SITE_URL}|网站地址||${SITE_NAME}|网站名||${PARENT_NICK}|被回复人昵称||${PARENT_COMMENT}|被回复人的评论内容||${NICK}|回复人昵称||${COMMENT}|回复人评论内容||${POST_URL}|文章链接||${IMG}|回复人头像||${PARENT_IMG}|被回复人头像||${MAIL}|回复人邮件||${IP}|回复人 IP 地址|参考：Twikoo评论回复邮件模板：Acrylic Mail 粉

通过RGB提取主题色
type: item
date: 2022-12-20T19:12:00+08:00
description: 对于这个功能个人感觉也是非常香，不过我后来参照heo方式，改为腾讯云API方式获取RGB了，目前把通过rgbaster和腾讯API方式都分享出来对于提取主题色，看过生成封面图片主色来作为文章封面顶图的文章，无意中看到了一篇帖子是关于这个的，于是便根据这个，加上Heo的教程，便解决了这个问题。[新建]themes/butterfly/source/js/rgbaster.min.js!function(n){"use strict";var t=function(){return document.createElement("canvas").getContext("2d")},e=function(n,e){var a=new Image,o=n.src||n;"data:"!==o.substring(0,5)&&(a.crossOrigin="Anonymous"),a.onload=function(){var n=t("2d");n.drawImage(a,0,0);var o=n.getImageData(0,0,a.width,a.height);e&&e(o.data)},a.src=o},a=function(n){return["rgb(",n,")"].join("")},o=function(n){return n.map(function(n){return a(n.name)})},r=5,i=10,c={};c.colors=function(n,t){t=t||{};var c=t.exclude||[],u=t.paletteSize||i;e(n,function(e){for(var i=n.width*n.height||e.length,m={},s="",d=[],f={dominant:{name:"",count:0},palette:Array.apply(null,new Array(u)).map(Boolean).map(function(){return{name:"0,0,0",count:0}})},l=0;i>l;){if(d[0]=e[l],d[1]=e[l+1],d[2]=e[l+2],s=d.join(","),m[s]=s in m?m[s]+1:1,-1===c.indexOf(a(s))){var g=m[s];g>f.dominant.count?(f.dominant.name=s,f.dominant.count=g):f.palette.some(function(n){return g>n.count?(n.name=s,n.count=g,!0):void 0})}l+=4*r}if(t.success){var p=o(f.palette);t.success({dominant:a(f.dominant.name),secondary:p[0],palette:p})}})},n.RGBaster=n.RGBaster||c}(window);引入jsinject: head: bottom: 使用对于使用，就是调用这个js，然后根据提取出来的图片设置博客的主题色就可以了，但是由于图片提取出来的颜色可能会太浅等原因，需要特殊处理下。对于里面的addRule设置变量颜色需要自行去修改。引入如下自定义js，你可以选择新建一个自定义的js文件，也可以在自己原本的自定义文件中使用。对于引入的文件需要保证在引入上述文件之后引入。// 封面纯色 function coverColor() { var path = document.getElementById("post-cover")?.src; if (path !== undefined) { RGBaster.colors(path, { paletteSize: 30, exclude: ["rgb(255,255,255)", "rgb(0,0,0)", "rgb(254,254,254)"], success: function (t) { if (t.dominant != 'rgb(66,90,239)') { const c = t.dominant.match(/\d+/g); var value = `rgb(${c[0]},${c[1]},${c[2]})`; if (getContrastYIQ(colorHex(value)) == "light") { value = LightenDarkenColor(colorHex(value), -40) } document.styleSheets[0].addRule(':root', '--Jay-main:' + …