
本文记录我博客从matery主题转butterfly主题的记录(matery还是很优秀的,感谢它能成为我的入门主题)
其实换主题已经有一段时间了,由于期末一下没太多时间整理,一耽搁,有些修改可能忘了,我就把能想起来的先记录下来,以备不时之需(所以,后续不定时更新)
由于想要增添一些新东西,原来使用的matery主题现有的布局,我认为再增添上东西后会影响布局的美观。在寻找解决方案的过程中,我发现了butterfly这个主题。该主题不但内容丰富、布局美观,并且自带了昼夜切换以及其侧边栏有较高的可拓展性。经过深思熟虑后,觉得将主题更换为butterfly主题。
【转载说明】本文优先发布于我的个人博客www.226yzy.com ,转载请注明出处并注明作者:星空下的YZY。 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0许可协议。
更好的阅读体验欢迎访问原文 https://226yzy.com/2022/010948485.html
建议自己新建一个CSS文件,然后在主题配置文件的中引入、
该主题的样板网站上有主题作者的详细的基础教程
传送门🚪 https://butterfly.js.org/
不得不说作者大大非常用心,这几篇教程不止基础修改配置,还有一些进阶魔改的内容,跟着做下来可DIY的地方非常多
这里不推荐使用主题作者推荐的那个地图,至少可以很明显看出来藏南地区有问题
这里推荐使用 https://www.revolvermaps.com/?target=gallery
这里需要注意使用无国旗标注的版本,不然台湾省那还是会有问题。维护国家主权和领土完整、坚持一个中国的原则是每个公民应尽的责任和义务。
更详细的操作请阅览官方文档https://waline.js.org/
需要用到这个网站 https://vercel.com/
完整教程参考https://twikoo.js.org/
同样需要用到这个网站 https://vercel.com/
在主题配置文件的中添加如下(当然把相关信息填成你自己的),如果添加后没效果,可能是插件没安装,其他相关的可以查看其中文文档https://aplayer.js.org/#/zh-Hans/
- <div class="aplayer no-destroy" data-id="6804316983" data-server="netease" data-type="playlist" data-fixed="true" data-mini="true" data-listFolded="true" data-order="random" data-preload="auto" data-autoplay="false" muted></div> 加入Aplayer音乐播放器后,发现没有直接是matery主题那样侧栏伸缩的效果。后来我找到了Akilar大佬的解决方案 https://akilar.top/posts/ebf20e02/
在主题目录下添加如下代码
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
left: -66px !important;
/* 默认情况下缩进左侧66px,只留一点箭头部分 */
}
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
left: 0 !important;
/* 鼠标悬停是左侧缩进归零,完全显示按钮 */
} 看板娘
这个我在matery主题的时候就弄过了,你直接将这三行添加至主题配置文件的中
- <script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css" />
- <script src="https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget/autoload.min.js"></script> 滚动条
美化滚动条嘛,我比较喜欢蓝白相间的。将下面的代码加入到你自己的CSS中即可
/* 滚动条 */
::-webkit-scrollbar-thumb {
background-color: #2ab1ff;
background-image: -webkit-linear-gradient(
45deg,
rgba(255, 255, 255, 0.4) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.4) 50%,
rgba(255, 255, 255, 0.4) 75%,
transparent 75%,
transparent
);
border-radius: 3em;
}
::-webkit-scrollbar-track {
background-color: #ffffff;
border-radius: 3em;
}
::-webkit-scrollbar {
width: 8px;
height: 15px;
} 修改字体
在你的CSS文件中按这个格式添加你的字体,然后在主题配置文件的相关配置中引用
@font-face{
font-family:'DIYJH' ;
src:url('/fonts/FZZJ-JHTJW.TTF');
font-display : swap;
} 如果你的字体文件过大又舍不得不用,可以参考我另一篇文章,
https://226yzy.com/2021/122648049.html
具体参考自https://www.antmoe.com/posts/2db95804/#自动提交网址给百度
不过小康大佬给的代码库地址似乎没法用了
如果不嫌弃可以用我这个代码库地址
https://github.com/226yzy/Hexo-BaiduPush.git
底部栏些许单调,有一次看到了底部跳动的鱼的效果还不错(效果可参考我的博客[226yzy.com]底部栏)
引用自https://weilining.github.io/206.html
在主题文件下的js文件中新建一个的js文件,然后在其中添加
fish();
function fish() {
return (
$("footer").append(
'<div id="jsi-flying-fish-container"></div>'
),
$(".container").css({
width: "100%",
height: "160px",
margin: 0,
padding: 0,
}),
$("#footer-wrap").css({
position: "absolute",
"text-align": "center",
top: 0,
right: 0,
left: 0,
bottom: 0,
}),
this
);
}
var RENDERER = {
POINT_INTERVAL: 5,
FISH_COUNT: 2,
MAX_INTERVAL_COUNT: 50,
INIT_HEIGHT_RATE: 0.5,
THRESHOLD: 50,
init: function () {
this.setParameters();
this.reconstructMethods();
this.setup();
this.bindEvent();
this.render();
},
setParameters: function () {
this.$window = $(window);
this.$container = $("#jsi-flying-fish-container");
this.$canvas = $("<canvas />");
this.context = this.$canvas
.appendTo(this.$container)
.get(0)
.getContext("2d");
this.points = [];
this.fishes = [];
this.watchIds = [];
},
createSurfacePoints: function () {
var count = Math.round(this.width / this.POINT_INTERVAL);
this.pointInterval = this.width / (count - 1);
this.points.push(new SURFACE_POINT(this, 0));
for (var i = 1; i < count; i++) {
var point = new SURFACE_POINT(this, i * this.pointInterval),
previous = this.points[i - 1];
point.setPreviousPoint(previous);
previous.setNextPoint(point);
this.points.push(point);
}
},
reconstructMethods: function () {
this.watchWindowSize = this.watchWindowSize.bind(this);
this.jdugeToStopResize = this.jdugeToStopResize.bind(this);
this.startEpicenter = this.startEpicenter.bind(this);
this.moveEpicenter = this.moveEpicenter.bind(this);
this.render = this.render.bind(this);
},
setup: function () {
this.points.length = 0;
this.fishes.length = 0;
this.watchIds.length = 0;
this.intervalCount = this.MAX_INTERVAL_COUNT;
this.width = this.$container.width();
this.height = this.$container.height();
this.fishCount =
(((this.FISH_COUNT * this.width) / 500) * this.height) / 500;
this.$canvas.attr({ width: this.width, height: this.height });
this.skyGradient = this.context.createLinearGradient(0, 0, 0, this.height);
this.skyGradient.addColorStop(0, "hsl(180, 80%, 70%)");
this.skyGradient.addColorStop(1, "hsl(180, 80%, 90%)");
this.seaGradient = this.context.createLinearGradient(0, 0, 0, this.height);
this.seaGradient.addColorStop(0, "hsl(180, 80%, 60%)");
this.seaGradient.addColorStop(0.5, "hsl(180, 80%, 50%)");
this.seaGradient.addColorStop(1, "hsl(210, 80%, 50%)");
this.fishes.push(new FISH(this));
this.createSurfacePoints();
},
watchWindowSize: function () {
this.clearTimer();
this.tmpWidth = this.$window.width();
this.tmpHeight = this.$window.height();
this.watchIds.push(setTimeout(this.jdugeToStopResize, this.WATCH_INTERVAL));
},
clearTimer: function () {
while (this.watchIds.length > 0) {
clearTimeout(this.watchIds.pop());
}
},
jdugeToStopResize: function () {
var width = this.$window.width(),
height = this.$window.height(),
stopped = width == this.tmpWidth && height == this.tmpHeight;
this.tmpWidth = width;
this.tmpHeight = height;
if (stopped) {
this.setup();
}
},
bindEvent: function () {
this.$window.on("resize", this.watchWindowSize);
this.$container.on("mouseenter", this.startEpicenter);
this.$container.on("mousemove", this.moveEpicenter);
},
getAxis: function (event) {
var offset = this.$container.offset();
return {
x: event.clientX - offset.left + this.$window.scrollLeft(),
y: event.clientY - offset.top + this.$window.scrollTop(),
};
},
startEpicenter: function (event) {
this.axis = this.getAxis(event);
},
moveEpicenter: function (event) {
var axis = this.getAxis(event);
if (!this.axis) {
this.axis = axis;
}
this.generateEpicenter(axis.x, axis.y, axis.y - this.axis.y);
this.axis = axis;
},
generateEpicenter: function (x, y, velocity) {
if (
y < this.height / 2 - this.THRESHOLD ||
y > this.height / 2 + this.THRESHOLD
) {
return;
}
var index = Math.round(x / this.pointInterval);
if (index < 0 || index >= this.points.length) {
return;
}
this.points[index].interfere(y, velocity);
},
controlStatus: function () {
for (var i = 0, count = this.points.length; i < count; i++) {
this.points[i].updateSelf();
}
for (var i = 0, count = this.points.length; i < count; i++) {
this.points[i].updateNeighbors();
}
if (this.fishes.length < this.fishCount) {
if (--this.intervalCount == 0) {
this.intervalCount = this.MAX_INTERVAL_COUNT;
this.fishes.push(new FISH(this));
}
}
},
render: function () {
requestAnimationFrame(this.render);
this.controlStatus();
this.context.fillStyle = this.skyGradient;
this.context.fillRect(0, 0, this.width, this.height);
this.context.fillStyle = this.seaGradient;
this.context.beginPath();
this.context.moveTo(0, this.height);
for (var i = 0, count = this.points.length; i < count; i++) {
this.points[i].render(this.context);
}
this.context.lineTo(this.width, this.height);
this.context.closePath();
this.context.fill();
for (var i = 0, count = this.fishes.length; i < count; i++) {
this.fishes[i].render(this.context);
}
},
};
var SURFACE_POINT = function (renderer, x) {
this.renderer = renderer;
this.x = x;
this.init();
};
SURFACE_POINT.prototype = {
SPRING_CONSTANT: 0.03,
SPRING_FRICTION: 0.9,
WAVE_SPREAD: 0.3,
ACCELARATION_RATE: 0.01,
init: function () {
this.initHeight = this.renderer.height * this.renderer.INIT_HEIGHT_RATE;
this.height = this.initHeight;
this.fy = 0;
this.force = { previous: 0, next: 0 };
},
setPreviousPoint: function (previous) {
this.previous = previous;
},
setNextPoint: function (next) {
this.next = next;
},
interfere: function (y, velocity) {
this.fy =
this.renderer.height *
this.ACCELARATION_RATE *
(this.renderer.height - this.height - y >= 0 ? -1 : 1) *
Math.abs(velocity);
},
updateSelf: function () {
this.fy += this.SPRING_CONSTANT * (this.initHeight - this.height);
this.fy *= this.SPRING_FRICTION;
this.height += this.fy;
},
updateNeighbors: function () {
if (this.previous) {
this.force.previous =
this.WAVE_SPREAD * (this.height - this.previous.height);
}
if (this.next) {
this.force.next = this.WAVE_SPREAD * (this.height - this.next.height);
}
},
render: function (context) {
if (this.previous) {
this.previous.height += this.force.previous;
this.previous.fy += this.force.previous;
}
if (this.next) {
this.next.height += this.force.next;
this.next.fy += this.force.next;
}
context.lineTo(this.x, this.renderer.height - this.height);
},
};
var FISH = function (renderer) {
this.renderer = renderer;
this.init();
};
FISH.prototype = {
GRAVITY: 0.4,
init: function () {
this.direction = Math.random() < 0.5;
this.x = this.direction
? this.renderer.width + this.renderer.THRESHOLD
: -this.renderer.THRESHOLD;
this.y = this.getRandomValue(
(this.renderer.height * 6) / 10,
(this.renderer.height * 9) / 10
);
this.previousY = this.y;
this.vx = this.getRandomValue(4, 10) * (this.direction ? -1 : 1);
this.vy = this.getRandomValue(-5, -2);
this.ay = this.getRandomValue(-0.2, -0.05);
this.theta = 0;
this.phi = 0;
this.isOut = false;
},
getRandomValue: function (min, max) {
return min + (max - min) * Math.random();
},
controlStatus: function (context) {
this.previousY = this.y;
this.x += this.vx;
this.y += this.vy;
this.vy += this.ay;
if (this.y < this.renderer.height * this.renderer.INIT_HEIGHT_RATE) {
this.vy += this.GRAVITY;
this.isOut = true;
} else {
if (this.isOut) {
this.ay = this.getRandomValue(-0.2, -0.05);
}
this.isOut = false;
}
if (!this.isOut) {
this.theta += Math.PI / 20;
this.theta %= Math.PI * 2;
this.phi += Math.PI / 30;
this.phi %= Math.PI * 2;
}
this.renderer.generateEpicenter(
this.x + (this.direction ? -1 : 1) * this.renderer.THRESHOLD,
this.y,
this.y - this.previousY
);
if (
(this.vx > 0 && this.x > this.renderer.width + this.renderer.THRESHOLD) ||
(this.vx < 0 && this.x < -this.renderer.THRESHOLD)
) {
this.init();
}
},
render: function (context) {
context.save();
context.translate(this.x, this.y);
context.rotate(Math.PI + Math.atan2(this.vy, this.vx));
context.scale(1, this.direction ? 1 : -1);
context.fillStyle = "hsl(180, 30%, 80%)";
context.beginPath();
context.moveTo(-30, 0);
context.bezierCurveTo(-20, 15, 15, 10, 40, 0);
context.bezierCurveTo(15, -10, -20, -15, -30, 0);
context.fill();
context.save();
context.translate(40, 0);
context.scale(0.9 + 0.2 * Math.sin(this.theta), 1);
context.fillStyle = "hsl(180, 30%, 80%)";
context.beginPath();
context.moveTo(0, 0);
context.quadraticCurveTo(5, 10, 20, 8);
context.quadraticCurveTo(12, 5, 10, 0);
context.quadraticCurveTo(12, -5, 20, -8);
context.quadraticCurveTo(5, -10, 0, 0);
context.fill();
context.restore();
context.save();
context.translate(-3, 0);
context.rotate(Math.PI / 3 + (Math.PI / 10) * Math.sin(this.phi));
context.fillStyle = "hsl(220, 80%, 40%)";
context.beginPath();
context.moveTo(-5, 0);
context.bezierCurveTo(-10, -10, -10, -30, 0, -40);
context.bezierCurveTo(12, -25, 8, -10, 0, 0);
context.closePath();
context.fill();
context.restore();
context.strokeStyle = "hsl(220, 80%, 40%)";
context.beginPath();
context.arc(-15, -3, 5, 0, Math.PI * 2, false);
context.stroke();
context.fillStyle = "hsl(220, 80%, 40%)";
context.beginPath();
context.arc(-15, -3, 3, 0, Math.PI * 2, false);
context.fill();
context.restore();
this.controlStatus(context);
},
};
$(function () {
RENDERER.init();
}); 主题配置文件的中引入
如果没有引入过的话也需要引入一下
其他参考:https://codepen.io/K-T/pen/qQZwzQ
美化鼠标光标,这个我在matery主题时简单弄过,后来看到Akilar大佬整理过,我用的如下
/*光标*/
/* 全局默认鼠标指针 */
body,
html {
cursor: url('../coursor/guangbiao.ico'), auto !important;
}
/* 悬停图片时的鼠标指针 */
img {
cursor: url('../coursor/Comix_White_Link.cur'), auto !important;
}
/* 选择链接标签时的鼠标指针 */
a:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
}
/* 选中输入框时的鼠标指针 */
/* input:hover {
cursor: url('../coursor/Comix_White_Text.cur'), auto;
} */
/* 悬停按钮时的鼠标指针 */
button:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
}
/* 悬停列表标签时的鼠标指针 */
i:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
}
/* 悬停页脚链接标签(例如页脚徽标)时的鼠标指针 */
#footer-wrap a:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
}
/* 悬停页码时的鼠标指针 */
#pagination .page-number:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
}
/* 悬停菜单栏时的鼠标指针 */
#nav .site-page:hover {
cursor: url('../coursor/Comix_White_Link.cur'), auto;
} 文章加密
matery主题中自带了文章加密功能
这个虽然一般情况用不到,但有些供自己参考的试验性内容,还是有可能使用的
注该文章加密后,代码块一键复制的效果将会没有
安装文章加密插件
npm install --save hexo-blog-encrypt 然后文章头部信息中加入属性
如果对原版配置内容不满意,可以在主题配置文件中自定义
encrypt:
enable: true
default_abstract: 这是一篇加密文章,内容可能是个人试验内容水平有限暂不公开。如果你确实想看,请与我联系。
default_message: 输入密码,查看文章。 如果想特定的文章做特殊处理,可在文章头部信息中添加来写提示内容
matery主题时参考过https://notes.zhangxiaocai.cn/posts/7496029d.html
现在Butterfly主题参考的是https://akilar.top/posts/f99b208/
这个还是参考Akilar大佬的https://akilar.top/posts/abab51cf/
大佬还是强啊,懂的多
大佬的插件包:https://zfe.space/post/hexo-butterfly-orchid.html
有六个插件,可按需使用
你还在为看这么多大佬的博客烦恼吗,那友链朋友圈就非常适合你了
页面效果参考https://226yzy.com/fcircle/index.html
不过这个流程较长,建议参考制作这个项目的大佬们的教程
比如小冰大佬的
https://zfe.space/post/friend-link-circle.html
或者贰猹大佬的
https://noionion.top/47095.html
上面两篇参考的部署的API不同,前端页面效果也不同,按自己喜好取用
另外matery主题的朋友也可以参考另一位大佬的教程
https://hesifan.top/posts/21326.html
参考自https://guole.fun/posts/butterfly-custom/
在博客根目录(没有请自行创建) 下新建 文件,通过路径就会随机跳转一篇文章。
内容如下
hexo.extend.generator.register('random', function (locals) {
const config = hexo.config.random || {}
const posts = []
for (const post of locals.posts.data) {
if (post.random !== false) posts.push(post.path)
}
return {
path: config.path || 'random/index.html',
data: `<html><head><script>var posts=${JSON.stringify(posts)};window.open('/'+posts[Math.floor(Math.random() * posts.length)],"_self")</script></head></html>`
}
}) 可以在博客配置文件添加以下配置:
random:
path: # 随机链接路径,默认"random/index.html"
如果不想随机跳转到某篇文章,可以在这篇文章 md 文件头部,添加:
random: false 星空和流星背景特效
暗夜模式下星空和流星背景特效
采用大佬的方案https://blog.justlovesmile.top/posts/6a260bf6.html
插入Canvas标签 首先打开Butterfly主题配置文件_config.yml文件或者使用HTML直接插入,找到配置文件对应的inject部分,插入<canvas id="universe"></canvas>
创建JS文件 在butterfly/source/js/创建一个universe.js文件,或者添加到自己的js文件中
function dark() {window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;var n,e,i,h,t=.05,s=document.getElementById(&quot;universe&quot;),o=!0,a=&quot;180,184,240&quot;,r=&quot;226,225,142&quot;,d=&quot;226,225,224&quot;,c=[];function f(){n=window.innerWidth,e=window.innerHeight,i=.216*n,s.setAttribute(&quot;width&quot;,n),s.setAttribute(&quot;height&quot;,e)}function u(){h.clearRect(0,0,n,e);for(var t=c.length,i=0;i&lt;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&amp;&amp;!o&amp;&amp;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(.2,1-.4*(this.comet+1-1)),this.do=l(5e-4,.002)+.001*(this.comet+1-1)},this.fadeIn=function(){this.fadingIn&amp;&amp;(this.fadingIn=!(this.opacity&gt;this.opacityTresh),this.opacity+=this.do)},this.fadeOut=function(){this.fadingOut&amp;&amp;(this.fadingOut=!(this.opacity&lt;0),this.opacity-=this.do/2,(this.x&gt;n||this.y&lt;0)&amp;&amp;(this.fadingOut=!1,this.reset()))},this.draw=function(){if(h.beginPath(),this.giant)h.fillStyle=&quot;rgba(&quot;+a+&quot;,&quot;+this.opacity+&quot;)&quot;,h.arc(this.x,this.y,2,0,2*Math.PI,!1);else if(this.comet){h.fillStyle=&quot;rgba(&quot;+d+&quot;,&quot;+this.opacity+&quot;)&quot;,h.arc(this.x,this.y,1.5,0,2*Math.PI,!1);for(var t=0;t&lt;30;t++)h.fillStyle=&quot;rgba(&quot;+d+&quot;,&quot;+(this.opacity-this.opacity/20*t)+&quot;)&quot;,h.rect(this.x-this.dx/4*t,this.y-this.dy/4*t-2,2,2),h.fill()}else h.fillStyle=&quot;rgba(&quot;+r+&quot;,&quot;+this.opacity+&quot;)&quot;,h.rect(this.x,this.y,this.r,this.r);h.closePath(),h.fill()},this.move=function(){this.x+=this.dx,this.y+=this.dy,!1===this.fadingOut&amp;&amp;this.reset(),(this.x&gt;n-n/4||this.y&lt;0)&amp;&amp;(this.fadingOut=!0)},setTimeout(function(){o=!1},50)}function m(t){return Math.floor(1e3*Math.random())+1&lt;10*t}function l(t,i){return Math.random()*(i-t)+t}f(),window.addEventListener(&quot;resize&quot;,f,!1),function(){h=s.getContext(&quot;2d&quot;);for(var t=0;t&lt;i;t++)c[t]=new y,c[t].reset();u()}(),function t(){document.getElementsByTagName(&#39;html&#39;)[0].getAttribute(&#39;data-theme&#39;)==&#39;dark&#39;&amp;&amp;u(),window.requestAnimationFrame(t)}()};
dark() CSS样式
/* 背景宇宙星光 */
#universe{
display: block;
position: fixed;
margin: 0;
padding: 0;
border: 0;
outline: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: -1;
}