hexo-theme-particlex 2.5.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -66,11 +66,15 @@ theme: particlex
66
66
  ## 配置
67
67
 
68
68
  ```yaml
69
- avatar: # Avatar image
70
- headBlockEnable: true # Home page info block
71
- background: # Home page background image
69
+ avatar:
70
+
71
+ headBlockEnable: true
72
+
73
+ background:
72
74
  ```
73
75
 
76
+ 其中 Background 可以是一个列表,打开时会随机加载一个背景
77
+
74
78
  - 导航栏
75
79
 
76
80
  为了方便,主题使用的图标是 Font Awesome 6 图标
@@ -80,27 +84,27 @@ background: # Home page background image
80
84
  Home:
81
85
  name: house
82
86
  theme: solid
83
- src: /
87
+ link: /
84
88
  About:
85
89
  name: id-card
86
90
  theme: solid
87
- src: /about
91
+ link: /about
88
92
  Archives:
89
93
  name: box-archive
90
94
  theme: solid
91
- src: /archives
95
+ link: /archives
92
96
  Categories:
93
97
  name: bookmark
94
98
  theme: solid
95
- src: /categories
99
+ link: /categories
96
100
  Tags:
97
101
  name: tags
98
102
  theme: solid
99
- src: /tags
103
+ link: /tags
100
104
  # <name>:
101
105
  # name: <icon-name>
102
106
  # theme: <icon-theme>
103
- # src: <link-url>
107
+ # link: <link-url>
104
108
  ```
105
109
 
106
110
  - 主页信息卡片
@@ -190,6 +194,15 @@ background: # Home page background image
190
194
  enable: false
191
195
  ```
192
196
 
197
+ - 图片预览
198
+
199
+ 简单的点击图片放大缩小的预览
200
+
201
+ ```yaml
202
+ preview:
203
+ enable: true
204
+ ```
205
+
193
206
  - 文章置顶
194
207
 
195
208
  在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `pinned` 作为置顶参数,越大越靠前,默认为 0
package/_config.yml CHANGED
@@ -18,27 +18,27 @@ menu:
18
18
  Home:
19
19
  name: house
20
20
  theme: solid
21
- src: /
21
+ link: /
22
22
  About:
23
23
  name: id-card
24
24
  theme: solid
25
- src: /about
25
+ link: /about
26
26
  Archives:
27
27
  name: box-archive
28
28
  theme: solid
29
- src: /archives
29
+ link: /archives
30
30
  Categories:
31
31
  name: bookmark
32
32
  theme: solid
33
- src: /categories
33
+ link: /categories
34
34
  Tags:
35
35
  name: tags
36
36
  theme: solid
37
- src: /tags
37
+ link: /tags
38
38
  # <name>:
39
39
  # name: <icon-name>
40
40
  # theme: <icon-theme>
41
- # src: <link-url>
41
+ # link: <link-url>
42
42
 
43
43
  # Side info card
44
44
  card:
@@ -82,6 +82,10 @@ highlight:
82
82
  math:
83
83
  enable: false
84
84
 
85
+ # Image Preview
86
+ preview:
87
+ enable: true
88
+
85
89
  # Article encryption
86
90
  crypto:
87
91
  enable: false
@@ -41,9 +41,9 @@
41
41
  "color: #00a596",
42
42
  "color: #ff7d73",
43
43
  ];
44
- let num = Math.floor(Math.random() * color.length);
44
+ let id = Math.floor(Math.random() * color.length);
45
45
  %>
46
- <a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
46
+ <a href="<%- url_for(data.path) %>" style="<%- color[id] %>"><%= data.name %></a>
47
47
  </span>
48
48
  <% }); %>
49
49
  </span>
@@ -6,10 +6,10 @@
6
6
  const color = is_category(category.name)
7
7
  ? ["linear-gradient(120deg, #9abbf7 0%, #ffbbf4 100%)"]
8
8
  : ["#ffa2c4", "#00bcd4", "#03a9f4", "#00a596", "#ff7d73"];
9
- let num = Math.floor(Math.random() * color.length);
9
+ let id = Math.floor(Math.random() * color.length);
10
10
  %>
11
11
  <span>
12
- <a href="<%- url_for(category.path) %>" style="background: <%- color[num] %>">
12
+ <a href="<%- url_for(category.path) %>" style="background: <%- color[id] %>">
13
13
  <span class="icon">
14
14
  <i class="fa-solid fa-bookmark fa-fw"></i>
15
15
  </span>
