样式预览

参考文章

新建留言板页面

1
hexo new page comments

配置

  • Page Front-matter
1
2
3
4
5
6
7
8
9
10
11

---
title: 留言板
date: 2023-12-26 22:16:14
comments: true
top_img: false
type: 'envelope'
aside: false
top_background: 'https://s11.ax1x.com/2023/12/20/pioqoNT.jpg'
---

主题配置文件

  • _config.anzhiyu.yml
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
  友链:
# 友人帐: /link/ || anzhiyu-icon-link
# 朋友圈: /fcircle/ || anzhiyu-icon-artstation
留言板: /comments/ || anzhiyu-icon-envelope

#envelope_comment
#seehttps://akilar.top/posts/e2d3c450/
envelope_comment:
enable: true #控制开关
custom_pic:
cover: https://cdn.cbd.int/naokuo-blog@1.2.12/img/posts/posts7.webp #信笺头部图片
line: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png #信笺底部图片
beforeimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png # 信封前半部分
afterimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png # 信封后半部分
message: #信笺正文,多行文本,写法如下
- 有什么想问的?
- 有什么想说的?
- 有什么想吐槽的?
- 哪怕是有什么想吃的,都可以告诉我哦~
bottom: 自动书记人偶竭诚为您服务! #仅支持单行文本
height: #1024px,信封划出的高度
easy_Danmaku_js: https://npm.onmicrosoft.cn/naokuo-blog@1.2.12/js/easy-Danmaku.js
danmu_page: '/comments/' # 即留言板地址
danmu_el: '#danmu' # 弹幕挂载节点
danmu_line: 10 # 弹幕行数
danmu_speed: 20 # 弹幕播放速度
danmu_hover: true
danmu_loop: true # 开启循环播放

新建envelope.pug

  • themes/anzhiyu/layout/includes/page/envelope.pug
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

#naokuo_envelope
- let maincontent_background = page.top_background
.author-content.author-content-item.album.single(style=`${maincontent_background ? `background: url(${maincontent_background}) top / cover no-repeat;` : ""}`)
.card-content
.author-content-item-tips 留言板
span.author-content-item-title 自动书记人偶竭诚为您服务!🤪
.content-bottom
.tips 有什么想说的,都可以告诉我哦~
.banner-button-group
a.banner-button(onclick='pjax.loadUrl("/about/")')
i.anzhiyufont.anzhiyu-icon-arrow-circle-right(style='font-size: 1.5rem')
span.banner-button-text 关于本人
#maincontent
#form-wrap
img#beforeimg.no-lightbox(src=url_for(theme.envelope_comment.custom_pic.beforeimg))
#envelope
form
.formmain(style="pointer-events: none;")
img.headerimg.no-lightbox(src=url_for(theme.envelope_comment.custom_pic.cover) style="width: 100%;overflow: hidden;pointer-events: none;")
.comments-main
h3.title3(style="text-decoration: none;color: $theme-color;text-align: center;")=`来自` + config.author + `的留言:`
.comments(style="text-align: center;border-bottom: #ddd 1px solid;border-left: #ddd 1px solid;padding-bottom: 20px;background-color: #eee;margin: 15px 0px;padding-left: 20px;padding-right: 20px;border-top: #ddd 1px solid;border-right: #ddd 1px solid;padding-top: 20px;")
each i in theme.envelope_comment.message
div=`${i}`
.bottomcontent(style="text-align: center;margin-top: 40px;")
img.bottomimg.no-lightbox(src=url_for(theme.envelope_comment.custom_pic.line) style="width: 100%;margin: 5px auto 5px auto;display: block;pointer-events: none;")
p.bottomhr(style="font-size: 12px;text-align: center;color: #999;")=`${theme.envelope_comment.bottom}`
img#afterimg.no-lightbox(src=url_for(theme.envelope_comment.custom_pic.afterimg))

