前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源计划-方舟:首页轮播图

源计划-方舟:首页轮播图

作者头像
Akilar
发布2023-01-30 15:11:25
5900
发布2023-01-30 15:11:25
举报

点击查看更新记录

更新记录

2023-01-03:内测版

  1. 沿用源计划-方舟:首页卡片的配色方案,建议一起使用。
  2. 首页轮播图采用液晶屏风格设计
  3. 窄屏样式已适配

点击查看参考教程

参考方向

教程原贴

参考了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初始化方法

小结

如果在配置时遇到实现不了的问题。那我建议你放弃。源计划-方舟不是为零基础的小白设计的魔改方案。

但是如果你有更多赛博风格化的想法,可以和我一起讨论,如果我觉得有趣的话就把它写出来。

当然,大部分情况下我更喜欢一意孤行的自己写下去。

我预备把它作为我今年的生日作。

至少在生日到来前,要把首页的版块改完。

最近爆肝的程度有点夸张。希望在灵感逃走前我已经把它们抓起来写到代码里了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 预览效果
  • 魔改步骤
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档