@@ -58,9 +58,9 @@
58
58
  "color: #00a596",
59
59
  "color: #ff7d73",
60
60
  ];
61
- let num = Math.floor(Math.random() * color.length);
61
+ let id = Math.floor(Math.random() * color.length);
62
62
  %>
63
- <a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
63
+ <a href="<%- url_for(data.path) %>" style="<%- color[id] %>"><%= data.name %></a>
64
64
  </span>
65
65
  <% }); %>
66
66
  </span>
package/layout/footer.ejs CHANGED
@@ -16,7 +16,7 @@
16
16
  <div>
17
17
  备案号:
18
18
  <% if (theme.footer.ICP.link) { %>
19
- <a href="<%- theme.footer.ICP.link %>"><%= theme.footer.ICP.code %></a>
19
+ <a href="<%- url_for(theme.footer.ICP.link) %>"><%= theme.footer.ICP.code %></a>
20
20
  <% } else { %>
21
21
  <%= theme.footer.ICP.code %>
22
22
  <% } %>
package/layout/import.ejs CHANGED
@@ -1,7 +1,10 @@
1
1
  <script src="https://cdn.staticfile.org/vue/3.2.45/vue.global.prod.min.js"></script>
2
2
  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.2.1/css/all.min.css" />
3
3
  <link rel="stylesheet" href="<%- url_for("/css/fonts.min.css") %>" />
4
- <script>const mixins = [];</script>
4
+ <script> const mixins = {}; </script>
5
+ <% if (theme.polyfill.enable) { %>
6
+ <script src="https://polyfill.io/v3/polyfill.min.js?features=<%- theme.polyfill.features %>"></script>
7
+ <% } %>
5
8
  <% if (theme.highlight.enable) { %>
6
9
  <script src="https://cdn.staticfile.org/highlight.js/11.7.0/highlight.min.js"></script>
7
10
  <link
@@ -10,23 +13,23 @@
10
13
  />
11
14
  <script src="<%- url_for("/js/lib/highlight.js") %>"></script>
12
15
  <% } %>
13
- <% if (theme.polyfill.enable) { %>
14
- <script src="https://polyfill.io/v3/polyfill.min.js?features=<%- theme.polyfill.features.join(",") %>"></script>
15
- <% } %>
16
16
  <% if (theme.math.enable) { %>
17
17
  <script src="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.js"></script>
18
18
  <script src="https://cdn.staticfile.org/KaTeX/0.16.4/contrib/auto-render.min.js"></script>
19
19
  <link rel="stylesheet" href="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.css" />
20
20
  <script src="<%- url_for("/js/lib/math.js") %>"></script>
21
21
  <% } %>
22
+ <% if (theme.preview.enable) { %>
23
+ <script src="<%- url_for("/js/lib/preview.js") %>"></script>
24
+ <% } %>
22
25
  <% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
23
26
  <script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
24
27
  <script src="<%- url_for("/js/lib/crypto.js") %>"></script>
25
28
  <% } %>
