点击查看更新记录
更新记录
2023-01-02:内测版
- 源计划-赛博更名为源计划-方舟
- 重写首页卡片。
- 调整布局,常态仅显示标题和封面。极致简化信息
- 悬停标题和封面,弹出描述面板
- 宽屏左右张开,窄屏上下张开。
- 置顶、评论数、分类、标签均隐藏至卡片四个牙角。悬停展开。
点击查看参考教程
参考方向 | 教程原贴 |
---|---|
参考了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引入阿里矢量图标库 |
预览效果
点击查看预览效果
魔改步骤
本篇需要用到iconfont作为卡片底部的装饰性图标。请先完成前置教程:Hexo引入阿里矢量图标库,务必确保symbol方案能够使用后再进行下方内容。
新建[Blogroot]themesbutterflyscriptshelperscybericon.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]themesbutterflylayoutincludesmixinspost-ui.pug
,将以下内容覆盖到源文件内:
mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item.cyber-post-card
-
let link = article.link || article.path
let title = article.title || _p('no_title')
let subtitle = article.subtitle || title
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
//- 更新时间、创建时间
.recent-post-item-headline
//- 置顶标签
if (is_home() && (article.top || article.sticky > 0))
.article-meta-sticky
i.fas.fa-thumbtack.sticky
span.sticky= _p('sticky')
//- 文章评论数
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta-comments
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' _p('card_post_count')
if theme.comments.card_post_count
case theme.comments.use[0]
when 'Disqus'
countBlockInIndex
a(href=full_url_for(link) '#disqus_thread')
i.fa-solid.fa-spinner.fa-spin
when 'Disqusjs'
countBlockInIndex
a(href=full_url_for(link) '#disqusjs')
span.disqus-comment-count(data-disqus-url=full_url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
countBlockInIndex
a(href=url_for(link) '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
countBlockInIndex
a(href=url_for(link) '#post-comment')
span.waline-comment-count(id=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
countBlockInIndex
a.twikoo-count(href=url_for(link) '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
countBlockInIndex
a(href=url_for(link) '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
countBlockInIndex
a(href=url_for(link) '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
countBlockInIndex
a(href=url_for(link) '#post-comment')
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin
if (theme.post_meta.page.date_type)
if (theme.post_meta.page.date_type === 'both')
.recent-post-time
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') ' ' full_date(article.updated))=date(article.updated, config.date_format)
//- 仅显示更新或创建时间
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
.recent-post-time
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title ' ' full_date(article[date_type]))=date(article[date_type], config.date_format)
//- 内容版块
.recent-post-content(class=leftOrRight)
//- 封面和标题
.recent-post-cover
img.article-cover(src=url_for(post_cover) onerror=`this.onerror=null;this.src='` url_for(theme.error_img.post_page) `'` alt=subtitle)
.recent-post-info
a.article-title(href=url_for(link) title=subtitle)
.article-title-link= title
//- 装饰图标盲盒
svg.icon.cyber-decoration(aria-hidden="true")
use(xlink:href=cybericon())
//- 文章描述
a.recent-post-description(href=url_for(link) title=subtitle)
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.article-content-text!= article.description
when 2
if article.description
.article-content-text!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert = ' ...' : ''
.article-content-text!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert = ' ...' : ''
.article-content-text!= expert
.recent-post-item-bottomline
//- 分类项
if (theme.post_meta.page.categories && article.categories.data.length > 0)
.article-meta-categories
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
//- 标签项
if (theme.post_meta.page.tags && article.tags.data.length > 0)
.article-meta-tags
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
if (theme.post_meta.page.date_type)
//- 同时显示更新和创建时间
if (theme.post_meta.page.date_type === 'both')
//- 同时显示更新和创建时间
.recent-post-time
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') ' ' full_date(article.date))=date(article.date, config.date_format)
if theme.ad && theme.ad.index
if (index 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index
新建[Blogroot]themesbutterflysourcecss_layoutcyber_index_card.styl
,这个stylus写的还挺复杂的,连我都要密密麻麻的注释才能分得清哪个是哪个。配色可以在开头的代码版块里自行调整。过年了嘛我就整了个喜庆点的红色。
//default color:
:root
--cyber-post-item-transition: all 0.5s cubic-bezier(0.59, 0.01, 0.48, 1.17)//动画效果
--cyber-post-item-border: rgba(153, 54, 44,0.8) //卡片边框颜色
--cyber-post-item-background: rgba(67, 66, 65,0.8) //背景色
--cyber-post-item-screen: rgba(61, 146, 204,0.6) //描述卡片背景
--cyber-post-item-font-color: #fff //字体颜色
--cyber-post-item-font-hover: #d97f17//文字悬停颜色
--cyber-post-item-box-shadow: rgba(111, 160, 225,0.8) //边框光晕颜色
--cyber-post-item-text-shadow: rgba(50, 51, 50,0.7) //字体光晕颜色
[data-theme="dark"]
--cyber-post-item-border: rgba(55, 112, 143,0.8) //卡片边框颜色
--cyber-post-item-background: rgba(47, 66, 70,0.8) //背景色
--cyber-post-item-screen: rgba(61, 146, 204,0.6) //描述卡片背景
--cyber-post-item-font-color: rgb(233, 233, 233)//字体颜色
--cyber-post-item-font-hover: #433686//文字悬停颜色
--cyber-post-item-box-shadow: rgba(252, 252, 252, 0.8) //边框光晕颜色
--cyber-post-item-text-shadow: rgba(50, 51, 50,0.7) //字体光晕颜色
//顶栏底栏基本属性
cyber_post_item_line()
display: flex;
width: 100%;
height: 40px;
justify-content: center;
flex-direction: row;
align-items: center;
position: relative
font-family: 'UnidreamLED','TaikoMagic';
//时间栏
cyber_post_item_time()
width: fit-content;
height: 40px;
background: var(--cyber-post-item-background);
color: var(--cyber-post-item-font-color);
padding: 5px 15px;
font-size: 15px;
display: flex;
position: relative;
z-index: 3;
align-items: center;
justify-content: center;
border: 5px groove var(--cyber-post-item-border);
transform: skewX(45deg);
clip-path: polygon(0 50%,35px 5px,50% 5px,50% 0,100% 0,100% 50%,calc(100% - 35px) calc(100% - 5px),50% calc(100% - 5px),50% 100%,0 100%);
*
transform: skewX(-45deg);
margin: 0px 3px
cyber_post_item_link_hover()
//置顶,评论数,分类,标题等元数据。
cyber_post_item_meta(skewXdeg,reverseskew,insetwidth,borderwidth,borderstyle)
display: flex;
position: absolute;
background: var(--cyber-post-item-background);
border-color: var(--cyber-post-item-border);
font-size: 14px;
z-index: 3;
height: 18px;
line-height: 14px;
transition: var(--cyber-post-item-transition)
transform: skewX(skewXdeg);
clip-path: inset(insetwidth);
border-width: borderwidth;
border-style: borderstyle;
*
transform: skewX(reverseskew);
margin: 0px 2px
color: var(--cyber-post-item-font-color)
cyber_post_item_link_hover()
&:hover
clip-path: inset(0 0 0 0);
transition: var(--cyber-post-item-transition)
//两侧的异形边框
cyber_post_item_border()
&::before
width: 100%;
z-index: 3
height: 100%;
left: 0;
top: 0;
content: ""
background: var(--cyber-post-item-border)
position: absolute
clip-path: polygon(50% 50%, 35px 50%, 30px calc(50% - 5px), 30px 50%, 25px 50%, 25px calc(50% - 25px), 15px calc(50% - 30px), 15px 10px, 30px 0, 10px 0px, 0 10px, 0 calc(100% - 10px), 10px 100%, 30px 100%, 15px calc(100% - 10px), 15px calc(50% 30px),25px calc(50% 25px), 25px 50%, 30px 50%, 30px calc(50% 5px), 35px 50%, 50% 50%, calc(100% - 35px) 50%, calc(100% - 30px) calc(50% - 5px), calc(100% - 30px) 50%, calc(100% - 25px) 50%, calc(100% - 25px) calc(50% - 25px), calc(100% - 15px) calc(50% - 30px), calc(100% - 15px) 10px, calc(100% - 30px) 0, calc(100% - 10px) 0px, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, calc(100% - 30px) 100%, calc(100% - 15px) calc(100% - 10px), calc(100% - 15px) calc(50% 30px),calc(100% - 25px) calc(50% 25px), calc(100% - 25px) 50%, calc(100% - 30px) 50%, calc(100% - 30px) calc(50% 5px), calc(100% - 35px) 50%, 50% 50%)
//悬停链接颜色
cyber_post_item_link_hover()
&:hover
transition: all 0.3s
color: var(--cyber-post-item-font-hover)
//封面和标题的基础样式
cyber_post_item_cover_title()
background: var(--cyber-post-item-background)
overflow: hidden
display: flex;
align-items: center;
justify-content: center;
position: absolute;
z-index: 2
transition: var(--cyber-post-item-transition)
//左半边切分
cyber_post_item_left_content()
left: 0
top: 0
border-radius: 15px 0 0 15px;
clip-path: polygon(calc(100% - 80px) 50%, calc(100% - 50px) calc(50% - 30px), 100% calc(50% - 30px), 100% 0, 0 0, 0 100%, 100% 100%, 100% calc(50% 30px), calc(100% - 50px) calc(50% 30px))
//左半边切分悬停
cyber_post_item_left_content_hover()
clip-path: polygon(0 50%, 10px calc(50% - 5px), 30% calc(50% - 5px), 40% 0, 0 0, 0 100%, 40% 100%, 30% calc(50% 5px), 10px calc(50% 5px))
transition: var(--cyber-post-item-transition)
//右半边切分
cyber_post_item_right_content()
right: 0
top: 0
border-radius: 0 15px 15px 0;
clip-path: polygon(80px 50%, 50px calc(50% - 30px), 0 calc(50% - 30px), 0 0, 100% 0, 100% 100%, 0 100%, 0 calc(50% 30px), 50px calc(50% 30px))
//右半边切分悬停
cyber_post_item_right_content_hover()
clip-path: polygon(100% 50%, calc(100% - 10px) calc(50% - 5px), 70% calc(50% - 5px), 60% 0, 100% 0, 100% 100%, 60% 100%, 70% calc(50% 5px), calc(100% - 10px) calc(50% 5px))
transition: var(--cyber-post-item-transition)
//上半边切分
cyber_post_item_top_content()
left: 0
top: 0
border-radius: 15px 15px 0 0;
clip-path: polygon(50% calc(100% - 30px), calc(50% - 30px) calc(100% - 30px), calc(50% - 45px) 100%, 0 100%, 0 0, 100% 0, 100% 100%, calc(50% 45px) 100%, calc(50% 30px) calc(100% - 30px));
//上半边切分悬停
cyber_post_item_top_content_hover()
clip-path: polygon(30% 30px, 20px 30px, 20px calc(100% - 15px), 0 100%, 0 0, 50% 0, calc(100% - 45px) 0, calc(100% - 60px) 15px, calc(30% 10px) 15px)
transition: var(--cyber-post-item-transition)
//下半边切分
cyber_post_item_bottom_content()
left: 0
bottom: 0
border-radius: 0 0 15px 15px;
clip-path: polygon(50% 30px, calc(50% - 30px) 30px, calc(50% - 45px) 0, 0 0, 0 100%, 100% 100%, 100% 0, calc(50% 45px) 0, calc(50% 30px) 30px);
//下半边切分悬停
cyber_post_item_bottom_content_hover()
clip-path: polygon(70% calc(100% - 30px), calc(100% - 20px) calc(100% - 30px), calc(100% - 20px) 15px, 100% 0, 100% 100%, 50% 100%, 45px 100%, 60px calc(100% - 15px), calc(70% - 10px) calc(100% - 15px))
transition: var(--cyber-post-item-transition)
//gitcalendar样式临时性
.recent-post-item
&#gitcalendarBar
position: relative
padding: 30px 30px!important;
background: transparent!important;
cyber_post_item_border()
div#git_container
background: var(--cyber-post-item-background);;
border-radius: 15px;
// 卡片本体
.recent-post-item
margin: 30px 0px;
&.cyber-post-card
z-index: 0
display: flex;
position: relative
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
align-content: center;
background: transparent;
padding: 0px 30px;
z-index: 0
//两侧的异形边框
cyber_post_item_border()
//顶栏
.recent-post-item-headline
cyber_post_item_line()
.recent-post-time
top: 20px;
transition: var(--cyber-post-item-transition)
cyber_post_item_time()
.article-meta-sticky
left: 20px
bottom: 0;
cyber_post_item_meta(-45deg,45deg,0 calc(100% - 25px) 0 0,1px 10px 0 30px,solid dashed solid groove)
&:hover
&~ .recent-post-time
top: 40px;
transition: var(--cyber-post-item-transition)
.article-meta-comments
right: 20px
bottom: 0;
cyber_post_item_meta(45deg,-45deg,0 0 0 calc(100% - 25px),1px 30px 0 10px,solid groove solid dashed)
&:hover
&~ .recent-post-time
top: 40px;
transition: var(--cyber-post-item-transition)
//底栏
.recent-post-item-bottomline
cyber_post_item_line()
.recent-post-time
bottom:20px;
transition: var(--cyber-post-item-transition)
cyber_post_item_time()
.article-meta-categories
left: 20px
top: 0;
cyber_post_item_meta(45deg,-45deg,0 calc(100% - 30px) 0 0 ,0 10px 1px 30px,solid dashed solid groove)
&:hover
&~ .recent-post-time
bottom: 40px;
transition: var(--cyber-post-item-transition)
.article-meta-tags
right: 20px
top: 0;
cyber_post_item_meta(-45deg,45deg,0 0 0 calc(100% - 30px),0 30px 1px 10px,solid groove solid dashed)
&:hover
&~ .recent-post-time
bottom: 40px;
transition: var(--cyber-post-item-transition)
//文章封面、标题、描述主体版块
.recent-post-content
display: flex;
z-index: 0
flex-direction: row;
align-items: center;
justify-content: center;
background: transparent;
position: relative;
&:hover
a.recent-post-description
transform: rotateX(0deg)
transition: var(--cyber-post-item-transition) 0.5s
.recent-post-cover
cyber_post_item_cover_title()
img.article-cover
object-fit: cover;
height: 100%
width: 100%;
//文章标题
.recent-post-info
cyber_post_item_cover_title()
.article-title-link
margin: 20px 80px
font-size: 24px;
text-align: center;
color: var(--cyber-post-item-font-color);
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2
cyber_post_item_link_hover()
//装饰性背景图标
svg.cyber-decoration
position: absolute;
z-index: 0;
opacity: 0.3;
color: var(--cyber-post-item-font-color);
width: 150px;
height: 150px;
top: calc(50% - 75px);
left: calc(50% - 75px);
cyber_post_item_link_hover()
//文章描述内容
a.recent-post-description
z-index: 1
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: var(--cyber-post-item-screen);
border-radius: 15px;
box-shadow: 0 0 10px var(--cyber-post-item-box-shadow);
transform: rotateX(90deg)
transition: var(--cyber-post-item-transition)
padding: 20px 20px;
.article-content-text
color: var(--cyber-post-item-font-color);
text-shadow: 3px 3px 3px var(--cyber-post-item-text-shadow);
overflow-y: scroll
font-size: 16px;
&::-webkit-scrollbar
width 0px
//pc端样式适配
@media screen and (min-width:900px)
// 卡片本体
.recent-post-item
&.cyber-post-card
width: 100%;
height: 320px;
//文章封面、标题、描述主体版块
.recent-post-content
width: 100%;
height: 240px;
&.both,
&.left
&:hover
.recent-post-cover
cyber_post_item_left_content_hover()
.recent-post-info
cyber_post_item_right_content_hover()
&.right
&:hover
.recent-post-cover
cyber_post_item_right_content_hover()
.recent-post-info
cyber_post_item_left_content_hover()
.recent-post-cover
width: 50%;
height: 240px;
//文章标题
.recent-post-info
width: 50%;
height: 240px;
.article-title-link
margin: 20px 80px
font-size: 24px;
&.both,
&.left
.recent-post-cover
cyber_post_item_left_content()
.recent-post-info
cyber_post_item_right_content()
&.right
.recent-post-cover
cyber_post_item_right_content()
.recent-post-info
cyber_post_item_left_content()
//文章描述内容
a.recent-post-description
height: 200px;
margin: 20px 0
width: 60%;
//平板宽度双栏样式适配
@media screen and (min-width:468px) and (max-width:900px)
#recent-posts
display: flex;
flex-direction: row;
flex-wrap: wrap;
// 卡片本体
.recent-post-item
&.cyber-post-card
width: 48%;
height: 360px;
margin: 0 1% 30px 1%
//文章封面、标题、描述主体版块
.recent-post-time
.article-meta-label
display: none
.recent-post-content
width: 100%;
height: 280px;
&:hover
.recent-post-cover
cyber_post_item_top_content_hover()
.recent-post-info
cyber_post_item_bottom_content_hover()
.recent-post-cover
width: 100%;
height: 140px;
cyber_post_item_top_content()
//文章标题
.recent-post-info
width: 100%;
height: 140px;
cyber_post_item_bottom_content()
.article-title-link
margin: 10px 10px
font-size: 18px;
//文章描述内容
a.recent-post-description
height: 200px;
margin: 40px 0
width: 70%;
//手机端样式适配
@media screen and (max-width:468px)
// 卡片本体
.recent-post-item
&.cyber-post-card
width: 100%;
height: 360px;
//文章封面、标题、描述主体版块
.recent-post-time
.article-meta-label
display: none
.recent-post-content
width: 100%;
height: 280px;
&:hover
.recent-post-cover
cyber_post_item_top_content_hover()
.recent-post-info
cyber_post_item_bottom_content_hover()
.recent-post-cover
width: 100%;
height: 140px;
cyber_post_item_top_content()
//文章标题
.recent-post-info
width: 100%;
height: 140px;
cyber_post_item_bottom_content()
.article-title-link
margin: 10px 10px
font-size: 18px;
//文章描述内容
a.recent-post-description
height: 200px;
margin: 40px 0
width: 70%;