Hexo NexT 博客增加瀑布流相册页面

12 次浏览 2 分钟阅读
目录
  • 1. json 文件处理图片信息
  • 2. 加载 js 文件
  • 3. 编辑相册页面
  • 4. 主题配置文件设置
  • 因为 Hexo NexT 博客没有提供相册页面模板,这里介绍一种添加瀑布流相册页面的方法。注意,本文适用于 Hexo 5.4.0 / NexT 8.3.0,其他版本的兼容性未知。

    1. json 文件处理图片信息

    在博客根目录的 /scripts/ 文件夹下新建一个 phototool.js 文件,内容如下。主要功能是访问照片文件夹,获取每张照片的大小和文件名,并生成对应的 json 文件:

    "use strict";
    const fs = require("fs");
    const sizeOf = require('image-size');
    //本地照片所在目录
    const path = "source/photos/images"; 
    //要放置生成的照片信息文件目录,建议直接放在 source/photos/ 文件夹下
    const output = "source/photos/photoslist.json";
    var dimensions;
    fs.readdir(path, function (err, files) {
        if (err) {
            return;
        }
        let arr = [];
        (function iterator(index) {
            if (index == files.length) {
                fs.writeFileSync(output, JSON.stringify(arr, null, "\t"));
                return;
            }
            fs.stat(path + "/" + files[index], function (err, stats) {
                if (err) {
                    return;
                }
                if (stats.isFile()) {
                    dimensions = sizeOf(path + "/" + files[index]);
                    console.log(dimensions.width, dimensions.height);
                    arr.push(dimensions.width + '.' + dimensions.height + ' ' + files[index]);
                }
                iterator(index + 1);
            })
        }(0));
    });

    创建好并把照片放在目录后,执行以下命令:

    1. 定位到 Hexo 博客目录
    cd <folder-path>
    
    1. 安装依赖包
    npm i image-size
    
    1. 生成对应的 json 文件
    node scripts/phototool.js  

    node scripts/phototool.js 这个步骤以后可以不用手动执行,每次 hexo s 或者 hexo deploy 时候会被自动执行。如果报错,请注意检查保存本地照片的文件夹里有没有非图片类文件,特别是要删除如 .DS_Store 这样的隐藏文件。json 文件样例如下:

    [
        "4032.3024 IMG_0391.webp",
        "12500.3874 IMG_0404.webp",
        "4032.3024 IMG_0416.webp",
        "4032.3024 IMG_0424.webp",
    ]

    2. 加载 js 文件

    首先,在 /source/js/ 目录下创建 photo.js

    var imgDataPath = '/photos/photoslist.json'; //图片名称高宽信息json文件路径
    var imgPath = '/images/photos/';  //图片访问路径
    var imgMaxNum = 50; //图片显示数量
    
    var windowWidth = window.innerWidth
    || document.documentElement.clientWidth
    || document.body.clientWidth;
    if (windowWidth < 768) {
        var imageWidth = 145; //图片显示宽度(手机端)
    } else {
        var imageWidth = 215; //图片显示宽度
    }
    
    photo = {
        page: 1,
        offset: imgMaxNum,
        init: function () {
            var that = this;
            $.getJSON(imgDataPath, function (data) {
                that.render(that.page, data);
                //that.scroll(data);
            });
        },
        render: function (page, data) {
            var begin = (page - 1) * this.offset;
            var end = page * this.offset;
            if (begin >= data.length) return;
            var html, imgNameWithPattern, imgName, imageSize, imageX, imageY, li = "";
            for (var i = begin; i < end && i < data.length; i++) {
               imgNameWithPattern = data[i].split(' ')[1];
               imgName = imgNameWithPattern.split('.')[0]
               imageSize = data[i].split(' ')[0];
               imageX = imageSize.split('.')[0];
               imageY = imageSize.split('.')[1];
                li += '<div class="card" style="width:' + imageWidth + 'px" >' +
                        '<div class="ImageInCard" style="height:'+ imageWidth * imageY / imageX + 'px">' +
                          '<a data-fancybox="gallery" href="' + imgPath + imgNameWithPattern + '" data-caption="' + imgName + '" title="' +  imgName + '">' +
                            '<img data-src="' + imgPath + imgNameWithPattern + ' " src="' + imgPath + imgNameWithPattern + ' " data-loaded="true">' +
                          '</a>' +
                        '</div>' +
                      '</div>'
            }
            $(".ImageGrid").append(li);
            this.minigrid();
        },
        minigrid: function() {
            var grid = new Minigrid({
                container: '.ImageGrid',
                item: '.card',
                gutter: 12
            });
            grid.mount();
            $(window).resize(function() {
               grid.mount();
            });
        }
    }
    photo.init();

    然后,在 /source/_data/ 下创建 body-end.swig 文件,并添加如下代码:

    {% if page.type ==='picture' %}
      <script src="//cdn.jsdelivr.net/npm/minigrid@3.1.1/dist/minigrid.min.js"></script>
      <script src="/js/photo.js"></script>
    {% endif %}

    因为这里利用到了主题注入功能,所以需要在主题配置文件启用该功能:

     custom_file_path:
    -  #bodyEnd: source/_data/body-end.swig
    +  bodyEnd: source/_data/body-end.swig

    3. 编辑相册页面

    新建相册页 hexo new page photos,创建 /source/photos/index.md,编辑为以下内容:

    ---
    title: 相册
    type: picture
    comments: true
    
    ---
    
    <style>
    .ImageGrid {
      width: 100%;
      max-width: 1040px;
      margin: 0 auto;
      text-align: center;
    }
    .card {
      overflow: hidden;
      transition: .3s ease-in-out;
      border-radius: 8px;
      background-color: #efefef;
      padding: 1.4px;
    }
    .ImageInCard img {
      padding: 0;
      border-radius: 8px;
    }
    @media (prefers-color-scheme: dark) {
      .card {background-color: #333;}
    }
    </style>
    
    <div class="ImageGrid"></div>
    

    4. 主题配置文件设置

    在主题配置文件中,按照说明安装和开启 fancybox 。在 menu 添加如下内容可以添加相册页导航菜单:

     menu:
    +  photos: /photos/ || fas fa-camera-retro

    相关文章

    班班

    暂无评论

    1. 还没有评论。

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注

    这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理