Hexo 添加粒子时钟

粒子时钟.png

截图出自 https://ruofei.site/,访问该站点可查看效果(在侧边栏标签云下方)。粒子时钟效果基于 Hexo 博客的 NexT 主题,其他主题的配置方式也可以参考这篇文章。

配置主题

为便于维护,通过修改主题配置文件(主题根目录的 _config.yml 文件)实现。打开主题目录下的 _config.yml 文件,新增以下代码片段:

# 侧栏粒子时钟
diy_clock:
  clock: true # 为 true 时开启粒子时钟,为 false 时关闭粒子时钟
  runtime: true

自定义粒子时钟脚本

主题目录下新增文件 source/js/custom/clock.js 文件。NexT 主题默认没有 custom 文件夹,需要自己新建。在 clock.js 文件中填入以下代码:

(function () {
  var digit =
    [
      [
        [0, 0, 1, 1, 1, 0, 0],
        [0, 1, 1, 0, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 0, 1, 1, 0],
        [0, 0, 1, 1, 1, 0, 0]
      ],//0
      [
        [0, 0, 0, 1, 1, 0, 0],
        [0, 1, 1, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [1, 1, 1, 1, 1, 1, 1]
      ],//1
      [
        [0, 1, 1, 1, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 1, 1, 0, 0, 0],
        [0, 1, 1, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 1, 1, 1, 1, 1]
      ],//2
      [
        [1, 1, 1, 1, 1, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 0]
      ],//3
      [
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 1, 0],
        [0, 0, 1, 1, 1, 1, 0],
        [0, 1, 1, 0, 1, 1, 0],
        [1, 1, 0, 0, 1, 1, 0],
        [1, 1, 1, 1, 1, 1, 1],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 1, 1]
      ],//4
      [
        [1, 1, 1, 1, 1, 1, 1],
        [1, 1, 0, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1, 0],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 0]
      ],//5
      [
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 1, 1, 0, 0, 0],
        [0, 1, 1, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 0, 0],
        [1, 1, 0, 1, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 0]
      ],//6
      [
        [1, 1, 1, 1, 1, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 0, 1, 1, 0, 0, 0],
        [0, 0, 1, 1, 0, 0, 0],
        [0, 0, 1, 1, 0, 0, 0],
        [0, 0, 1, 1, 0, 0, 0]
      ],//7
      [
        [0, 1, 1, 1, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 0]
      ],//8
      [
        [0, 1, 1, 1, 1, 1, 0],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [1, 1, 0, 0, 0, 1, 1],
        [0, 1, 1, 1, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 0, 1, 1],
        [0, 0, 0, 0, 1, 1, 0],
        [0, 0, 0, 1, 1, 0, 0],
        [0, 1, 1, 0, 0, 0, 0]
      ],//9
      [
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 1, 1, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 0]
      ]//:
    ];

  var canvas = document.getElementById('canvasDiyBlock');

  if (canvas.getContext) {
    var cxt = canvas.getContext('2d');
    //声明canvas的宽高
    var H = 100, W = 700;
    canvas.height = H;
    canvas.width = W;
    cxt.fillStyle = '#f00';
    cxt.fillRect(10, 10, 50, 50);

    //存储时间数据
    var data = [];
    //存储运动的小球
    var balls = [];
    //设置粒子半径
    var R = canvas.height / 20 - 1;
    (function () {
      var temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec(new Date());
      //存储时间数字,由十位小时、个位小时、冒号、十位分钟、个位分钟、冒号、十位秒钟、个位秒钟这7个数字组成
      data.push(temp[1], temp[2], 10, temp[3], temp[4], 10, temp[5], temp[6]);
    })();

    /*生成点阵数字*/
    function renderDigit(index, num) {
      for (var i = 0; i < digit[num].length; i++) {
        for (var j = 0; j < digit[num][i].length; j++) {
          if (digit[num][i][j] == 1) {
            cxt.beginPath();
            cxt.arc(14 * (R + 2) * index + j * 2 * (R + 1) + (R + 1), i * 2 * (R + 1) + (R + 1), R, 0, 2 * Math.PI);
            cxt.closePath();
            cxt.fill();
          }
        }
      }
    }

    /*更新时钟*/
    function updateDigitTime() {
      var changeNumArray = [];
      var temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec(new Date());
      var NewData = [];
      NewData.push(temp[1], temp[2], 10, temp[3], temp[4], 10, temp[5], temp[6]);
      for (var i = data.length - 1; i >= 0; i--) {
        //时间发生变化
        if (NewData[i] !== data[i]) {
          //将变化的数字值和在data数组中的索引存储在changeNumArray数组中
          changeNumArray.push(i + '_' + (Number(data[i]) + 1) % 10);
        }
      }
      //增加小球
      for (var i = 0; i < changeNumArray.length; i++) {
        addBalls.apply(this, changeNumArray[i].split('_'));
      }
      data = NewData.concat();
    }

    /*更新小球状态*/
    function updateBalls() {
      for (var i = 0; i < balls.length; i++) {
        balls[i].stepY += balls[i].disY;
        balls[i].x += balls[i].stepX;
        balls[i].y += balls[i].stepY;
        if (balls[i].x > W + R || balls[i].y > H + R) {
          balls.splice(i, 1);
          i--;
        }
      }
    }

    /*增加要运动的小球*/
    function addBalls(index, num) {
      var numArray = [1, 2, 3];
      var colorArray = ["#3BE", "#09C", "#A6C", "#93C", "#9C0", "#690", "#FB3", "#F80", "#F44", "#C00"];
      for (var i = 0; i < digit[num].length; i++) {
        for (var j = 0; j < digit[num][i].length; j++) {
          if (digit[num][i][j] == 1) {
            var ball = {
              x: 14 * (R + 2) * index + j * 2 * (R + 1) + (R + 1),
              y: i * 2 * (R + 1) + (R + 1),
              stepX: Math.floor(Math.random() * 4 - 2),
              stepY: -2 * numArray[Math.floor(Math.random() * numArray.length)],
              color: colorArray[Math.floor(Math.random() * colorArray.length)],
              disY: 1
            };
            balls.push(ball);
          }
        }
      }
    }

    /*渲染*/
    function render() {
      //重置画布宽度,达到清空画布的效果
      canvas.height = 100;
      //渲染时钟
      for (var i = 0; i < data.length; i++) {
        renderDigit(i, data[i]);
      }
      //渲染小球
      for (var i = 0; i < balls.length; i++) {
        cxt.beginPath();
        cxt.arc(balls[i].x, balls[i].y, R, 0, 2 * Math.PI);
        cxt.fillStyle = balls[i].color;
        cxt.closePath();
        cxt.fill();
      }
    }

    clearInterval(oTimer);
    var oTimer = setInterval(function () {
      //更新时钟
      updateDigitTime();
      //更新小球状态
      updateBalls();
      //渲染
      render();
    }, 50);
  }
})();

