点击查看更新记录
更新记录
2023-01-03:内测版
点击查看参考教程
参考方向 | 教程原贴 |
---|---|
参考了UI风格和配色样式 | Neon-Space-Rainmeter |
参考了UI风格和配色样式 | JARVIS-Highpitched-OS |
fontawesome图标文档 | fontawesome |
Flex布局参数解释 | Flex 布局教程:语法篇 - 阮一峰的网络日志 |
Transition属性实现平滑过渡动画 | CSS3实现伪类hover离开时平滑过渡效果示例 |
CSS伪类实现三角形绘制 | 纯CSS 实现绘制各种三角形(各种角度) - saucxs - 博客园 |
使用clip-path实现多边形剪裁。 | 不可思议的CSS之clip-path |
站内教程:iconfont引入教程 | Hexo引入阿里矢量图标库 |
swiper中文文档,查看初始化参数 | Swiper中文网 |
点击查看预览效果
本篇讨论的轮播图的配置项可能与hexo-butterfly-swiper插件的配置项有冲突,如果您曾经安装过该插件或者该插件的衍生插件(例如anzhiyu、anzhiyupro、allbs、ihao、lyx、btmuli,一查才知道已经有这么多亚种了吗)。请确保您已经卸载了它们。
npm uninstall hexo-butterfly-swiper --save
本篇沿用了源计划-方舟:首页卡片中用到的部分方案,为保证样式完整,且避免报错,推荐先完成首页卡片的魔改后再考虑使用本方案。
本篇需要用到iconfont作为卡片底部的装饰性图标。请先完成前置教程:Hexo引入阿里矢量图标库,务必确保symbol方案能够使用后再进行下方内容。
新建[Blogroot]\themes\butterfly\scripts\helpers\cybericon.js
,这个js的作用是返回一个随机的图标值,逢年过节的还能换成喜庆点的图标,注意以下icon[]内部的图标均为我个人图标库内的图标名称。请务必记得替换成你自己的图标。且这是个内部函数,必须保证在scripts目录下,不要自作聪明建在别的目录还到inject配置项去引入。
hexo.extend.helper.register('cybericon', function () {
var icon = [
'#icon-fukong',
'#icon-fan',
'#icon-partial-discharge',
'#icon-menu-zizhanbaowei',
'#icon-YunTai-unfold',
'#icon-camera-GOTO_PRESET',
'#icon-d3',
'#icon-copy',
'#icon-config'
]
var index = Math.floor(Math.random()*icon.length);
return icon[index]
});
新建[Blogroot]\themes\butterfly\scripts\helpers\swiperbar.js
,这个脚本的作用是返回在front-matter设置了swiper_index数值的文件。
'use strict'
hexo.extend.helper.register('swiper_list', function (locals) {
var posts_list = hexo.locals.get('posts').data;
var swiper_list = []
// 若文章的front_matter内设置了index和描述,则将其放到swiper_list内
for (var item of posts_list) {
if (item.swiper_index) {
swiper_list.push(item)
}
}
// 对swiper_list进行处理,使其按照index大小进行排序
function sortNumber(a, b) {
return a.swiper_index - b.swiper_index
}
swiper_list = swiper_list.sort(sortNumber);
// 排序反转,使得数字越大越靠前
swiper_list = swiper_list.reverse();
return swiper_list;
})
新建[Blogroot]\themes\butterfly\layout\includes\custom\cyber_swiperBar.pug
,
.recent-post-item#swiperBar
#cyber-swiper-container
.swiper-wrapper.cyber-swiper-wrapper
//- 文章卡片
if theme.pjax.enable
each item in swiper_list()
//- 内容版块
.swiper-slide.cyber-swiper-item
//- 封面
.cyber-swiper-item-cover
img.article-cover(src=item.cover title='' onerror=`this.src=` + theme.swiperBar.error_img + `; this.onerror = null;`)
//- 时间
if (theme.swiperBar.timemode === 'updated' )
.cyber-swiper-item-time
span='updated:'
span= item.updated.format('YYYY-MM-DD')
else
.cyber-swiper-item-time
span='published:'
span= item.date.format('YYYY-MM-DD')
//- 标题和描述
.cyber-swiper-item-info
a.cyber-swiper-item-title(onclick=`pjax.loadUrl("` + item.path + `");` title='')
.cyber-swiper-item-title-link= item.title
a.cyber-swiper-item-description(onclick=`pjax.loadUrl("` + item.path + `");` title='')
.cyber-swiper-item-description-text!= item.description ? item.description : theme.swiperBar.default_descr
//- 装饰图标盲盒
svg.icon.cyber-swiper-item-decoration(aria-hidden="true")
use(xlink:href=cybericon())
else
each item in swiper_list()
//- 内容版块
.swiper-slide.cyber-swiper-item
//- 封面
a.cyber-swiper-item-cover(href=item.path title='')
img.article-cover(src=item.cover title='' onerror=`this.src=` + theme.swiperBar.error_img + `; this.onerror = null;`)
//- 时间
if (theme.swiperBar.timemode === 'updated' )
.cyber-swiper-item-time
span='updated:'
span= item.updated.format('YYYY-MM-DD')
else
.cyber-swiper-item-time
span='updated:'
span= item.date.format('YYYY-MM-DD')
//- 标题和描述
.cyber-swiper-item-info
a.cyber-swiper-item-title(href=item.path title='')
.cyber-swiper-item-title-link= item.title
a.cyber-swiper-item-description(href=item.path title='')
.cyber-swiper-item-description-text!= item.description ? item.description : theme.swiperBar.default_descr
//- 装饰图标盲盒
svg.icon.cyber-swiper-item-decoration(aria-hidden="true")
use(xlink:href=cybericon())
.swiper-pagination.cyber-swiper-pagination
script(defer src=url_for(theme.swiperBar.swiper_js))
script(defer data-pjax src=url_for(theme.swiperBar.swiper_init_js))
到[Blogroot]\themes\butterfly\layout\index.pug
中引入轮播图组件,最好不要问我为啥你的文件和我的不一样。这个文件以后会经常见面的。
extends includes/layout.pug
block content
include ./includes/mixins/post-ui.pug
#recent-posts.recent-posts
+ if theme.swiperBar.enable
+ !=partial('includes/custom/cyber_swiperBar', {}, {cache: true})
if theme.categoryBar.enable
!=partial('includes/custom/categoryBar', {}, {cache: true})
+postUI
include includes/pagination.pug
新建[Blogroot]\themes\butterfly\source\css\_layout\cyber_swiper_bar.styl
,这个文件里用到了源计划-方舟:首页卡片中的配色变量和一些样式方法。如果没完成首页卡片,那么大概率绝对会报错。
.recent-post-item
&#swiperBar
width: 100%;
position: relative
#cyber-swiper-container
width: 100%;
height: 200px;
overflow: hidden;
position: relative;
border-radius: 15px;
.cyber-swiper-wrapper
width: 100%;
height: 200px;
display: flex;
flex-direction: row;
.cyber-swiper-item
position: relative
width: 100%;
height: 200px;
display: flex;
flex-direction: row;
overflow: hidden;
border-radius: 15px;
box-shadow: 0 0 3px inset var(--cyber-post-item-box-shadow);
.cyber-swiper-item-cover
height: 100%;
display: flex;
position: absolute;
top: 0
left: 0
align-items: center;
justify-content: center;
overflow: hidden;
z-index: 0
img
object-fit: cover;
width: 100%;
height: 100%
z-index: 1;
opacity: 0.8
.cyber-swiper-item-time
width: 350px;
color: var(--cyber-post-item-font-color);
font-size: 25px;
text-shadow: 2px 2px 3px black;
background: rgba(153, 54, 44,0.8);
font-family: 'UnidreamLED';
display: flex;
position: absolute;
height: 30px;
top: calc(50% - 15px);
left: calc(50% - 175px);
align-items: center;
justify-content: center;
z-index: 2;
span
margin: 0 3px
.cyber-swiper-item-info
flex-direction: column;
background: var(--cyber-post-item-screen)
height: 100%;
display: flex;
position: absolute
top: 0
right: 0
align-items: center;
justify-content: space-between;
flex-direction: column;
overflow: hidden;
z-index: 0;
a.cyber-swiper-item-title
border-style: dotted;
border-width: 0 0 3px 0;
width: 100%;
height: 80px;
color: var(--cyber-post-item-font-color);
font-family: 'TaikoMagic';
border-color: rgba(153, 54, 44,0.8);
text-align: center;
display: flex;
align-items: center;
justify-content: center;
.cyber-swiper-item-title-link
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
cyber_post_item_link_hover()
.cyber-swiper-item-description
color: var(--cyber-post-item-font-color);
display: flex;
text-align: start;
height: 130px;
align-items: center;
.cyber-swiper-item-description-text
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
.cyber-swiper-item-decoration
width: 150px;
height: 150px;
opacity: 0.3;
position: absolute;
top: calc(50% - 75px);
left: calc(50% - 75px);
z-index: -1
.cyber-swiper-pagination
bottom: 5px;
left: 0;
right: 0;
margin: 0 auto;
//宽屏样式
@media screen and (min-width:768px)
.recent-post-item
&#swiperBar
height: 260px;
padding: 30px 30px
&::before
content: ""
display: block
height: 100%
width: 100%
position: absolute
background: var(--cyber-post-item-border)
z-index: 3
left: 0
top: 0
clip-path: polygon(50% 50%, 50% 0, calc(50% - 10px) 0, 30% 0, calc(30% - 10px) 10px, 10px 15px, 0 25px, 25px 25px, 30px 20px, calc(30% + 10px) 20px, calc(30% + 20px) 10px, calc(50% - 30px) 10px, calc(50% - 10px) 0, 50% 0, 50% 50%, 50% 0, calc(50% + 10px) 0, 70% 0, calc(70% + 10px) 10px, calc(100% - 10px) 15px, 100% 25px, calc(100% - 25px) 25px, calc(100% - 30px) 20px, calc(70% - 10px) 20px, calc(70% - 20px) 10px, calc(50% + 30px) 10px, calc(50% + 10px) 0, 50% 0, 50% 50%,50% 100%, calc(50% - 10px) 100%, 30% 100%, calc(30% - 10px) calc(100% - 10px), 10px calc(100% - 15px), 0 calc(100% - 25px), 25px calc(100% - 25px), 30px calc(100% - 20px), calc(30% + 10px) calc(100% - 20px), calc(30% + 20px) calc(100% - 10px), calc(50% - 30px) calc(100% - 10px), calc(50% - 10px) 100%, 50% 100%, 50% 50%, 50% 100%, calc(50% + 10px) 100%, 70% 100%, calc(70% + 10px) calc(100% - 10px), calc(100% - 10px) calc(100% - 15px), 100% calc(100% - 25px), calc(100% - 25px) calc(100% - 25px), calc(100% - 30px) calc(100% - 20px), calc(70% - 10px) calc(100% - 20px), calc(70% - 20px) calc(100% - 10px), calc(50% + 30px) calc(100% - 10px), calc(50% + 10px) 100%, 50% 100%, 50% 50%)
&::after
content: ""
display: block
height: 100%
width: 100%
position: absolute
background: linear-gradient(to right,var(--cyber-post-item-screen) 30px,#e9e9e9,#e9e9e9 60px,transparent),linear-gradient(to left,var(--cyber-post-item-screen) 30px,#e9e9e9,#e9e9e9 60px,transparent)
z-index: 3
left: 0
top: 0
clip-path: polygon(50% 50%, 45px 50%, 45px 45px, 60px 45px, 65px 40px, 40px 40px, 40px calc(50% - 10px), 45px calc(50% - 10px), 45px 50%, 25px 50%, 25px calc(50% - 15px), 10px calc(50% - 15px), 10px calc(50% - 10px), 25px calc(50% - 10px), 25px calc(50% - 2.5px), 0 calc(50% - 2.5px), 0 50%, 50% 50%, 45px 50%, 45px calc(100% - 45px), 60px calc(100% - 45px), 65px calc(100% - 40px), 40px calc(100% - 40px), 40px calc(50% + 10px), 45px calc(50% + 10px), 45px 50%, 25px 50%, 25px calc(50% + 15px), 10px calc(50% + 15px), 10px calc(50% + 10px), 25px calc(50% + 10px), 25px calc(50% + 2.5px), 0 calc(50% + 2.5px), 0 50%, 50% 50%, calc(100% - 45px) 50%, calc(100% - 45px) 45px, calc(100% - 60px) 45px, calc(100% - 65px) 40px, calc(100% - 40px) 40px, calc(100% - 40px) calc(50% - 10px), calc(100% - 45px) calc(50% - 10px), calc(100% - 45px) 50%, calc(100% - 25px) 50%, calc(100% - 25px) calc(50% - 15px), calc(100% - 10px) calc(50% - 15px), calc(100% - 10px) calc(50% - 10px), calc(100% - 25px) calc(50% - 10px), calc(100% - 25px) calc(50% - 2.5px), 100% calc(50% - 2.5px), 100% 50%, 50% 50%, calc(100% - 45px) 50%, calc(100% - 45px) calc(100% - 45px), calc(100% - 60px) calc(100% - 45px), calc(100% - 65px) calc(100% - 40px), calc(100% - 40px) calc(100% - 40px), calc(100% - 40px) calc(50% + 10px), calc(100% - 45px) calc(50% + 10px), calc(100% - 45px) 50%, calc(100% - 25px) 50%, calc(100% - 25px) calc(50% + 15px), calc(100% - 10px) calc(50% + 15px), calc(100% - 10px) calc(50% + 10px), calc(100% - 25px) calc(50% + 10px), calc(100% - 25px) calc(50% + 2.5px), 100% calc(50% + 2.5px), 100% 50%, 50% 50%)
#cyber-swiper-container
.cyber-swiper-wrapper
.cyber-swiper-item
.cyber-swiper-item-cover
width: calc(50% + 100px);
clip-path: polygon(0 0,100% 0,calc(100% - 200px) 100%,0 100%);
.cyber-swiper-item-time
transform: rotateZ(-45deg);
.cyber-swiper-item-info
width: calc(50% + 100px);
clip-path: polygon(100% 0,100% 100%,0 100%,200px 0 );
padding: 0 0 0 140px;
a.cyber-swiper-item-title
padding: 15px 20px 0 60px;
font-size: 20px;
line-height: 25px;
.cyber-swiper-item-title-link
-webkit-line-clamp: 2
.cyber-swiper-item-description
padding: 10px 20px 10px 10px;
font-size: 16px;
line-height: 30px;
.cyber-swiper-item-description-text
-webkit-line-clamp: 3
@media screen and (max-width:768px)
.recent-post-item
&#swiperBar
height: 200px;
padding: 0px 0px
#cyber-swiper-container
.cyber-swiper-wrapper
.cyber-swiper-item
.cyber-swiper-item-cover
width: calc(50% + 50px);
clip-path: polygon(0 0,100% 0,calc(100% - 100px) 100%,0 100%);
.cyber-swiper-item-time
transform: rotateZ(-60deg);
.cyber-swiper-item-info
width: calc(50% + 50px);
clip-path: polygon(100% 0,100% 100%,0 100%,100px 0 );
padding: 0 0 0 60px;
a.cyber-swiper-item-title
padding: 10px 16px 0 45px;
font-size: 16px;
line-height: 20px;
.cyber-swiper-item-title-link
-webkit-line-clamp: 2
.cyber-swiper-item-description
padding: 0px 15px 10px 5px;
font-size: 14px;
line-height: 20px;
.cyber-swiper-item-description-text
-webkit-line-clamp: 4
还需要新建[Blogroot]\themes\butterfly\source\js\custom\swiper_init.js
,作为swiper的初始化方案。这里另外新建文件而不是直接在pug里插入script标签是为了实现defer异步。毕竟swiper的js有144KB。更多参数可以自行查看Swiper中文网来添加。
var swiper = new Swiper("#cyber-swiper-container", {
direction: "horizontal", //横向切换
loop: true,
grabCursor : true,//鼠标悬停时显示抓手
updateOnWindowResize: true, //屏幕变动时重新计算
slidesPerView: 1,
spaceBetween: 30, // 每块间隔
mousewheel: true, //鼠标滚轮控制切换
pagination: {
el: ".swiper-pagination",
clickable: true, // 点击分页切换
},
autoplay: {
delay: 2000,//2秒切换一次
disableOnInteraction: true, // 操作以后停止自动播放
},
});
在主题配置文件[Blogroot]/_config.butterfly.yml
中添加配置项用以控制轮播图。配置项释义用过插件hexo-butterfly-swiper的应该都了解了,我就不另做解释了。
# 源计划-方舟:首页轮播图
# see https://akilar.top/posts/658f52d0/
swiperBar:
enable: true # 开关
timemode: updated #date/updated
error_img: /img/loading.gif #默认封面。记得换成自己的。
default_descr: 就算再怎么看我也不知道怎么描述它好啦!
swiper_css: https://npm.elemecdn.com/swiper@8.4.2/swiper-bundle.min.css #swiper css依赖
swiper_js: https://npm.elemecdn.com/swiper@8.4.2/swiper-bundle.min.js #swiper js依赖
swiper_init_js: /js/custom/swiper_init.js # swiper初始化方法
如果在配置时遇到实现不了的问题。那我建议你放弃。源计划-方舟不是为零基础的小白设计的魔改方案。
但是如果你有更多赛博风格化的想法,可以和我一起讨论,如果我觉得有趣的话就把它写出来。
当然,大部分情况下我更喜欢一意孤行的自己写下去。
我预备把它作为我今年的生日作。
至少在生日到来前,要把首页的版块改完。
最近爆肝的程度有点夸张。希望在灵感逃走前我已经把它们抓起来写到代码里了。