如何在Hexo中實現自適應響應式相冊功能
用最清晰簡潔的方法整合一個響應式相冊
效果
技術選型
- 由於我選用的主題使用了fancyBox作為圖片彈出展示的框架,查看後表示很不錯,能滿足需要
http://fancyapps.com/fancybox/3/ - 圖片加載可能會太慢,所以還需要一個圖片延遲加載插件 Lazyload
- 想使用瀑布流作為展示,粗略了解了下,便使用開源的MiniGrid,原因是它很小巧也剛好滿足需求(ps:它的文檔讓我看了很捉急,不完善的文檔是個大坑)
相冊文件夾
按照Hexo官方給的建議
資源(Asset)代表 source 文件夾中除了文章以外的所有文件,例如圖片、CSS、JS 文件等。比方說,如果你的Hexo項目中只有少量圖片,那最簡單的方法就是將它們放在 source/images 文件夾中。然後通過類似於
![](/images/image.jpg)
的方法訪問它們。
對於那些想要更有規律地提供圖片和其他資源以及想要將他們的資源分布在各個文章上的人來說,Hexo也提供了更組織化的方式來管理資源。這個稍微有些復雜但是管理資源非常方便的功能可以通過將 config.yml 文件中的post_asset_folder
選項設為true
來打開。
post_asset_folder: true
然後就可以在文件夾source
下新建一個相冊文件夾Images
,將照片放入這個文件夾
相冊頁面
我們需要一個相冊頁面以加載所有照片
--- title: 相冊 noDate: ‘true‘ --- <script src="https://cdn.bootcss.com/jquery_lazyload/1.9.7/jquery.lazyload.js"></script> <script src="https://unpkg.com/[email protected]/dist/minigrid.min.js"></script> <div class="ImageGrid"></div> <script src="/js/photo.js"></script>
這裏使用noDate
來自定義一些HTML數據,加載一些JS文件(minigrid在bootcss中還是1.*的版本,只好使用它推薦的cdn了),其中photo.js
是自定義的,用來加載照片,稍後提到。
現在,我們就有一個相冊頁面了,接下來的問題是怎麽批量加載那些照片。
腳本
大家可以集思廣益,我是用的是一個教程中的腳本改的,與其思路一致。
在博客主文件夾下新建tool.js
:
"use strict"; const fs = require("fs"); const sizeOf = require(‘image-size‘); const path = "./source/Images"; const outputfile = "./source/Images/output.json"; var dimensions; fs.readdir(path, function (err, files) { if (err) { return; } let arr = []; (function iterator(index) { if (index == files.length) { fs.writeFile(outputfile, 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)); });
每次在相冊中更新照片後都要在控制臺node tool.js
一下,以便更新數據。
它會生成一個json文件,帶有每張照片的長寬及文件名。
需要它的寬高是因為我們需要它滿足瀑布流樣式。
output.json樣式類似於:
[
"3120.4160 發票.jpg",
"516.516 頭像.jpg",
"402.180 錄音.jpeg",
"720.758 截圖1.jpg",
"720.978 截圖2.jpg"
]
photo.js
photo ={
page: 1,
offset: 20,
init: function () {
var that = this;
$.getJSON("/photo/output.json", 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, li = "";
for (var i = begin; i < end && i < data.length; i++) {
li += ‘<div class="card">‘ +
‘<div class="ImageInCard">‘ +
‘<a data-fancybox="gallery" href="/Images/‘ + data[i] + ‘">‘ +
‘<img src="/Images/‘ + data[i] + ‘"/>‘ +
‘</a>‘ +
‘</div>‘ +
‘<div class="TextInCard">‘+data[i].split(‘.‘)[0]+‘</div>‘ +
‘</div>‘
}
$(".ImageGrid").append(li);
$(".ImageGrid").lazyload();
this.minigrid();
},
minigrid: function() {
var grid = new Minigrid({
container: ‘.ImageGrid‘,
item: ‘.card‘,
gutter: 12
});
grid.mount();
$(window).resize(function() {
grid.mount();
});
}
}
photo.init();
js文件也可以放在Images文件夾下,只需要將相冊頁面加載的<script src="/js/photo.js"></script>
改成<script src="/Images/photo.js"></script>
即可。
css
這個樣式是我自己寫的,大家可以按照自己的想法自行更改:
.ImageGrid {width: 100%;max-width: 1040px;margin: 0 auto;text-align: center;}
.card {width:160px;height:260px;overflow: hidden;}
.ImageInCard {height:185px}
.ImageInCard img {height:100%;width: auto;padding: 0 0 0 0; }
.TextInCard {height:75;background-color: #fff;}
自動構建
我是使用travis-ci自動構建的。(用過以後表示很雞肋)
如果你也使用了這個的話,在travis.yml
中的script
或者before_script
,添加一句node tool.js
,就可以將相冊腳本也加入自動構建:
script:
- node tool.js
- hexo g
如何在Hexo中實現自適應響應式相冊功能