new
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/artitalk"></script>
|
||||
<div id="artitalk_main"></div>
|
||||
<script>
|
||||
new Artitalk({
|
||||
appId: '<%- theme.artitalk.appId %>',
|
||||
appKey: '<%- theme.artitalk.appKey %>',
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,171 @@
|
||||
<%
|
||||
var colorArr = ['#F9EBEA', '#F5EEF8', '#D5F5E3', '#E8F8F5', '#FEF9E7',
|
||||
'#F8F9F9', '#82E0AA', '#D7BDE2', '#A3E4D7', '#85C1E9', '#F8C471', '#F9E79F', '#FFF'];
|
||||
var colorCount = colorArr.length;
|
||||
var hashCode = function (str) {
|
||||
if (!str && str.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hash = 0;
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
var i = 0;
|
||||
var isCategory = is_category();
|
||||
%>
|
||||
|
||||
<div id="category-cloud" class="container chip-container">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="tag-title center-align">
|
||||
<i class="fas fa-bookmark"></i> <%= __('postCategoryTitle') %>
|
||||
</div>
|
||||
<div class="tag-chips">
|
||||
<% if (site.categories && site.categories.length > 0) { %>
|
||||
<% site.categories.map(function(category) { %>
|
||||
<%
|
||||
i++;
|
||||
// 随机颜色
|
||||
var colors = '#' + Math.random().toString(16).substr(2, 6).toUpperCase();
|
||||
|
||||
/* var color = i >= colorCount
|
||||
? colorArr[Math.abs(hashCode(category.name) % colorCount)]
|
||||
: colorArr[i - 1]; */
|
||||
%>
|
||||
<a href="<%- url_for(category.path) %>" title="<%- category.name %>: <%- category.length %>">
|
||||
<div class="moleskine-wrapper">
|
||||
<div class="moleskine-notebook">
|
||||
<div class="chip notebook-cover center-align waves-effect waves-light
|
||||
<% if (isCategory && category.name == page.category) { %> chip-active <% } else { %> chip-default <% } %>"
|
||||
style="background-color: <%- colors %>;">
|
||||
<div class="notebook-skin
|
||||
<% if (isCategory && category.name == page.category) { %> chip-active <% } else { %> chip-default <% } %>"
|
||||
><%- category.name %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notebook-page dotted"></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<%= __('categoryEmptyTip') %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
/* 文章分类书本样式 */
|
||||
.chip-container .tag-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.chip-container .tag-chips a {
|
||||
margin: 0 7px 10px;
|
||||
}
|
||||
.chip-container .chip {
|
||||
max-width: calc(100% / 4);
|
||||
min-width: 10em;
|
||||
height: 200px;
|
||||
position: relative;
|
||||
transition: .5s linear;
|
||||
padding: 19px 0;
|
||||
line-height: 20px;
|
||||
z-index: 990;
|
||||
border-radius: 5px 15px 15px 5px;
|
||||
transform-origin: left center 0;
|
||||
}
|
||||
.chip-container .notebook-cover::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: calc(100% + 2px);
|
||||
top: -1px;
|
||||
z-index: 100;
|
||||
border-radius: 2px;
|
||||
right: 25px;
|
||||
transition: 2s ease;
|
||||
/* background: linear-gradient(to right,#9c2e2b 0,#cc4b48 12%,#9c2e2b 25%,#cc4b48 37%,#9c2e2b 50%,#cc4b48 62%,#9c2e2b 75%,#cc4b48 87%,#9c2e2b 100%); */
|
||||
background: linear-gradient(to right,#1e606e 0,#2e95aa 12%,#1e606e 25%,#2e95aa 37%,#1e606e 50%,#2e95aa 62%,#1e606e 75%,#2e95aa 87%,#1e606e 100%);
|
||||
}
|
||||
|
||||
.chip .notebook-skin {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background: #e8e8e0;
|
||||
margin-top: 42px;
|
||||
padding: 10px 32px 64px 10px;
|
||||
font-size: 19px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
color: #222;
|
||||
text-align: left;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.2);
|
||||
}
|
||||
.chip .notebook-skin:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 15px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: #cddc39;
|
||||
}
|
||||
.notebook-cover {
|
||||
background: #cc4b48;
|
||||
height: 200px;
|
||||
width: 140px;
|
||||
position: absolute;
|
||||
border-radius: 5px 15px 15px 5px;
|
||||
z-index: 10;
|
||||
transition: .5s linear;
|
||||
transform-style: preserve-3d;
|
||||
transform-origin: left center 0;
|
||||
}
|
||||
|
||||
.moleskine-wrapper {
|
||||
max-width: calc(100% / 4);
|
||||
min-width: 10em;
|
||||
}
|
||||
.moleskine-notebook:hover .notebook-cover {
|
||||
transform: rotateY(-50deg);
|
||||
z-index: 99;
|
||||
box-shadow: 20px 10px 50px rgba(0,0,0,.2);
|
||||
}
|
||||
.moleskine-notebook {
|
||||
height: 200px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
transition: .5s linear;
|
||||
border-radius: 5px 15px 15px 5px;
|
||||
transform-origin: left center 0;
|
||||
}
|
||||
.moleskine-notebook:hover {
|
||||
transform: rotateZ(-10deg);
|
||||
}
|
||||
.notebook-page.dotted {
|
||||
background: linear-gradient(to bottom,#fbfae8 9px,#e4e4e4 1px);
|
||||
background-size: 100% 10px;
|
||||
}
|
||||
.chip-container .chip:hover {
|
||||
background: none;
|
||||
}
|
||||
.notebook-page {
|
||||
height: 100%;
|
||||
width: 140px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
background-color: #fbfae8;
|
||||
z-index: 0;
|
||||
border-radius: 5px 16px 16px 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,74 @@
|
||||
<style type="text/css">
|
||||
#category-radar {
|
||||
width: 100%;
|
||||
height: 360px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container" data-aos="fade-up">
|
||||
<div class="card">
|
||||
<div id="category-radar" class="card-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.echarts) %>"></script>
|
||||
<script type="text/javascript">
|
||||
let radarChart = echarts.init(document.getElementById('category-radar'));
|
||||
|
||||
<%
|
||||
var categories = site.categories;
|
||||
|
||||
// Find the maximum and average values of the post categories.
|
||||
var radarValueArr = [];
|
||||
categories.some(function(category) {
|
||||
radarValueArr.push(category.length);
|
||||
});
|
||||
|
||||
var max = Math.max.apply(null, radarValueArr) + Math.min.apply(null, radarValueArr);
|
||||
|
||||
// Calculate the data needed for the radar chart.
|
||||
var indicatorArr = [];
|
||||
categories.map(function(category) {
|
||||
indicatorArr.push({'name': category.name, 'max': max});
|
||||
});
|
||||
|
||||
var indicatorData = JSON.stringify(indicatorArr);
|
||||
var radarValueData = JSON.stringify(radarValueArr);
|
||||
%>
|
||||
|
||||
let option = {
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '<%= __("categoryRadarTitle") %>',
|
||||
textStyle: {
|
||||
fontWeight: 500,
|
||||
fontSize: 22
|
||||
}
|
||||
},
|
||||
tooltip: {},
|
||||
radar: {
|
||||
name: {
|
||||
textStyle: {
|
||||
color: '#3C4858'
|
||||
}
|
||||
},
|
||||
indicator: <%- indicatorData %>,
|
||||
nameGap: 5,
|
||||
center: ['50%','55%'],
|
||||
radius: '66%'
|
||||
},
|
||||
series: [{
|
||||
type: 'radar',
|
||||
color: ['#3ecf8e'],
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data : [
|
||||
{
|
||||
value : <%- radarValueData %>,
|
||||
name : '<%= __("categoryNumber") %>'
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
radarChart.setOption(option);
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="dream">
|
||||
<% if (theme.dream.showTitle) { %>
|
||||
<div class="title center-align">
|
||||
<i class="far fa-lightbulb"></i> <%= theme.dream.title %>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="row">
|
||||
<div class="col l8 offset-l2 m10 offset-m1 s10 offset-s1 center-align text">
|
||||
<%= theme.dream.text %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,56 @@
|
||||
<link rel="stylesheet" href="<%- theme.jsDelivr.url %><%- url_for(theme.libs.css.aplayer) %>">
|
||||
<style>
|
||||
.aplayer .aplayer-lrc p {
|
||||
<%if(theme.music.hideLrc){%>
|
||||
display: none;
|
||||
<%}%>
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
line-height: 16px !important;
|
||||
}
|
||||
|
||||
.aplayer .aplayer-lrc p.aplayer-lrc-current {
|
||||
<%if(theme.music.hideLrc){%>
|
||||
display: none;
|
||||
<%}%>
|
||||
font-size: 15px;
|
||||
color: <%- theme.music.theme %>;
|
||||
}
|
||||
|
||||
<%if(theme.music.autoHide){%>
|
||||
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
|
||||
left: -66px !important;
|
||||
}
|
||||
|
||||
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
<%}%>
|
||||
</style>
|
||||
<div class="<% if(!theme.music.fixed) { %>music-player<% } %>">
|
||||
<% if (!theme.music.fixed && theme.music.title.enable) { %>
|
||||
<div class="title center-align">
|
||||
<i class="fas fa-music"></i> <%- theme.music.title.show %>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="row">
|
||||
<meting-js class="col l8 offset-l2 m10 offset-m1 s12"
|
||||
server="<%- theme.music.server %>"
|
||||
type="<%- theme.music.type %>"
|
||||
id="<%- theme.music.id %>"
|
||||
fixed='<%- theme.music.fixed ? 'true' : 'false' %>'
|
||||
autoplay='<%- theme.music.autoplay === true %>'
|
||||
theme='<%- theme.music.theme %>'
|
||||
loop='<%- theme.music.loop %>'
|
||||
order='<%- theme.music.order %>'
|
||||
preload='<%- theme.music.preload %>'
|
||||
volume='<%- Number(theme.music.volume) %>'
|
||||
list-folded='<%- theme.music.listFolded ? 'true' : 'false' %>'
|
||||
>
|
||||
</meting-js>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.aplayer) %>"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
|
||||
@@ -0,0 +1,58 @@
|
||||
<link rel="stylesheet" href="<%- theme.libs.css.aplayer %>">
|
||||
<style>
|
||||
.aplayer .aplayer-lrc p {
|
||||
<%if(theme.musics.hideLrc){%>
|
||||
display: none;
|
||||
<%}%>
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
line-height: 16px !important;
|
||||
}
|
||||
|
||||
.aplayer .aplayer-lrc p.aplayer-lrc-current {
|
||||
<%if(theme.musics.hideLrc){%>
|
||||
display: none;
|
||||
<%}%>
|
||||
font-size: 15px;
|
||||
color: <%- theme.musics.theme %>;
|
||||
}
|
||||
|
||||
<%if(theme.musics.autoHide){%>
|
||||
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
|
||||
left: -66px !important;
|
||||
}
|
||||
|
||||
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
<%}%>
|
||||
</style>
|
||||
<div class="<% if(!theme.musics.fixed) { %>music-player<% } %>">
|
||||
<% if (!theme.musics.fixed && theme.musics.title.enable) { %>
|
||||
<div class="title center-align">
|
||||
<i class="fa fa-music"></i> <%- theme.musics.title.show %>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="row">
|
||||
<meting-js class="col l8 offset-l2 m10 offset-m1 s12"
|
||||
server="<%- theme.musics.server %>"
|
||||
type="<%- theme.musics.type %>"
|
||||
id="<%- theme.musics.id %>"
|
||||
fixed='<%- theme.musics.fixed ? 'true' : 'false' %>'
|
||||
autoplay='<%- theme.musics.autoplay === true %>'
|
||||
theme='<%- theme.musics.theme %>'
|
||||
loop='<%- theme.musics.loop %>'
|
||||
order='<%- theme.musics.order %>'
|
||||
preload='<%- theme.musics.preload %>'
|
||||
volume='<%- Number(theme.musics.volume) %>'
|
||||
listMaxHeight='<%- theme.musics.listMaxHeight %>'
|
||||
list-folded='<%- theme.musics.listFolded ? 'true' : 'false' %>'
|
||||
>
|
||||
</meting-js>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="<%- theme.libs.js.aplayer %>"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
|
||||
@@ -0,0 +1,31 @@
|
||||
<%
|
||||
// the gallery photos of theme _config.yml.
|
||||
var gallery = theme.myGallery.data;
|
||||
%>
|
||||
<div id="myGallery" class="my-gallery">
|
||||
<div class="title center-align" data-aos="zoom-in-up">
|
||||
<i class="far fa-image"></i> <%- __('gallery') %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<% if (gallery) { %>
|
||||
<% Object.keys(gallery).forEach(function(photo) { %>
|
||||
<div class="photo col s12 m6 l4" data-aos="fade-up">
|
||||
<div class="img-item" data-src="<%- gallery[photo] %>">
|
||||
<img src="<%- theme.jsDelivr.url %><%- url_for(gallery[photo]) %>" class="responsive-img">
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
let animateClass = 'animated pulse';
|
||||
$('#myGallery .photo').hover(function () {
|
||||
$(this).addClass(animateClass);
|
||||
}, function () {
|
||||
$(this).removeClass(animateClass);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,27 @@
|
||||
<%
|
||||
// the projects information of theme _config.yml.
|
||||
var myprojects = theme.myProjects.data;
|
||||
%>
|
||||
<div class="my-projects">
|
||||
<div class="title center-align" data-aos="zoom-in-up">
|
||||
<i class="fas fa-gift"></i> <%- __('myProjects') %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<% if (myprojects) { %>
|
||||
<% Object.keys(myprojects).forEach(function(project) { %>
|
||||
<div class="col s12 m6 l4" data-aos="fade-up">
|
||||
<div class="info center-align">
|
||||
<a href="<%- myprojects[project].url %>" class="icon"
|
||||
style="background: <%- myprojects[project].iconBackground %>" target="_blank">
|
||||
<i class="<%- myprojects[project].icon %>"></i>
|
||||
</a>
|
||||
<div class="info-title">
|
||||
<a href="<%- url_for(myprojects[project].url) %>" target="_blank"><%- project %></a>
|
||||
</div>
|
||||
<div class="info-desc"><%= myprojects[project].desc %></div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,59 @@
|
||||
<%
|
||||
// the skills information of theme _config.yml.
|
||||
var mySkills = theme.mySkills.data;
|
||||
var topSkillArr = [];
|
||||
%>
|
||||
<div class="my-skills">
|
||||
<div class="title center-align" data-aos="zoom-in-up">
|
||||
<i class="fas fa-wrench"></i> <%- __('mySkills') %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<% if (mySkills) { %>
|
||||
<% Object.keys(mySkills).forEach(function(skill) { %>
|
||||
<% topSkillArr.push(skill); %>
|
||||
<div class="col s12 m6 l6" data-aos="fade-up">
|
||||
<div class="skillbar">
|
||||
<div class="skillbar-title"
|
||||
style="background: <%- mySkills[skill].background %>; width: <%- mySkills[skill].percent %>">
|
||||
<span><%- skill %></span>
|
||||
</div>
|
||||
<div class="skill-bar-percent"><%- mySkills[skill].percent %></div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<%
|
||||
/**
|
||||
* Determine if an element is included in the array.
|
||||
*
|
||||
* @param arr array
|
||||
* @param value value
|
||||
*/
|
||||
var isInArray = function (arr, value) {
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (value == arr[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
%>
|
||||
|
||||
<% if (site.tags) { %>
|
||||
<div class="other-skills chip-container" data-aos="zoom-in-up">
|
||||
<div class="sub-title center-align"><i class="fa fa-book"></i> <%- __('otherSkills') %></div>
|
||||
<div class="tag-chips center-align">
|
||||
<% site.tags.map(function(tag) { %>
|
||||
<% if (!isInArray(topSkillArr, tag.name)) { %>
|
||||
<a href="<%- url_for(tag.path) %>">
|
||||
<span class="chip center-align waves-effect waves-light chip-default"><%- tag.name %></span>
|
||||
</a>
|
||||
<% } %>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,110 @@
|
||||
<div class="container archive-calendar">
|
||||
<div class="card">
|
||||
<div id="post-calendar" class="card-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.echarts) %>"></script>
|
||||
<script type="text/javascript">
|
||||
let myChart = echarts.init(document.getElementById('post-calendar'));
|
||||
|
||||
<%
|
||||
var nameMap = (config.language && config.language.indexOf('zh') >= 0) ? 'cn' : 'en';
|
||||
var titleText = (config.language && config.language.indexOf('zh') >= 0) ? '文章日历' : 'Post Calendar';
|
||||
|
||||
// calculate range.
|
||||
var startDate = moment().subtract(1, 'years');
|
||||
var endDate = moment();
|
||||
var rangeArr = '["' + startDate.format('YYYY-MM-DD') + '", "' + endDate.format('YYYY-MM-DD') + '"]';
|
||||
|
||||
// post and count map.
|
||||
var dateMap = new Map();
|
||||
site.posts.forEach(function (post) {
|
||||
var date = post.date.format('YYYY-MM-DD');
|
||||
var count = dateMap.get(date);
|
||||
dateMap.set(date, count == null || count == undefined ? 1 : count + 1);
|
||||
});
|
||||
|
||||
// loop the data for the current year, generating the number of post per day
|
||||
var i = 0;
|
||||
var datePosts = '[';
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
for (var time = startDate; time <= endDate; time += dayTime) {
|
||||
var date = moment(time).format('YYYY-MM-DD');
|
||||
datePosts = (i === 0 ? datePosts + '["' : datePosts + ', ["') + date + '", '
|
||||
+ (dateMap.has(date) ? dateMap.get(date) : 0) + ']';
|
||||
i++;
|
||||
}
|
||||
datePosts += ']';
|
||||
%>
|
||||
|
||||
let option = {
|
||||
title: {
|
||||
top: 0,
|
||||
text: '<%- titleText %>',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#3C4858'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
padding: 10,
|
||||
backgroundColor: '#555',
|
||||
borderColor: '#777',
|
||||
borderWidth: 1,
|
||||
formatter: function (obj) {
|
||||
var value = obj.value;
|
||||
return '<div style="font-size: 14px;">' + value[0] + ':' + value[1] + '</div>';
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
show: true,
|
||||
showLabel: true,
|
||||
categories: [0, 1, 2, 3, 4],
|
||||
calculable: true,
|
||||
inRange: {
|
||||
symbol: 'rect',
|
||||
color: ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']
|
||||
},
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
orient: 'horizontal',
|
||||
left: 'center',
|
||||
bottom: 0
|
||||
},
|
||||
calendar: [{
|
||||
left: 'center',
|
||||
range: <%- rangeArr %>,
|
||||
cellSize: [13, 13],
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#196127',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
yearLabel: {
|
||||
show: false
|
||||
},
|
||||
monthLabel: {
|
||||
nameMap: '<%- nameMap %>',
|
||||
fontSize: 11
|
||||
},
|
||||
dayLabel: {
|
||||
formatter: '{start} 1st',
|
||||
nameMap: '<%- nameMap %>',
|
||||
fontSize: 11
|
||||
}
|
||||
}],
|
||||
series: [{
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
calendarIndex: 0,
|
||||
data: <%- datePosts %>
|
||||
}]
|
||||
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
</script>
|
||||
@@ -0,0 +1,218 @@
|
||||
<style type="text/css">
|
||||
#posts-chart,
|
||||
#categories-chart,
|
||||
#tags-chart {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="postCharts" class="post-charts">
|
||||
<div class="title center-align" data-aos="zoom-in-up">
|
||||
<i class="far fa-bar-chart"></i> <%- __('postCharts') %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="chart col s12 m6 l4" data-aos="zoom-in-up">
|
||||
<div id="posts-chart"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart col s12 m6 l4" data-aos="zoom-in-up">
|
||||
<div id="categories-chart"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart col s12 m6 l4" data-aos="zoom-in-up">
|
||||
<div id="tags-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.echarts) %>"></script>
|
||||
<script>
|
||||
let postsChart = echarts.init(document.getElementById('posts-chart'));
|
||||
let categoriesChart = echarts.init(document.getElementById('categories-chart'));
|
||||
let tagsChart = echarts.init(document.getElementById('tags-chart'));
|
||||
|
||||
<%
|
||||
/* calculate postsOption data. */
|
||||
var startDate = moment().subtract(1, 'years').startOf('month');
|
||||
var endDate = moment().endOf('month');
|
||||
|
||||
var monthMap = new Map();
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
for (var time = startDate; time <= endDate; time += dayTime) {
|
||||
var month = moment(time).format('YYYY-MM');
|
||||
if (!monthMap.has(month)) {
|
||||
monthMap.set(month, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// post and count map.
|
||||
site.posts.forEach(function (post) {
|
||||
var month = post.date.format('YYYY-MM');
|
||||
if (monthMap.has(month)) {
|
||||
monthMap.set(month, monthMap.get(month) + 1);
|
||||
}
|
||||
});
|
||||
|
||||
// xAxis data and yAxis data.
|
||||
var monthArr = JSON.stringify([...monthMap.keys()]);
|
||||
var monthValueArr = JSON.stringify([...monthMap.values()]);
|
||||
%>
|
||||
|
||||
let postsOption = {
|
||||
title: {
|
||||
text: '<%- __("postPublishChart") %>',
|
||||
top: -5,
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: <%- monthArr %>
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '<%- __("postsNumberName") %>',
|
||||
type: 'line',
|
||||
color: ['#6772e5'],
|
||||
data: <%- monthValueArr %>,
|
||||
markPoint: {
|
||||
symbolSize: 45,
|
||||
color: ['#fa755a','#3ecf8e','#82d3f4'],
|
||||
data: [{
|
||||
type: 'max',
|
||||
itemStyle: {color: ['#3ecf8e']},
|
||||
name: '<%- __("maximum") %>'
|
||||
}, {
|
||||
type: 'min',
|
||||
itemStyle: {color: ['#fa755a']},
|
||||
name: '<%- __("minimum") %>'
|
||||
}]
|
||||
},
|
||||
markLine: {
|
||||
itemStyle: {color: ['#ab47bc']},
|
||||
data: [
|
||||
{type: 'average', name: '<%- __("average") %>'}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
<%
|
||||
/* calculate categoriesOption data. */
|
||||
var categoryArr = [];
|
||||
site.categories.map(function(category) {
|
||||
categoryArr.push({'name': category.name, 'value': category.length})
|
||||
});
|
||||
|
||||
var categoryArrJson = JSON.stringify(categoryArr);
|
||||
%>
|
||||
|
||||
let categoriesOption = {
|
||||
title: {
|
||||
text: '<%- __("categoriesChart") %>',
|
||||
top: -4,
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: "{a} <br/>{b} : {c} ({d}%)"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '<%- __("categories") %>',
|
||||
type: 'pie',
|
||||
radius: '50%',
|
||||
color: ['#6772e5', '#ff9e0f', '#fa755a', '#3ecf8e', '#82d3f4', '#ab47bc', '#525f7f', '#f51c47', '#26A69A'],
|
||||
data: <%- categoryArrJson %>,
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
<%
|
||||
/* calculate tagsOption data. */
|
||||
// get all tags name and count,then order by length desc.
|
||||
var tagArr = [];
|
||||
site.tags.map(function(tag) {
|
||||
tagArr.push({'name': tag.name, 'value': tag.length});
|
||||
});
|
||||
tagArr.sort((a, b) => {return b.value - a.value});
|
||||
|
||||
// get Top 10 tags name and count.
|
||||
var tagNameArr = [];
|
||||
var tagCountArr = [];
|
||||
for (var i = 0, len = Math.min(tagArr.length, 10); i < len; i++) {
|
||||
tagNameArr.push(tagArr[i].name);
|
||||
tagCountArr.push(tagArr[i].value);
|
||||
}
|
||||
|
||||
var tagNameArrJson = JSON.stringify(tagNameArr);
|
||||
var tagCountArrJson = JSON.stringify(tagCountArr);
|
||||
%>
|
||||
|
||||
let tagsOption = {
|
||||
title: {
|
||||
text: '<%- __("top10TagsChart") %>',
|
||||
top: -5,
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: <%- tagNameArrJson %>
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
color: ['#82d3f4'],
|
||||
barWidth : 18,
|
||||
data: <%- tagCountArrJson %>,
|
||||
markPoint: {
|
||||
symbolSize: 45,
|
||||
data: [{
|
||||
type: 'max',
|
||||
itemStyle: {color: ['#3ecf8e']},
|
||||
name: '<%- __("maximum") %>'
|
||||
}, {
|
||||
type: 'min',
|
||||
itemStyle: {color: ['#fa755a']},
|
||||
name: '<%- __("minimum") %>'
|
||||
}],
|
||||
},
|
||||
markLine: {
|
||||
itemStyle: {color: ['#ab47bc']},
|
||||
data: [
|
||||
{type: 'average', name: '<%- __("average") %>'}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// render the charts
|
||||
postsChart.setOption(postsOption);
|
||||
categoriesChart.setOption(categoriesOption);
|
||||
tagsChart.setOption(tagsOption);
|
||||
</script>
|
||||
@@ -0,0 +1,131 @@
|
||||
<%
|
||||
// get all top posts.
|
||||
var topPosts = [];
|
||||
if (theme.recommend.useConfig) {
|
||||
topPosts = site.data.recommends;
|
||||
} else {
|
||||
site.posts.forEach(function (post) {
|
||||
if (post.top) {
|
||||
topPosts.push(post);
|
||||
}
|
||||
});
|
||||
}
|
||||
var topPostsCount = topPosts.length;
|
||||
%>
|
||||
|
||||
<% if (topPostsCount > 0) { %>
|
||||
<%
|
||||
var hashCode = function (str) {
|
||||
if (!str && str.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hash = 0;
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
||||
var featureImages = theme.featureImages;
|
||||
var imgCount = featureImages.length;
|
||||
var bgColorArr = [
|
||||
'linear-gradient(to right, #FF5E3A 0%, #FF2A68 100%)',
|
||||
'linear-gradient(to right, #EF4DB6 0%, #C643FC 100%)',
|
||||
'linear-gradient(to right, #1AD6FD 0%, #1D62F0 100%)',
|
||||
'linear-gradient(to right, #FFCC00 0%, #FF9500 100%)',
|
||||
'linear-gradient(to right, #4cbf30 0%, #0f9d58 100%)',
|
||||
'linear-gradient(to right, #C644FC 0%, #5856D6 100%)',
|
||||
'linear-gradient(to right, #55EFCB 0%, #5BCAFF 100%)'];
|
||||
var colorCount = bgColorArr.length;
|
||||
%>
|
||||
|
||||
<% if (theme.recommend.showTitle) { %>
|
||||
<div class="title"><i class="far fa-thumbs-up"></i> <%- __('recommendedPosts') %></div>
|
||||
<% } %>
|
||||
<div class="row">
|
||||
<% if (topPostsCount % 2 === 0) { %>
|
||||
<% for (var i = 0; i < topPostsCount; i++) { %>
|
||||
<%
|
||||
var post = topPosts[i];
|
||||
var featureImg = post.img ? url_for(post.img) : url_for(featureImages[Math.abs(hashCode(post.title) % imgCount)]);
|
||||
var bgColor = bgColorArr[i % colorCount];
|
||||
%>
|
||||
<div class="col s12 m6" <% if (i > 1) { %>data-aos="zoom-in-up"<% } %>>
|
||||
<% if (post.img) {%>
|
||||
<div class="post-card" style="background-image: url('<%- featureImg %>')">
|
||||
<%}else{%>
|
||||
<div class="post-card" style="background-image: url('<%- theme.jsDelivr.url %><%- featureImg %>')">
|
||||
<% } %>
|
||||
<div class="post-body">
|
||||
<div class="post-categories">
|
||||
<% if (theme.recommend.useConfig) { %>
|
||||
<a href="<%- url_for(post.categoryPath) %>" class="category"><%= post.categoryName %></a>
|
||||
<% } else { %>
|
||||
<% post.categories.forEach(category => { %>
|
||||
<a href="<%- url_for(category.path) %>" class="category"><%= category.name %></a>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
<a href="<%- url_for(post.path) %>">
|
||||
<h3 class="post-title"><%= post.title %></h3>
|
||||
</a>
|
||||
<p class="post-description">
|
||||
<% if (post.summary && post.summary.length > 0) { %>
|
||||
<%- post.summary %>
|
||||
<% } else { %>
|
||||
<%- strip_html(post.content).substring(0, 70) %>
|
||||
<% } %>
|
||||
</p>
|
||||
<a href="<%- url_for(post.path) %>" class="read-more btn waves-effect waves-light" style="background: <%- bgColor %>" target="_blank">
|
||||
<i class="icon far fa-eye fa-fw"></i><%- __('readMore') %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } else { %>
|
||||
<% for (var i = 0; i < topPostsCount; i++) { %>
|
||||
<%
|
||||
var post = topPosts[i];
|
||||
var grid = (i % 3 === 0) ? 's12' : 's12 m6';
|
||||
var description = (i % 3 === 0) ? strip_html(post.content).substring(0, 85)
|
||||
: strip_html(post.content).substring(0, 70);
|
||||
if (post.summary && post.summary.length > 0) {
|
||||
description = post.summary;
|
||||
}
|
||||
|
||||
var featureImg = post.img ? url_for(post.img) : url_for(featureImages[Math.abs(hashCode(post.title) % imgCount)]);
|
||||
var bgColor = bgColorArr[i % colorCount];
|
||||
%>
|
||||
<div class="col <%- grid %>" <% if (i > 0) { %>data-aos="zoom-in-up"<% } %>>
|
||||
<% if (post.img) {%>
|
||||
<div class="post-card" style="background-image: url('<%- featureImg %>')">
|
||||
<%}else{%>
|
||||
<div class="post-card" style="background-image: url('<%- theme.jsDelivr.url %><%- featureImg %>')">
|
||||
<% } %>
|
||||
<div class="post-body">
|
||||
<div class="post-categories">
|
||||
<% if (theme.recommend.useConfig) { %>
|
||||
<a href="<%- url_for(post.categoryPath) %>" class="category"><%= post.categoryName %></a>
|
||||
<% } else { %>
|
||||
<% post.categories.forEach(category => { %>
|
||||
<a href="<%- url_for(category.path) %>" class="category"><%= category.name %></a>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
<a href="<%- url_for(post.path) %>">
|
||||
<h3 class="post-title"><%= post.title %></h3>
|
||||
</a>
|
||||
<p class="post-description"><%= description %></p>
|
||||
<a href="<%- url_for(post.path) %>" class="read-more btn waves-effect waves-light" style="background: <%- bgColor %>" target="_blank">
|
||||
<i class="icon far fa-eye fa-fw"></i><%- __('readMore') %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
@@ -0,0 +1,45 @@
|
||||
<%
|
||||
var colorArr = ['#F9EBEA', '#F5EEF8', '#D5F5E3', '#E8F8F5', '#FEF9E7',
|
||||
'#F8F9F9', '#82E0AA', '#D7BDE2', '#A3E4D7', '#85C1E9', '#F8C471', '#F9E79F', '#FFF'];
|
||||
var colorCount = colorArr.length;
|
||||
var hashCode = function (str) {
|
||||
if (!str && str.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hash = 0;
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
var i = 0;
|
||||
var isTag = is_tag();
|
||||
%>
|
||||
|
||||
<div id="tags" class="container chip-container">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="tag-title center-align">
|
||||
<i class="fas fa-tags"></i> <%= __('postTagTitle') %>
|
||||
</div>
|
||||
<div class="tag-chips">
|
||||
<% site.tags.map(function(tag) { %>
|
||||
<%
|
||||
i++;
|
||||
var color = i >= colorCount ? colorArr[Math.abs(hashCode(tag.name) % colorCount)]
|
||||
: colorArr[i - 1];
|
||||
%>
|
||||
<a href="<%- url_for(tag.path) %>" title="<%- tag.name %>: <%- tag.length %>">
|
||||
<span class="chip center-align waves-effect waves-light
|
||||
<% if (isTag && tag.name == page.tag) { %> chip-active <% } else { %> chip-default <% } %>"
|
||||
data-tagname="<%- tag.name %>" style="background-color: <%- color %>;"><%- tag.name %>
|
||||
<span class="tag-length"><%- tag.length %></span>
|
||||
</span>
|
||||
</a>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,29 @@
|
||||
<link rel="stylesheet" type="text/css" href="<%- theme.jsDelivr.url %><%- url_for(theme.libs.css.jqcloud) %>">
|
||||
<style type="text/css">
|
||||
#tag-wordcloud {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container" data-aos="fade-up">
|
||||
<div class="card">
|
||||
<div id="tag-wordcloud" class="card-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.jqcloud) %>"></script>
|
||||
<script type="text/javascript">
|
||||
<%
|
||||
let tagWordArr = [];
|
||||
site.tags.map(function(tag) {
|
||||
tagWordArr.push({'text': tag.name, 'weight': tag.length, 'link': decodeURI(url_for(tag.path))});
|
||||
});
|
||||
|
||||
let tagWords = JSON.stringify(tagWordArr);
|
||||
%>
|
||||
|
||||
$('#tag-wordcloud').jQCloud(<%- tagWords %>, {
|
||||
autoResize: true
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,34 @@
|
||||
<link rel="stylesheet" href="<%- theme.jsDelivr.url %><%- url_for(theme.libs.css.dplayer) %>">
|
||||
<div class="video-player">
|
||||
<% if (theme.video.showTitle) { %>
|
||||
<div class="title center-align">
|
||||
<i class="fas fa-video-camera"></i> <%= theme.video.title %>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="row">
|
||||
<div class="col l8 offset-l2 m10 offset-m1 s12">
|
||||
<div id="dplayer" class="dplayer-video"
|
||||
<% if (theme.video.height) { %> style="height: <%- theme.video.height %>px;"<% } %>></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.dplayer) %>"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
new DPlayer({
|
||||
container: document.getElementById('dplayer'),
|
||||
autoplay: '<%- theme.video.autoplay %>' === 'true',
|
||||
theme: '<%- theme.video.theme %>',
|
||||
loop: '<%- theme.video.loop %>' === 'true',
|
||||
lang: '<%- config.language %>' === 'zh-CN' ? 'zh-cn' : 'en',
|
||||
preload: '<%- theme.video.preload %>',
|
||||
volume: Number('<%- theme.video.volume %>'),
|
||||
video: {
|
||||
url: '<% if (theme.video.url) { %><%- url_for(theme.video.url) %><% } %>',
|
||||
pic: '<% if (theme.video.pic) { %><%- url_for(theme.video.pic) %><% } %>',
|
||||
thumbnails: '<% if (theme.video.thumbnails) { %><%- url_for(theme.video.thumbnails) %><% } %>'
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user