26
- <% if (theme.search.enable && type === "archives") { %>
29
+ <% if (type === "archives" && theme.search.enable) { %>
27
30
  <script src="<%- url_for("/js/lib/search.js") %>"></script>
28
31
  <% } %>
29
- <% if (page.comments && type === "post") { %>
32
+ <% if (type === "post" && page.comments) { %>
30
33
  <% if (theme.gitalk.enable) { %>
31
34
  <script src="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.js"></script>
32
35
  <link rel="stylesheet" href="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.css" />
@@ -40,5 +43,7 @@
40
43
  <script src="https://cdn.staticfile.org/twikoo/1.6.8/twikoo.all.min.js"></script>
41
44
  <% } %>
42
45
  <% } %>
43
- <script src="<%- url_for("/js/lib/preview.js") %>"></script>
46
+ <% if (type === "index") %>
47
+ <script src="<%- url_for("/js/lib/home.js") %>"></script>
48
+ <% %>
44
49
  <link rel="stylesheet" href="<%- url_for("/css/main.css") %>" />
package/layout/index.ejs CHANGED
@@ -1,5 +1,5 @@
1
- <div id="home-head" ref="head">
2
- <div id="home-background" style="background-image: url(<%- theme.background %>)"></div>
1
+ <div id="home-head">
2
+ <div id="home-background" ref="homeBackground" data-image="<% url_for(theme.background) %>"></div>
3
3
  <% if (theme.headBlockEnable) { %>
4
4
  <div id="home-info" @click="homeClick">
5
5
  <span class="loop"></span>
@@ -16,7 +16,7 @@
16
16
  </div>
17
17
  <% } %>
18
18
  </div>
19
- <div id="home-posts-wrap" <%- theme.card.enable ? "" : 'class="home-posts-wrap-no-card"' %> ref="wrap">
19
+ <div id="home-posts-wrap" <%- theme.card.enable ? "" : 'class="home-posts-wrap-no-card"' %> ref="homePostsWrap">
20
20
  <div id="home-posts">
21
21
  <div id="posts">
22
22
  <%- partial("posts") %>
package/layout/layout.ejs CHANGED
@@ -51,11 +51,13 @@
51
51
  <%- partial("footer") %>
52
52
  </div>
53
53
  </transition>
54
+ <% if (theme.preview.enable) { %>
54
55
  <transition name="fade">
55
56
  <div id="preview" ref="preview" v-show="previewShow">
56
57
  <img id="preview-content" ref="previewContent" />
57
58
  </div>
58
59
  </transition>
60
+ <% } %>
59
61
  </div>
60
62
  <script src="<%- url_for("/js/main.js") %>"></script>
61
63
  <% if (type === "post" && page.comments) { %>
package/layout/menu.ejs CHANGED
@@ -4,7 +4,7 @@
4
4
  <span><%= config.title.toUpperCase() %></span>
5
5
  </a>
6
6
  <% Object.keys(theme.menu).forEach(key => { %>
7
- <a href="<%- url_for(theme.menu[key].src) %>">
7
+ <a href="<%- url_for(theme.menu[key].link) %>">
8
8
  <i class="fa-<%- theme.menu[key].theme %> fa-<%- theme.menu[key].name %> fa-fw"></i>
9
9
  <span>&ensp;<%= key %></span>
10
10
  </a>
@@ -19,7 +19,7 @@
19
19
  <transition name="slide">
20
20
  <div class="items" v-show="showMenu">
21
21
  <% Object.keys(theme.menu).forEach(key => { %>
22
- <a href="<%- url_for(theme.menu[key].src) %>">
22
+ <a href="<%- url_for(theme.menu[key].link) %>">
23
23
  <div class="item">
24
24
  <div style="min-width: 20px; max-width: 50px; width: 10%">
25
25
  <i class="fa-<%- theme.menu[key].theme %> fa-<%- theme.menu[key].name %> fa-fw"></i>
package/layout/post.ejs CHANGED
@@ -1,6 +1,6 @@
1
1
  <div class="article">
2
2
  <div>
3
- <h1><%= page.title %> </h1>
3
+ <h1><%= page.title %></h1>
4
4
  </div>
5
5
  <div class="info">
6
6
  <span class="date">
@@ -34,9 +34,9 @@
34
34
  "color: #00a596",
35
35
  "color: #ff7d73",
36
36
  ];
37
- let num = Math.floor(Math.random() * color.length);
37
+ let id = Math.floor(Math.random() * color.length);
38
38
  %>
39
- <a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
39
+ <a href="<%- url_for(data.path) %>" style="<%- color[id] %>"><%= data.name %></a>
40
40
  </span>
41
41
  <% }); %>
42
42
  </span>
package/layout/posts.ejs CHANGED
@@ -68,9 +68,9 @@
68
68
  "color: #00a596",
69
69
  "color: #ff7d73",
70
70
  ];
71
- let num = Math.floor(Math.random() * color.length);
71
+ let id = Math.floor(Math.random() * color.length);
72
72
  %>
73
- <a href="<%- url_for(data.path) %>" style="<%- color[num] %>">
73
+ <a href="<%- url_for(data.path) %>" style="<%- color[id] %>">
74
74
  <%= data.name %>
75
75
  </a>
76
76
  </span>
package/layout/tags.ejs CHANGED
@@ -6,10 +6,10 @@
6
6
  const color = is_tag(tag.name)
7
7
  ? ["linear-gradient(120deg, #9abbf7 0%, #ffbbf4 100%)"]
8
8
  : ["#ffa2c4", "#00bcd4", "#03a9f4", "#00a596", "#ff7d73"];
9
- let num = Math.floor(Math.random() * color.length);
9
+ let id = Math.floor(Math.random() * color.length);
10
10
  %>
11
11
  <span>
12
- <a href="<%- url_for(tag.path) %>" style="background: <%- color[num] %>">
12
+ <a href="<%- url_for(tag.path) %>" style="background: <%- color[id] %>">
13
13
  <span class="icon">
14
14
  <i class="fa-solid fa-tags fa-fw"></i>
15
15
  </span>
@@ -58,9 +58,9 @@
58
58
  "color: #00a596",
59
59
  "color: #ff7d73",
60
60
  ];
61
- let num = Math.floor(Math.random() * color.length);
61
+ let id = Math.floor(Math.random() * color.length);
62
62
  %>
63
- <a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
63
+ <a href="<%- url_for(data.path) %>" style="<%- color[id] %>"><%= data.name %></a>
64
64
  </span>
65
65
  <% }); %>