上面这段 js 代码就是粒子时钟的具体实现。

自定义视图

接下来在主题下新增一个视图文件 layout/_custom/clock.swig,用这个文件来引入上面的 js 代码。NexT 主题默认没有 _custom 文件夹,需自行创建。通常情况下,自定义的所有视图统一放置在 _custom 目录下。

<div>
  <canvas id="canvasDiyBlock" style="width:60%;">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
  {{- next_js('custom/clock.js') }}
</div>

代码中的第 3 行,next_js() 方法是 NexT 主题内置的用来引入 js 的通用方法,该方法将 source/js/ 目录作为相对路径,所以上面的 custom/clock.js 其实就是主题目录中的 source/js/custom/clock.js 文件。

因粒子时钟的实现是用现代浏览器支持的 canvas 绘图实现的,在 IE 等浏览器上可能无法正常显示,这时,页面上就会显示当前浏览器不支持canvas,请更换浏览器后再试

导入视图

至此,在页面上任意位置引入上面的 layout/_custom/clock.swig 文件即可实现粒子时钟了。比如放在页面的侧边栏,既美观又不影响网站的易用性。打开主题目录下的 layout/_macro/sidevar.swig 文件,找到 classsidebar-innerdiv 元素,在该元素中最后位置引入上面的 clock.swig 文件:

{%- if theme.diy_clock.clock %}
  {%- include '../_custom/clock.swig' %}
{%- endif %}

当主题配置中的 diy_clock.clocktrue 时,页面加载粒子时钟。

小结

这篇文章介绍了如何在页面引入粒子时钟方法,按照类似的思路,任何第三方或自定义的任意功能都可以根据这个思路来实现。关于 NexT 主题的详细文档参考官网,也可在本站浏览相关页面。


本文标题: Hexo 添加粒子时钟
本文作者: 若非
发布时间: 2020年02月06日 - 11:54:38
版权声明: 文章转载自 https://ruofei.site/post/26884a10/,采用 BY-NC-SA 许可协议。转载请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容