if theme.envelope_comment.enable && theme.envelope_comment.easy_Danmaku_js
#danmuBtn
#danmu
style.
#article-container a:not(.headerlink, .fancybox, .default-style a) {
font-weight: 700;
color: var(--font-color);
padding: 0 3px;
border-bottom: 2px var(--anzhiyu-main) solid;
}
#article-container a:not(.headerlink, .fancybox, .default-style a):hover {
color: #fff;
border-radius: 5px;
text-decoration: none;
background-color: var(--anzhiyu-main);
}
#danmu {
width: 100%;
height: calc(100% - 60px);
position: fixed;
left: 0;
top: 60px;
z-index: 1;
pointer-events: none;
}
.hidedanmu {
opacity: 0;
}
.hidedanmu * {
pointer-events: none !important;
}
div#danmuBtn {
display: flex;
justify-content: center;
margin: var(--album-spacing-xxl) 0 0;
}
div#danmuBtn button {
background: rgba(52,106,133,.478);
color: white;
padding: 8px 20px;
margin: 0 20px;
border-radius: 100px;
}
div#danmuBtn button:hover {
background: var(--anzhiyu-main);
}
.default-style {
pointer-events: all;
cursor: pointer;
font-size: 16px;
border-radius: 100px;
overflow: hidden;
}
.default-style a {
background-color: var(--naokuo-danmuBg);
transition: .3s;
color: #eee !important;
display: flex;
align-items: center;
justify-content: center;
padding: 6px 16px 6px 6px;
text-decoration: none !important;
}
.default-style a:hover {
background-color: var(--anzhiyu-main);
}
.default-style img {
pointer-events: none;
height: 30px;
width: 30px;
margin: 0 5px 0 0 !important;
border-radius: 50% !important;
}
.default-style p {
line-height: 1;
pointer-events: none;
margin: 0 !important;
max-width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

引入envelope.pug

  • themes/anzhiyu/layout/page.pug
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

block content
#page
if top_img === false && !page.top_single
h1.page-title= page.title
case page.type
when 'tags'
include includes/page/tags.pug
when 'link'
include includes/page/flink.pug
when 'categories'
include includes/page/categories.pug
when 'essay'
include includes/page/essay.pug
when 'room'
include includes/page/room.pug
when 'about'
include includes/page/about.pug
when 'album'
include includes/page/album.pug
when 'fcircle'
include includes/page/fcircle.pug
when 'album_detail'
include includes/page/album_detail.pug
when 'music'
include includes/page/music.pug
+ when 'envelope'
+ include includes/page/envelope.pug
default
include includes/page/default-page.pug

新建danmu.pug

  • themes/anzhiyu/layout/includes/anzhiyu/danmu.pug
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
- const { envId } = theme.twikoo
- const { easy_Danmaku_js, danmu_page, danmu_el, danmu_line, danmu_speed, danmu_hover, danmu_loop } = theme.envelope_comment

script.
//- 留言板页面弹幕
window.addEventListener('load', () => {
const getnaokuo_danmu = () => {
if (!window.location.pathname.startsWith('!{danmu_page}')) return; //- 判断是否是留言板页面
const naokuo_danmu = async () => {
window.Danmaku = new EasyDanmaku({
page: '!{danmu_page}', //- 即留言板地址
el: '!{danmu_el}', //- 弹幕挂载节点
line: !{danmu_line}, //- 弹幕行数
speed: !{danmu_speed}, //- 弹幕播放速度
hover: !{danmu_hover},
loop: !{danmu_loop}, //- 开启循环播放
});
try {
let danmuStore = saveToLocal.get('danmu');
if (!danmuStore) {
const options = {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"includeReply": false,
"pageSize": 100
}),
headers: { 'Content-Type': 'application/json' }
}
danmuStore = [];
const response = await fetch(`!{envId}`, options);
if (response.ok) {
const { data } = await response.json();
//- console.info(data);
data.forEach(i => {
if (i.avatar == undefined) i.avatar = 'https://cravatar.cn/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp'
danmuStore.push({ avatar: i.avatar, content: i.nick + ':' + formatDanmaku(i.comment), url: i.url + '#' + i.id })
});
Danmaku.batchSend(danmuStore, true);
saveToLocal.set('danmu', danmuStore, 0.02)
}
//- 格式化评论
function formatDanmaku(str) {
str = str.replace(/<\/*br>|[\s\uFEFF\xA0]+/g, '');
str = str.replace(/<img.*?>/g, '[图片]');
str = str.replace(/<a.*?>.*?<\/a>/g, '[链接]');
str = str.replace(/<pre.*?>.*?<\/pre>/g, '[代码块]');
str = str.replace(/<.*?>/g, '');
return str
}
} else {
Danmaku.batchSend(danmuStore, true);
}
} catch (err) {
console.error("Error fetching data:", err);
}

document.getElementById('danmuBtn') && (document.getElementById('danmuBtn').innerHTML = `<button class="hideBtn" onclick="document.getElementById('danmu').classList.remove('hidedanmu')">显示弹幕</button> <button class="hideBtn" onclick="document.getElementById('danmu').classList.add('hidedanmu')">隐藏弹幕</button>`)
}
if (typeof Danmaku === 'object') {
naokuo_danmu()
} else {
getScript('!{url_for(easy_Danmaku_js)}').then(naokuo_danmu)
}
}
getnaokuo_danmu()
document.addEventListener('pjax:complete', getnaokuo_danmu)
})

引入danmu.pug

  • themes/anzhiyu/layout/includes/additional-js.pug
1
2
3
//- 弹幕js
if theme.envelope_comment.enable && theme.envelope_comment.easy_Danmaku_js
!= partial("includes/anzhiyu/danmu.pug", {}, { cache: true })

新建CSS样式

  • themes/anzhiyu/source/css/_page/envelope.styl
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
77
78
79
80
81
82
83
84
85
if hexo-config('envelope_comment.enable')
$hoverHeight = hexo-config('envelope_comment.height') ? convert(hexo-config('envelope_comment.height')) : 1050px
body[data-type="envelope"]
#page
border: 0
box-shadow: none !important
padding: 0 !important
background: 0 0 !important
.page-title
display: none
#maincontent
margin: var(--album-spacing-xxl) 0 0

@media screen and (max-width: 600px)
#beforeimg,
#afterimg
display: none !important

@media screen and (min-width: 600px)
#article-container img
margin: 0 auto 0rem

#form-wrap
overflow: hidden
height: 447px
position: relative
top: 0px
transition: all 1s ease-in-out .3s
z-index: 0
&:hover
height: $hoverHeight
top: -200px
will-change: transform,top

#beforeimg
position: absolute
bottom: 126px
left: 0px
background-repeat: no-repeat
width: 530px
height: 317px
z-index: -100
pointer-events: none

#afterimg
position: absolute
bottom: -2px
left: 0
background-repeat: no-repeat
width: 530px
height: 259px
z-index: 100
pointer-events: none

#envelope
position: relative
overflow: visible
width: 500px
margin: 0px auto
transition: all 1s ease-in-out .3s
padding-top: 200px
will-change: transform

#maincontent
width: 530px
margin: 20px auto 0

.formmain
background: white
width: 95%
max-width: 800px
margin: auto auto
border-radius: 5px
border: 1px solid
overflow: hidden
-webkit-box-shadow: 0px 0px 20px 0px #000000
box-shadow: 0px 0px 20px 0px #000000

// 夜间模式
[data-theme='dark']
body[data-type="envelope"]
.formmain
background: #323232
.comments
background: #5a5a5a !important

以下内容已经弃用

添加JS控制

  • themes/anzhiyu/source/js/utils.js
V1版本,已弃用
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
const NaoKuo = {
// 留言板页面弹幕
naokuo_danmu: () => {
if (!window.location.pathname.startsWith("/comments/")) return; //判断是否是留言板页面
// console.log(1);
const Danmaku = new EasyDanmaku({
page: '/comments/', // 即留言板地址
el: '#danmu', //弹幕挂载节点
line: 10, //弹幕行数
speed: 20, //弹幕播放速度
hover: true,
loop: true, //开启循环播放
})
let data = saveToLocal.get('danmu')
if (data) Danmaku.batchSend(data, true);
else {
let ls = []
fetch('https://twikoo.top/', { // 此处替换成自己的twikoo地址
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"includeReply": false,
"pageSize": 100
}),
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json()).then(({ data }) => {
data.forEach(i => {
if (i.avatar == undefined) i.avatar = 'https://cravatar.cn/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp'
ls.push({ avatar: i.avatar, content: i.nick + ':' + formatDanmaku(i.comment), url: i.url + '#' + i.id })
});
Danmaku.batchSend(ls, true);
saveToLocal.set('danmu', ls, 0.02)
});
// 格式化评论
function formatDanmaku(str) {
str = str.replace(/<\/*br>|[\s\uFEFF\xA0]+/g, '');
str = str.replace(/<img.*?>/g, '[图片]');
str = str.replace(/<a.*?>.*?<\/a>/g, '[链接]');
str = str.replace(/<pre.*?>.*?<\/pre>/g, '[代码块]');
str = str.replace(/<.*?>/g, '');
return str
}
}
document.getElementById('danmuBtn').innerHTML = `<button class="hideBtn" onclick="document.getElementById('danmu').classList.remove('hidedanmu')">显示弹幕</button> <button class="hideBtn" onclick="document.getElementById('danmu').classList.add('hidedanmu')">隐藏弹幕</button>`
}
}
  • V2版本,增加异步函数
已弃用
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
const NaoKuo = {
// 留言板页面弹幕
naokuo_danmu: async () => {
if (!window.location.pathname.startsWith("/comments/")) return; //判断是否是留言板页面
const Danmaku = new EasyDanmaku({
page: '/comments/', // 即留言板地址
el: '#danmu', //弹幕挂载节点
line: 10, //弹幕行数
speed: 20, //弹幕播放速度
hover: true,
loop: true, //开启循环播放
})
let danmuStore = saveToLocal.get('danmu')

try {
if (!danmuStore) {
const options = {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"includeReply": false,
"pageSize": 100
}),
headers: { 'Content-Type': 'application/json' }
}
danmuStore = []
const response = await fetch(`https://twikoo.top/`, options); // 此处替换成自己的twikoo地址
if (response.ok) {
const { data } = await response.json();
// console.info(data);
data.forEach(i => {
if (i.avatar == undefined) i.avatar = 'https://cravatar.cn/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp'
danmuStore.push({ avatar: i.avatar, content: i.nick + ':' + formatDanmaku(i.comment), url: i.url + '#' + i.id })
});
Danmaku.batchSend(danmuStore, true);
saveToLocal.set('danmu', danmuStore, 0.02)
}
// 格式化评论
function formatDanmaku(str) {
str = str.replace(/<\/*br>|[\s\uFEFF\xA0]+/g, '');
str = str.replace(/<img.*?>/g, '[图片]');
str = str.replace(/<a.*?>.*?<\/a>/g, '[链接]');
str = str.replace(/<pre.*?>.*?<\/pre>/g, '[代码块]');
str = str.replace(/<.*?>/g, '');
return str
}
} else {
Danmaku.batchSend(danmuStore, true);
}
} catch (err) {
console.error("Error fetching data:", err);
}
document.getElementById('danmuBtn') && (document.getElementById('danmuBtn').innerHTML = `<button class="hideBtn" onclick="document.getElementById('danmu').classList.remove('hidedanmu')">显示弹幕</button> <button class="hideBtn" onclick="document.getElementById('danmu').classList.add('hidedanmu')">隐藏弹幕</button>`)
}
}

引入JS控制

已弃用
  • 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
    // needRefresh
// nav中间的标题变化
document.getElementById("page-name").innerText = document.title.split(` | ${GLOBAL_CONFIG_SITE.configTitle}`)[0];
anzhiyu.initIndexEssay();
anzhiyu.changeTimeInEssay();
anzhiyu.removeBodyPaceClass();
anzhiyu.qrcodeCreate();
anzhiyu.changeTimeInAlbumDetail();
anzhiyu.reflashEssayWaterFall();
anzhiyu.sayhi();
anzhiyu.stopImgRightDrag();
anzhiyu.addNavBackgroundInit();
anzhiyu.setValueToBodyType();
anzhiyu.catalogActive();
anzhiyu.tagsPageActive();
anzhiyu.categoriesBarActive();
anzhiyu.topCategoriesBarScroll();
anzhiyu.switchRightClickMenuHotReview();
anzhiyu.getCustomPlayList();
anzhiyu.addEventListenerConsoleMusicList(false);
anzhiyu.initPaginationObserver();
+ // 以上是原有的
+ // 留言板页面弹幕
+ NaoKuo.naokuo_danmu();