66
66
  </span>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-particlex",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "A concise Hexo theme, based on Particle.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,7 +47,7 @@
47
47
  top: 80px;
48
48
  }
49
49
  #crypto {
50
- margin: 50px auto 0;
50
+ margin: 50px 0;
51
51
  }
52
52
  #crypto.fail {
53
53
  border-color: #ea4a5a;
@@ -452,7 +452,7 @@
452
452
  max-width: 95%;
453
453
  }
454
454
  #search-bar {
455
- margin: 0 auto 50px;
455
+ margin-bottom: 50px;
456
456
  z-index: 10001;
457
457
  }
458
458
  #timeline-wrap {
@@ -504,24 +504,24 @@ body::-webkit-scrollbar-track {
504
504
  margin: 15px auto;
505
505
  max-width: 75%;
506
506
  }
507
- .copycode {
507
+ .code-copy {
508
508
  color: #5c6b72;
509
509
  position: absolute;
510
510
  right: 0;
511
511
  top: 0;
512
512
  }
513
- .copycode i {
513
+ .code-copy i {
514
514
  padding: 15px;
515
515
  position: absolute;
516
516
  right: 0;
517
517
  top: 0;
518
518
  transition: transform 0.25s;
519
519
  }
520
- .copycode.copied i {
520
+ .code-copy.copied i {
521
521
  transform: scale(1.25);
522
522
  }
523
- .copycode.copied i:first-child,
524
- .copycode:not(.copied) i:last-child {
523
+ .code-copy.copied i:first-child,
524
+ .code-copy:not(.copied) i:last-child {
525
525
  opacity: 0;
526
526
  }
527
527
  .fade-enter-active,
@@ -658,7 +658,7 @@ a {
658
658
  text-decoration: none;
659
659
  }
660
660
  a:hover,
661
- .content .copycode:hover {
661
+ .content .code-copy:hover {
662
662
  opacity: 0.8;
663
663
  }
664
664
  b,
@@ -687,7 +687,6 @@ audio,
687
687
  iframe,
688
688
  #home-head,
689
689
  #menu,
690
- #loading,
691
690
  .katex,
692
691
  .go-post,
693
692
  .page-current,
@@ -695,7 +694,7 @@ iframe,
695
694
  .friend-link a,
696
695
  .icon-link a,
697
696
  .language,
698
- .copycode {
697
+ .code-copy {
699
698
  user-select: none;
700
699
  }
701
700
  code {
@@ -1,9 +1,6 @@
1
- const cryptoMixin = {
1
+ mixins.crypto = {
2
2
  data() {
3
- return {
4
- crypto: "",
5
- check: false,
6
- };
3
+ return { crypto: "", check: false };
7
4
  },
8
5
  methods: {
9
6
  SHA(word) {
@@ -1,20 +1,20 @@
1
- const highlightMixin = {
1
+ mixins.highlight = {
2
2
  data() {
3
- return { copying: false };
3
+ return { copying: false, renderers: [this.highlight] };
4
4
  },
5
- mounted() {
5
+ created() {
6
6
  hljs.configure({ ignoreUnescapedHTML: true });
7
7
  },
8
8
  methods: {
9
9
  highlight() {
10
10
  let that = this;
11
- let codes = document.getElementsByTagName("pre");
11
+ let codes = document.querySelectorAll("pre");
12
12
  for (let i of codes) {
13
13
  let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
14
14
  let code = i.innerText;
15
- i.innerHTML = `<div class="code-content">${code}</div><div class="language">${lang}</div><div class="copycode"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
16
- let copycode = i.getElementsByClassName("copycode")[0];
17
- copycode.addEventListener("click", async function () {
15
+ i.innerHTML = `<div class="code-content">${code}</div><div class="language">${lang}</div><div class="code-copy"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
16
+ let copy = i.querySelector(".code-copy");
17
+ copy.addEventListener("click", async function () {
18
18
  if (that.copying) return;
19
19
  that.copying = true;
20
20
  this.classList.add("copied");
@@ -23,10 +23,9 @@ const highlightMixin = {
23
23
  this.classList.remove("copied");
24
24
  that.copying = false;
25
25
  });
26
- let content = i.getElementsByClassName("code-content")[0];
26
+ let content = i.querySelector(".code-content");
27
27
  hljs.highlightElement(content);
28
28
  }
29
29
  },
30
30
  },
31
31
  };
32
- mixins.push(highlightMixin);
@@ -0,0 +1,15 @@
1
+ mixins.home = {
2
+ mounted() {
3
+ let menu = this.$refs.menu,
4
+ background = this.$refs.homeBackground;
5
+ menu.classList.add("menu-color");
6
+ let image = background.dataset.image.split(",");
7
+ let id = Math.floor(Math.random * image.length);
8
+ background.style.backgroundImage = `url('${image[id]}')`;
9
+ },
10
+ methods: {
11
+ homeClick() {
12
+ window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
13
+ },
14
+ },
15
+ };
@@ -1,4 +1,7 @@
1
- const mathMixin = {
1
+ mixins.math = {
2
+ data() {
3
+ return { renderers: [this.math] };
4
+ },
2
5
  methods: {
3
6
  math() {
4
7
  renderMathInElement(document.body, {
@@ -12,4 +15,3 @@ const mathMixin = {
12
15
  },
13
16
  },
14
17
  };
15
- mixins.push(mathMixin);
@@ -1,13 +1,13 @@
1
- const previewMixin = {
1
+ mixins.preview = {
2
2
  data() {
3
- return { previewShow: false };
3
+ return { previewShow: false, renderers: [this.preview] };
4
4
  },
5
5
  methods: {
6
6
  preview() {
7
7
  let that = this;
8
8
  let preview = this.$refs.preview,
9
- content = this.$refs.previewContent,
10
- images = document.getElementsByTagName("img");
9
+ content = this.$refs.previewContent;
10
+ let images = document.querySelectorAll("img");
11
11
  for (let i of images)
12
12
  i.addEventListener("click", function () {
13
13
  content.alt = this.alt;
@@ -23,4 +23,3 @@ const previewMixin = {
23
23
  },
24
24
  },
25
25
  };
26
- mixins.push(previewMixin);
@@ -1,8 +1,6 @@
1
- const searchMixin = {
1
+ mixins.search = {
2
2
  data() {
3
- return {
4
- rawSearch: "",
5
- };
3
+ return { rawSearch: "" };
6
4
  },
7
5
  watch: {
8
6
  search(value) {
@@ -25,4 +23,3 @@ const searchMixin = {
25
23
  },
26
24
  },
27
25
  };
28
- mixins.push(searchMixin);
package/source/js/main.js CHANGED
@@ -1,11 +1,7 @@
1
1
  const app = Vue.createApp({
2
- mixins,
2
+ mixins: Object.values(mixins),
3
3
  data() {
4
- return {
5
- loading: true,
6
- showMenu: false,
7
- barLocal: 0,
8
- };
4
+ return { loading: true, showMenu: false, barLocal: 0 };
9
5
  },
10
6
  created() {
11
7
  window.addEventListener("load", () => {
@@ -13,17 +9,17 @@ const app = Vue.createApp({
13
9
  });
14
10
  },
15
11
  mounted() {
16
- if (this.$refs.head) this.$refs.menu.classList.add("menu-color");
17
12
  window.addEventListener("scroll", this.handleScroll, true);
18
13
  this.render();
19
14
  },
20
15
  methods: {
21
- homeClick() {
22
- window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
16
+ render() {
17
+ if (typeof this.renderers === "undefined") return;
18
+ for (let i of this.renderers) i();
23
19
  },
24
20
  handleScroll() {
25
21
  let menu = this.$refs.menu,
26
- wrap = this.$refs.wrap;
22
+ wrap = this.$refs.homePostsWrap;
27
23
  let newlocal = document.documentElement.scrollTop;
28
24
  if (this.barLocal < newlocal) {
29
25
  this.showMenu = false;
@@ -37,11 +33,6 @@ const app = Vue.createApp({
37
33
  }
38
34
  this.barLocal = newlocal;
39
35
  },
40
- render() {
41
- if (typeof this.highlight !== "undefined") this.highlight();
42
- if (typeof this.math !== "undefined") this.math();
43
- this.preview();
44
- },
45
36
  },
46
37
  });
47
38
  app.mount("#layout");