Fork me on GitHub

Hexo主题美化小结(基于Next主题)

标题图片来自自己在17年3月给朋友画的小说封面

关于Next主题

  • Hexo 是高效的静态站点生成框架,基于 Node.js。Next是基于Hexo的一个功能较为完整的热门主题。
  • 关于Next下载和基本使用方法详见:
    Next使用文档

Hexo博客架构简介

  • hexo文件夹目录:

    1
    2
    3
    4
    5
    6
    7
    8
    .
    ├── _config.yml
    ├── package.json
    ├── scaffolds
    ├── source
    | ├── _drafts
    | └── _posts
    └── themes
    • _config.yml:网站的配置信息,可以设置大部分的参数。
    • package.json:应用程序的信息,包括各种版本号。
    • scaffolds:模版文件夹。当您新建文章时,Hexo会根据scaffold来建立文件。
    • source:存放用户资源。如新建的博文就放在_posts下。Markdown 和 HTML 文件会被解析并放到 public 文件夹,而其他文件会被拷贝过去。
    • themes:主题文件夹,如Next主题就放在该文件夹下。Hexo会根据主题生成静态页面。
  • 主题文件夹目录:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      .
    ├── _config.yml //记录主题配置信息
    ├── languages //语言文件夹
    ├── layout //存放布局模板文件
    │ └── _partial //布局文件中可共用的模板
    ├── scripts //脚本文件夹
    └── source //静态资源文件夹
    ├── css
    ├── fonts
    ├── js
    └── sass
  • 详细可参考:
    Hexo文档
    写一个自己的Hexo主题

主题美化

修改背景

  • 进入/themes/next/source/css/_custom/custom.js
  • 加入如下代码:

    1
    2
    3
    4
    5
    body {
    background:url(/images/background3.jpg) top left no-repeat;
    background-attachment: fixed;
    background-size: cover;
    }

    其中,图片放在主题文件夹下source/images下。

给主页文章添加阴影效果

  • 进入/themes/next/source/css/_custom/custom.js
  • 加入如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    // 主页文章添加阴影效果
    .post {
    margin-top: 60px;
    margin-bottom: 60px;
    padding: 25px;
    -webkit-box-shadow: 0 0 5px rgba(202, 203, 203, .5);
    -moz-box-shadow: 0 0 5px rgba(202, 203, 204, .5);
    }
  • 如同时添加其他页面,可加上.page,.comments等。

添加动态背景

  • Next主题最新版支持四种动态背景样式。
  • 进入主题配置文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # Canvas-nest
    # Dependencies: https://github.com/theme-next/theme-next-canvas-nest
    canvas_nest: false
    # JavaScript 3D library.
    # Dependencies: https://github.com/theme-next/theme-next-three
    # three_waves
    three_waves: false
    # canvas_lines
    canvas_lines: true
    # canvas_sphere
    canvas_sphere: false
  • 根据四种动态背景样式的Dependencies下载相关依赖包并设置对应属性为true。

鼠标点击效果

  • 点击出现桃心:

    • 进入网址:http://7u2ss1.com1.z0.glb.clouddn.com/love.js 复制js代码。
    • 在/themes/next/source/js/src目录下新建love.js,复制刚刚的代码。保存。
    • 打开/themes/next/layout/_layout.swig,在前添加:

      1
      2
      3
      {% if theme.love %}
      <script type="text/javascript" src="/js/src/love.js"></script>
      {% endif %}
    • 在主题配置文件中添加:

      1
      2
      # 鼠标点击效果
      love: true
  • 点击出现烟花效果

    • 和上面的流程差不多,首先在/themes/next/source/js/src目录下新建fireworks.js,复制如下代码并保存:

      1
      "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=0.1,a.alpha=0.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:0.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)}"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=0.1,a.alpha=0.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:0.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)};
    • 打开\themes\next\layout_layout.swig,在body结尾符号前添加:

      1
      2
      3
      4
      5
        {% if theme.fireworks %}
      <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
      <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
      <script type="text/javascript" src="/js/src/fireworks.js"></script>
      {% endif %}
    • 在主题配置文件中添加:

      1
      2
        # 鼠标点击效果
      fireworks: true

修改文章底部标签样式

  • 修改模板/themes/next/layout/_macro/post.swig,搜索 rel=”tag”>#,将#换成
    1
    <i class="fa fa-tag"></i>

设置网站的图标Favicon

  • 找相关大小的icon文件放入文件夹/themes/next/source/images
  • 修改追配置文件:
    1
    2
    3
    4
    5
    6
    7
    favicon:
    small: /images/favicon-16x16-next2.png
    medium: /images/favicon-32x32-next2.png
    apple_touch_icon: /images/apple-touch-icon-next2.png
    safari_pinned_tab: /images/logo.svg
    #android_manifest: /images/manifest.json
    #ms_browserconfig: /images/browserconfig.xml

