Hexo个人博客之Next-8.20主题下载及美化
安装next主题
下载next主题,cd到博客文件中
npm install hexo-theme-next
,下载完成后博客文件的themes文件会出现next文件,这就是记事本打开hexo中的_config.yml文件,将theme的值改为next至此next安装完成
配置及美化next
设置主题模式
打开next主题的配置文件:_config.yml,ctrl+f,搜索scheme,旗下的四个值即为next的四种主题模式,想用哪个主题就把那个主题的
#
去掉,再把不用的加上#
,我用的Gemini主题模式,# Schemes #scheme: Muse #scheme: Mist #scheme: Pisces scheme: Gemini
设置菜单
在配置文件中搜索:menu
# 菜单选项设置
menu:
home: / || fa fa-home # 跳转主页
tags: /tags/ || fa fa-tags # 标签
categories: /categories/ || fa fa-th # 分类
archives: /archives/ || fa fa-archive # 归档
schedule: /schedule/ || fa fa-calendar # 日程表
#sitemap: /sitemap.xml || fa fa-sitemap # 站点地图
#commonweal: /404/ || fa fa-heartbeat # 公益404
about: /about/ || fa fa-user
# 菜单表现设置
menu_settings:
icons: true #选项图标是否显示
badges: true #菜单某选项内容的显示总数量
开启菜单:标签/分类/日程表功能
- 建立tags/categories/schedule文件夹及其index.md文档
hexo new page tags/categories/schedule
修改对应index.md文档内容(以categories举例)
--- title: 分类 date: 2024-05-15 18:38:43 type: "categories" ---
开启社交功能:
在_config.yml中搜索social
social:
GitHub: https://github.com/xxxxx || fab fa-github
E-Mail: mailto:xxxxxx@qq.com || fa fa-envelope
#Weibo: https://weibo.com/yourname || fab fa-weibo
#Twitter: https://twitter.com/yourname || fab fa-twitter
#FB Page: https://www.facebook.com/yourname || fab fa-facebook
#StackOverflow: https://stackoverflow.com/yourname || fab fa-stack-overflow
#YouTube: https://youtube.com/yourname || fab fa-youtube
#Instagram: https://instagram.com/yourname || fab fa-instagram
#Skype: skype:yourname?call|chat || fab fa-skype
开启阅读进度及回到顶部功能:
在_config.yml中搜索back2top
back2top:
enable: true
sidebar: false # 回到顶部在侧边栏。
scrollpercent: true # 以百分比的形式展示阅读进度
添加live2D看板娘
- 下载live2d文件
npm install --save hexo-helper-live2d
- 下载live2d模型文件
npm install live2d-widget-model-模型名字
具体查看小人样式请移步https://blog.csdn.net/wang_123_zy/article/details/87181892 - 配置hexo的_config.yml文件
#Live2D
live2d:
enable: true
pluginModelPath: assets/ # 模型文件相对与插件根目录路径
model:
use: live2d-widget-model-shizuku # npm-module package name
display:
position: right
width: 150
height: 300
mobile:
show: true # 手机中是否展示
添加鼠标点击特效
取消next的_config.yml文件中bodyEnd的注释
添加配置项
# 鼠标点击特效 # 鼠标点击效应: fireworks(礼花) | explosion(爆炸) | love(爱心) | text(文字) cursor_effect: text
在
next/source/_data
文件下创建body-end.njk
并复制以下代码{ # 鼠标点击特效 #} { % if theme.cursor_effect == "fireworks" %} <script async src="/js/cursor/fireworks.js"></script> { % elseif theme.cursor_effect == "explosion" %} <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas> <script src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> <script async src="/js/cursor/explosion.min.js"></script> { % elseif theme.cursor_effect == "love" %} <script async src="/js/cursor/love.min.js"></script> { % elseif theme.cursor_effect == "text" %} <script async src="/js/cursor/text.js"></script> { % endif %}
themes/next/source/js/cursor/目录下创建特效js文件
- 文字点击特效(推荐),数组内文字按顺序出现,字体颜色随机
var a_idx = 0;
jQuery(document).ready(function($) {
var colorNames = ["#333", "rgb(77,64,48)"/*淡松烟*/, "rgb(238,160,140)"/*淡罂粟红*/, "rgb(243,71,24)"/*榴花红*/,"rgb(32,137,77)"/*鲸鱼灰*/, "rgb(71,81,100)"/*宫殿绿*/, "red", "Fuchsia", "MediumAquamarine", "yellow", " Blue", "DarkOrange", "MediumSpringGreen", "Crimson"];
$("body").click(function(e) {
var a = ["轻轻的我走了", "正如我轻轻的来", "我轻轻的招手", "作别西天的云彩", "那河畔的金柳", "是夕阳中的新娘",
"波光里的艳影", "在我的心头荡漾", "软泥上的青荇", "油油的在水底招摇", "在康河的柔波里", "我甘心做一条水草!", "那榆荫下的一潭",
"不是清泉,是天上虹", "揉碎在浮藻间", "沉淀着彩虹似的梦", "寻梦?撑一支长篙", "向青草更青处漫溯", "满载一船星辉", "在星辉斑斓里放歌",
"但我不能放歌", "悄悄是别离的笙箫", "夏虫也为我沉默", "沉默是今晚的康桥!", "悄悄的我走了", "正如我悄悄的来", "我挥一挥衣袖", "不带走一片云彩"];
var $i = $("<span/>")
.text(a[a_idx])
.css({
"user-select": "none", // 防止复制
"font-family": '"Kaiti SC", "KaiTi", "楷体", serif', // 设置楷体
"font-size": "16px", // 示例:设置字体大小为16像素
// 可以继续添加更多样式,如字体加粗、斜体等
});
var randomColorName = colorNames[Math.floor(Math.random() * colorNames.length)];
var x = e.pageX,
y = e.pageY;
$i.css({
"z-index": 99999,
"top": y - 28,
"left": x - a[a_idx].length * 8,
"position": "absolute"
});
// 动态应用颜色
setTimeout(function() {
$i.css("color", randomColorName);
}, 0); // 确保颜色在元素添加到DOM后改变
$("body").append($i);
$i.animate({
"top": y - 180,
"opacity": 0
}, 1500, function() {
$i.remove();
});
a_idx = (a_idx + 1) % a.length;
});
});
2. 礼炮特效
class Circle {
constructor({
origin, speed, color, angle, context }) {
this.origin = origin
this.position = {
...this.origin }
this.color = color
this.speed = speed
this.angle = angle
this.context = context
this.renderCount = 0
}
draw() {
this.context.fillStyle = this.color
this.context.beginPath()
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
this.context.fill()
}
move() {
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
this.renderCount++
}
}
class Boom {
constructor ({
origin, context, circleCount = 16, area }) {
this.origin = origin
this.context = context
this.circleCount = circleCount
this.area = area
this.stop = false
this.circles = []
}
randomArray(range) {
const length = range.length
const randomIndex = Math.floor(length * Math.random())
return range[randomIndex]
}
randomColor() {
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
}
randomRange(start, end) {
return (end - start) * Math.random() + start
}
init() {
for(let i = 0; i < this.circleCount; i++) {
const circle = new Circle({
context: this.context,
origin: this.origin,
color: this.randomColor(),
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
speed: this.randomRange(1, 6)
})
this.circles.push(circle)
}
}
move() {
this.circles.forEach((circle, index) => {
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
return this.circles.splice(index, 1)
}
circle.move()
})
if (this.circles.length == 0) {
this.stop = true
}
}
draw() {
this.circles.forEach(circle => circle.draw())
}
}
class CursorSpecialEffects {
constructor() {
this.computerCanvas = document.createElement('canvas')
this.renderCanvas = document.createElement('canvas')
this.computerContext = this.computerCanvas.getContext('2d')
this.renderContext = this.renderCanvas.getContext('2d')
this.globalWidth = window.innerWidth
this.globalHeight = window.innerHeight
this.booms = []
this.running = false
}
handleMouseDown(e) {
const boom = new Boom({
origin: {
x: e.clientX, y: e.clientY },
context: this.computerContext,
area: {
width: this.globalWidth,
height: this.globalHeight
}
})
boom.init()
this.booms.push(boom)
this.running || this.run()
}
handlePageHide() {
this.booms = []
this.running = false
}
init() {
const style = this.renderCanvas.style
style.position = 'fixed'
style.top = style.left = 0
style.zIndex = '999999999999999999999999999999999999999999'
style.pointerEvents = 'none'
style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight
document.body.append(this.renderCanvas)
window.addEventListener('mousedown', this.handleMouseDown.bind(this))
window.addEventListener('pagehide', this.handlePageHide.bind(this))
}
run() {
this.running = true
if (this.booms.length == 0) {
return this.running = false
}
requestAnimationFrame(this.run.bind(this))
this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
this.booms.forEach((boom, index) => {
if (boom.stop) {
return this.booms.splice(index, 1)
}
boom.move()
boom.draw()
})
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
}
}
const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()
3. 爆炸特效
"use strict";function updateCoords(e){
pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){
var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{
x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){
var a={
};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){
ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){
var a={
};return a.x=e,a.y=t,a.color="#F00",a.radius=.1,a.alpha=.5,a.lineWidth=6,a.draw=function(){
ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){
for(var t=0;t<e.animatables.length;t++)e.animatables[t].target.draw()}function animateParticules(e,t){
for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++)n.push(createParticule(e,t));anime.timeline().add({
targets:n,x:function(e){
return e.endPos.x},y:function(e){
return e.endPos.y},radius:.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({
targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{
value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){
var a;return function(){
var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){
e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){
var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){
canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({
duration:1/0,update:function(){
ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){
"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)}
4. 爱心特效
!function(e,t,a){
function n(){
c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){
for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){
var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){
t&&t(),i(e)}}function i(e){
var a=t.createElement("div");a.className="heart",d.push({
el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){
var a=t.createElement("style");a.type="text/css";try{
a.appendChild(t.createTextNode(e))}catch(t){
a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){
return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){
return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){
setTimeout(e,1e3/60)}}(),n()}(window,document);