添加友情链接

  • 修改主题配置文件:
    1
    2
    3
    4
    5
    6
    7
    # Blog rolls
    links_icon: link
    links_title: 「友情链接」
    links_layout: block
    #links_layout: inline
    links:
    显示连接名称: 链接url

网站底部添加访问量

  • 打开/themes/next/layout/_partials/footer.swig文件,在copyright前加上:

    1
    <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  • 在{% if theme.footer.powered %}后面加上:

    1
    2
    3
    4
    5
    <div class="powered-by">
    <i class="fa fa-user-md"></i><span id="busuanzi_container_site_uv">
    本站访客数:<span id="busuanzi_value_site_uv"></span>
    </span>
    </div>

添加文章热度

  • 需要使用leanCloud。之后的评论设置也需要集成leanCloud。先去leanCloud注册账号:
    leanCloud

  • 应用-创建新应用,输入应用名字,创建。

    image

  • 进入应用,点击右侧创建Class,输入名称为Counter,其他默认,点击创建。创建的表类似于你的数据库,存放关于你网站文章的相关信息,包括阅读数量等。

  • 获取AppId和AppKey:点击设置-应用key即可查看到id和key。

  • 回到主题配置文件,修改相应代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Show number of visitors to each article.
    # You can visit https://leancloud.cn get AppID and AppKey.
    leancloud_visitors:
    enable: true
    app_id: 你的AppId
    app_key: 你的AppKey
    # Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security
    security: true
    betterPerformance: false
    • 注:我使用的版本NexT.Muse v6.0.5在这里有个bug,主题文件夹下layout/third-party/analytics/lean-analytics.swig中对id和key的引用为:

      1
      <script>AV.initialize("{{theme.leancloud_visitors.app_id}}", "{{theme.leancloud_visitors.app_key}}");</script>

      而主题配置文件中的参数为appId和appKey,两者不一致,注意这个地方需要改成app_id和app_key。

添加评论:Valine

  • 在上面创建的leanCloud项目中,新建表Comment,存放评论信息。
  • 修改主题配置文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # Valine.
    # You can get your appid and appkey from https://leancloud.cn
    # more info please open https://valine.js.org
    valine:
    enable: true
    appid: 你的appId
    appkey: 你的appKey
    notify: false # mail notifier , https://github.com/xCss/Valine/wiki
    verify: false # Verification code
    placeholder: Just go go # comment box placeholder
    avatar: mm # gravatar style
    guest_info: nick,mail,link # custom comment header
    pageSize: 10 # pagination size
  • 点击Comment表可查看存储的评论内容:

    image

添加打赏功能

  • 在themes/next/source/images下,放入支付宝或者微信的二维码图片,打开主题配置文件,修改reward_comment,添加图片路径:

    1
    2
    3
    4
    5
    # Reward
    reward_comment: 打赏界面想说的话
    #wechatpay: /images/wechatpay.jpg
    alipay: /images/alipay.png
    #bitcoin: /images/bitcoin.png
  • 修改闪动bug:
    修改next/source/css/_common/components/post/post-reward.styl,注释wechat:hover、alipay:hover和bitcoin:hover

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /* 注释文字闪动函数
    #wechat:hover p{
    animation: roll 0.1s infinite linear;
    -webkit-animation: roll 0.1s infinite linear;
    -moz-animation: roll 0.1s infinite linear;
    }
    #alipay:hover p{
    animation: roll 0.1s infinite linear;
    -webkit-animation: roll 0.1s infinite linear;
    -moz-animation: roll 0.1s infinite linear;
    }
    #bitcoin:hover p {
    animation: roll 0.1s infinite linear;
    -webkit-animation: roll 0.1s infinite linear;
    -moz-animation: roll 0.1s infinite linear;
    }
    */

添加分享:BaiduShare

  • 在站点配置文件中,添加baiduShare字段。

    1
    2
    #baidushare
    baidushare: true
  • 在主题配置文件中,修改相关内容。百度分享有两种样式,button是显示在文章底部,而slide收束在文章左侧,点击可展开。

    1
    2
    3
    4
    5
    6
    # Baidu Share
    # Available value:
    # button | slide
    # Warning: Baidu Share does not support https.
    baidushare:
    type: slide
  • 这里会出现一个问题,分享功能在4000端口可以显示,但是在发布到github后用网址访问时无法显示,原因是百度分享不支持https,而代码中它会去请求http中的资源,一个share.js,既然这样,我们能想到的就是把这个资源放到非http上,或者干脆直接放到我们自己的目录下面。

    • 去下载源码:baiduShare
    • 下载后解压,把static文件放在主题文件的source目录下。
    • 修改/themes/next/layout/_partials/share/baidushare.swing文件,把结尾处的https引用修改为文件夹引用:
      1
      2
      3
      .src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
      //把上面的改为
      .src='/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>