hexo-theme-particlex 2.4.11 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>
@@ -51,10 +51,16 @@
51
51
  <% post.tags.data.forEach(data => { %>
52
52
  <span class="tag">
53
53
  <%
54
- const color = ["color: #ffa2c4", "color: #00bcd4", "color: #03a9f4", "color: #00a596", "color: #ff7d73"];
55
- let num = Math.floor(Math.random() * color.length);
54
+ const color = [
55
+ "color: #ffa2c4",
56
+ "color: #00bcd4",
57
+ "color: #03a9f4",
58
+ "color: #00a596",
59
+ "color: #ff7d73",
60
+ ];
61
+ let id = Math.floor(Math.random() * color.length);
56
62
  %>
57
- <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>
58
64
  </span>
59
65
  <% }); %>
60
66
  </span>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-particlex",
3
- "version": "2.4.11",
3
+ "version": "2.5.1",
4
4
  "description": "A concise Hexo theme, based on Particle.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,53 +1,3 @@
1
- @keyframes into {
2
- from {
3
- opacity: 0;
4
- transform: scale(1.1);
5
- }
6
- to {
7
- opacity: 1;
8
- transform: scale(1);
9
- }
10
- }
11
- @keyframes loading {
12
- from {
13
- opacity: 0;
14
- }
15
- to {
16
- opacity: 1;
17
- }
18
- }
19
- @keyframes loop1 {
20
- from {
21
- transform: rotate(30deg);
22
- }
23
- to {
24
- transform: rotate(390deg);
25
- }
26
- }
27
- @keyframes loop2 {
28
- from {
29
- transform: rotate(60deg);
30
- }
31
- to {
32
- transform: rotate(420deg);
33
- }
34
- }
35
- @keyframes loop3 {
36
- from {
37
- transform: rotate(90deg);
38
- }
39
- to {
40
- transform: rotate(450deg);
41
- }
42
- }
43
- @keyframes loop4 {
44
- from {
45
- transform: rotate(120deg);
46
- }
47
- to {
48
- transform: rotate(480deg);
49
- }
50
- }
51
1
  #archives {
52
2
  margin: auto;
53
3
  margin-top: 100px;
@@ -97,7 +47,7 @@
97
47
  top: 80px;
98
48
  }
99
49
  #crypto {
100
- margin: 50px auto 0;
50
+ margin: 50px 0;
101
51
  }
102
52
  #crypto.fail {
103
53
  border-color: #ea4a5a;
@@ -117,19 +67,19 @@
117
67
  text-align: center;
118
68
  width: 100%;
119
69
  }
120
- #footer .footer-icon {
70
+ #footer #footer-icon {
121
71
  color: #66afef;
122
72
  display: inline-block;
123
73
  font-size: 18px;
124
74
  margin: 0 10px;
125
75
  }
126
- #footer .footer-wrap {
76
+ #footer #footer-wrap {
127
77
  border-top: 1px solid #aaa;
128
78
  color: #5c6b72;
129
79
  margin: auto;
130
80
  width: 900px;
131
81
  }
132
- #footer .footer-wrap div {
82
+ #footer #footer-wrap div {
133
83
  margin: 15px;
134
84
  }
135
85
  #home-card {
@@ -376,9 +326,42 @@
376
326
  #home-posts-wrap,
377
327
  #archives,
378
328
  .article,
379
- #footer .footer-wrap {
329
+ #footer #footer-wrap {
380
330
  box-sizing: border-box;
381
331
  }
332
+ #loading {
333
+ align-items: center;
334
+ background: #fff;
335
+ display: flex;
336
+ flex-direction: column;
337
+ height: 100vh;
338
+ justify-content: center;
339
+ left: 0;
340
+ position: fixed;
341
+ top: 0;
342
+ width: 100vw;
343
+ z-index: 2147483647;
344
+ }
345
+ #loading h2,
346
+ #loading p,
347
+ #loading img {
348
+ margin: 10px;
349
+ }
350
+ #loading img {
351
+ border-radius: 0;
352
+ height: 50px;
353
+ }
354
+ #loading-circle {
355
+ align-items: center;
356
+ border: 10px solid #a3ddfb;
357
+ border-radius: 50%;
358
+ display: flex;
359
+ flex-direction: column;
360
+ height: 50vmin;
361
+ justify-content: center;
362
+ padding: 50px;
363
+ width: 50vmin;
364
+ }
382
365
  #main {
383
366
  margin-right: calc(100% - 100vw);
384
367
  overflow: auto;
@@ -391,8 +374,8 @@
391
374
  position: fixed;
392
375
  top: 0;
393
376
  transition: background 0.25s ease-out, top 0.25s ease-out;
394
- width: 100%;
395
- z-index: 10005;
377
+ width: 100vw;
378
+ z-index: 10004;
396
379
  }
397
380
  #menu .desktop-menu {
398
381
  height: 50px;
@@ -408,11 +391,11 @@
408
391
  display: inline-block;
409
392
  margin-left: 30px;
410
393
  }
411
- #menu .phone-menu {
394
+ #menu #mobile-menu {
412
395
  min-height: 50px;
413
396
  text-align: center;
414
397
  }
415
- #menu .phone-menu .curtain {
398
+ #menu #mobile-menu .curtain {
416
399
  height: 100%;
417
400
  left: 0;
418
401
  position: fixed;
@@ -420,26 +403,26 @@
420
403
  width: 100%;
421
404
  z-index: -1;
422
405
  }
423
- #menu .phone-menu .items {
406
+ #menu #mobile-menu .items {
424
407
  padding: 10px 0 20px;
425
- z-index: 10003;
408
+ z-index: 10002;
426
409
  }
427
- #menu .phone-menu .items .item {
410
+ #menu #mobile-menu .items .item {
428
411
  display: flex;
429
412
  justify-content: center;
430
413
  margin: auto;
431
414
  min-width: 200px;
432
415
  width: 80%;
433
416
  }
434
- #menu .phone-menu .items a {
417
+ #menu #mobile-menu .items a {
435
418
  color: #555;
436
419
  }
437
- #menu .phone-menu .title {
420
+ #menu #mobile-menu .title {
438
421
  color: #555;
439
422
  cursor: pointer;
440
- z-index: 10004;
423
+ z-index: 10003;
441
424
  }
442
- #menu.hidden-menu {
425
+ #menu.hidden {
443
426
  top: -70px !important;
444
427
  }
445
428
  #menu.menu-color {
@@ -450,38 +433,32 @@
450
433
  #menu.menu-color a {
451
434
  color: #fff !important;
452
435
  }
453
- #search-bar {
454
- margin: 0 auto 50px;
455
- }
456
- #search-mask {
457
- background: #f6f8fa;
458
- height: 150px;
459
- margin: auto;
460
- margin-bottom: -25px;
461
- margin-top: -125px;
462
- width: 100%;
463
- }
464
- #showimg {
436
+ #preview {
465
437
  align-items: center;
466
438
  background-color: #fffc;
467
439
  display: flex;
468
440
  height: 100vh;
469
441
  justify-content: center;
470
442
  left: 0;
471
- opacity: 0;
472
443
  position: fixed;
473
444
  top: 0;
474
- transition: opacity 0.25s, visibility 0.25s;
475
- visibility: hidden;
476
445
  width: 100vw;
477
- z-index: 10006;
446
+ z-index: 10005;
478
447
  }
479
- #showimg-content {
448
+ #preview-content {
480
449
  box-shadow: 0 0 50px 10px #d9d9d980;
481
450
  margin: auto;
482
451
  max-height: 95%;
483
452
  max-width: 95%;
484
453
  }
454
+ #search-bar {
455
+ margin-bottom: 50px;
456
+ z-index: 10001;
457
+ }
458
+ #timeline-wrap {
459
+ display: flex;
460
+ flex-direction: column-reverse;
461
+ }
485
462
  * {
486
463
  margin: 0;
487
464
  padding: 0;
@@ -527,24 +504,32 @@ body::-webkit-scrollbar-track {
527
504
  margin: 15px auto;
528
505
  max-width: 75%;
529
506
  }
530
- .copycode {
507
+ .code-copy {
531
508
  color: #5c6b72;
532
509
  position: absolute;
533
510
  right: 0;
534
511
  top: 0;
535
512
  }
536
- .copycode i {
513
+ .code-copy i {
537
514
  padding: 15px;
538
515
  position: absolute;
539
516
  right: 0;
540
517
  top: 0;
541
518
  transition: transform 0.25s;
542
519
  }
543
- .copycode.copied i {
520
+ .code-copy.copied i {
544
521
  transform: scale(1.25);
545
522
  }
546
- .copycode.copied i:first-child,
547
- .copycode:not(.copied) i:last-child {
523
+ .code-copy.copied i:first-child,
524
+ .code-copy:not(.copied) i:last-child {
525
+ opacity: 0;
526
+ }
527
+ .fade-enter-active,
528
+ .fade-leave-active {
529
+ transition: opacity 0.3s;
530
+ }
531
+ .fade-enter-from,
532
+ .fade-leave-to {
548
533
  opacity: 0;
549
534
  }
550
535
  .icon {
@@ -575,7 +560,15 @@ body::-webkit-scrollbar-track {
575
560
  }
576
561
  .into-enter-active,
577
562
  .into-leave-active {
578
- animation: into 0.6s;
563
+ transition: opacity 0.5s, transform 0.5s;
564
+ }
565
+ .into-enter-from,
566
+ .into-leave-to {
567
+ opacity: 0;
568
+ transform: scale(1.1);
569
+ }
570
+ .katex {
571
+ overflow: auto;
579
572
  }
580
573
  .language {
581
574
  background: linear-gradient(to right, #ed6ea0 0%, #ec8c69 100%);
@@ -589,14 +582,18 @@ body::-webkit-scrollbar-track {
589
582
  position: absolute;
590
583
  top: 0;
591
584
  }
592
- .katex {
593
- overflow: auto;
594
- }
595
585
  .page-num,
596
586
  .icon-link a,
597
587
  .friend-link a {
598
588
  transition: background 0.25s, color 0.25s;
599
589
  }
590
+ .page-num:hover,
591
+ .icon-link a:hover,
592
+ .friend-link a:hover,
593
+ .categories-tags a:hover,
594
+ .go-post:hover {
595
+ opacity: 1;
596
+ }
600
597
  .slide-enter-active,
601
598
  .slide-leave-active {
602
599
  transition: margin-top 0.3s, opacity 0.3s;
@@ -608,7 +605,7 @@ body::-webkit-scrollbar-track {
608
605
  }
609
606
  .timeline {
610
607
  margin-bottom: 30px;
611
- transition: margin-top 0.5s, opacity 0.25s;
608
+ transition: margin-top 0.5s, opacity 0.3s, visibility 0.3s;
612
609
  }
613
610
  .timeline-content {
614
611
  background: #fff;
@@ -661,7 +658,7 @@ a {
661
658
  text-decoration: none;
662
659
  }
663
660
  a:hover,
664
- .content .copycode:hover {
661
+ .content .code-copy:hover {
665
662
  opacity: 0.8;
666
663
  }
667
664
  b,
@@ -697,7 +694,7 @@ iframe,
697
694
  .friend-link a,
698
695
  .icon-link a,
699
696
  .language,
700
- .copycode {
697
+ .code-copy {
701
698
  user-select: none;
702
699
  }
703
700
  code {
@@ -720,13 +717,6 @@ h6 {
720
717
  font-weight: bold;
721
718
  margin: 15px 0;
722
719
  }
723
- .page-num:hover,
724
- .icon-link a:hover,
725
- .friend-link a:hover,
726
- .categories-tags a:hover,
727
- .go-post:hover {
728
- opacity: 1;
729
- }
730
720
  h2 {
731
721
  font-size: 27px;
732
722
  }
@@ -801,6 +791,38 @@ ul li,
801
791
  ol li {
802
792
  margin: 8px 0;
803
793
  }
794
+ @keyframes loop1 {
795
+ from {
796
+ transform: rotate(30deg);
797
+ }
798
+ to {
799
+ transform: rotate(390deg);
800
+ }
801
+ }
802
+ @keyframes loop2 {
803
+ from {
804
+ transform: rotate(60deg);
805
+ }
806
+ to {
807
+ transform: rotate(420deg);
808
+ }
809
+ }
810
+ @keyframes loop3 {
811
+ from {
812
+ transform: rotate(90deg);
813
+ }
814
+ to {
815
+ transform: rotate(450deg);
816
+ }
817
+ }
818
+ @keyframes loop4 {
819
+ from {
820
+ transform: rotate(120deg);
821
+ }
822
+ to {
823
+ transform: rotate(480deg);
824
+ }
825
+ }
804
826
  @media (min-width: 900px) {
805
827
  #home-card {
806
828
  margin-right: auto;
@@ -851,12 +873,12 @@ ol li {
851
873
  #menu .desktop-menu {
852
874
  display: block;
853
875
  }
854
- #menu .phone-menu {
876
+ #menu #mobile-menu {
855
877
  display: none;
856
878
  }
857
879
  .article,
858
880
  #archives,
859
- #footer .footer-wrap {
881
+ #footer #footer-wrap {
860
882
  width: 900px;
861
883
  }
862
884
  .home-posts-wrap-no-card #home-posts {
@@ -932,14 +954,14 @@ ol li {
932
954
  #home-posts-wrap,
933
955
  .article,
934
956
  #archives,
935
- #footer .footer-wrap {
957
+ #footer #footer-wrap {
936
958
  width: 100%;
937
959
  }
938
960
  #menu .desktop-menu,
939
961
  #home-card {
940
962
  display: none;
941
963
  }
942
- #menu .phone-menu {
964
+ #menu #mobile-menu {
943
965
  display: block;
944
966
  }
945
967
  ul,
@@ -0,0 +1,38 @@
1
+ mixins.crypto = {
2
+ data() {
3
+ return { crypto: "", check: false };
4
+ },
5
+ methods: {
6
+ SHA(word) {
7
+ return CryptoJS.SHA256(word).toString();
8
+ },
9
+ decrypt(word, secret, shasum) {
10
+ try {
11
+ let res = CryptoJS.AES.decrypt(word, secret).toString(CryptoJS.enc.Utf8);
12
+ return { check: this.SHA(res) === shasum, decrypted: res };
13
+ } catch {
14
+ return { check: false };
15
+ }
16
+ },
17
+ },
18
+ watch: {
19
+ crypto(value) {
20
+ let input = this.$refs.crypto,
21
+ content = this.$refs.content;
22
+ let { decrypted, check } = this.decrypt(
23
+ input.dataset.encrypted,
24
+ value,
25
+ input.dataset.shasum
26
+ );
27
+ this.check = check;
28
+ if (check) {
29
+ input.classList.remove("fail");
30
+ input.classList.add("success");
31
+ input.disabled = true;
32
+ content.innerHTML = decrypted;
33
+ this.render();
34
+ } else input.classList.add("fail");
35
+ },
36
+ },
37
+ };
38
+ mixins.push(cryptoMixin);
@@ -0,0 +1,31 @@
1
+ mixins.highlight = {
2
+ data() {
3
+ return { copying: false, renderers: [this.highlight] };
4
+ },
5
+ created() {
6
+ hljs.configure({ ignoreUnescapedHTML: true });
7
+ },
8
+ methods: {
9
+ highlight() {
10
+ let that = this;
11
+ let codes = document.querySelectorAll("pre");
12
+ for (let i of codes) {
13
+ let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
14
+ let code = i.innerText;
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
+ if (that.copying) return;
19
+ that.copying = true;
20
+ this.classList.add("copied");
21
+ await navigator.clipboard.writeText(code);
22
+ await new Promise(resolve => setTimeout(resolve, 1000));
23
+ this.classList.remove("copied");
24
+ that.copying = false;
25
+ });
26
+ let content = i.querySelector(".code-content");
27
+ hljs.highlightElement(content);
28
+ }
29
+ },
30
+ },
31
+ };
@@ -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
+ };
@@ -0,0 +1,17 @@
1
+ mixins.math = {
2
+ data() {
3
+ return { renderers: [this.math] };
4
+ },
5
+ methods: {
6
+ math() {
7
+ renderMathInElement(document.body, {
8
+ delimiters: [
9
+ { left: "$$", right: "$$", display: true },
10
+ { left: "$", right: "$", display: false },
11
+ { left: "\\(", right: "\\)", display: false },
12
+ { left: "\\[", right: "\\]", display: true },
13
+ ],
14
+ });
15
+ },
16
+ },
17
+ };
@@ -0,0 +1,25 @@
1
+ mixins.preview = {
2
+ data() {
3
+ return { previewShow: false, renderers: [this.preview] };
4
+ },
5
+ methods: {
6
+ preview() {
7
+ let that = this;
8
+ let preview = this.$refs.preview,
9
+ content = this.$refs.previewContent;
10
+ let images = document.querySelectorAll("img");
11
+ for (let i of images)
12
+ i.addEventListener("click", function () {
13
+ content.alt = this.alt;
14
+ content.src = this.src;
15
+ that.previewShow = true;
16
+ });
17
+ preview.addEventListener("click", () => {
18
+ this.previewShow = false;
19
+ });
20
+ window.addEventListener("resize", () => {
21
+ this.previewShow = false;
22
+ });
23
+ },
24
+ },
25
+ };
@@ -0,0 +1,25 @@
1
+ mixins.search = {
2
+ data() {
3
+ return { rawSearch: "" };
4
+ },
5
+ watch: {
6
+ search(value) {
7
+ let timeline = this.$refs.timeline.childNodes;
8
+ for (let i of timeline)
9
+ if (!value || i.dataset.title.includes(value)) {
10
+ i.style.opacity = 1;
11
+ i.style.visibility = "visible";
12
+ i.style.marginTop = 0;
13
+ } else {
14
+ i.style.opacity = 0;
15
+ i.style.visibility = "hidden";
16
+ i.style.marginTop = -i.offsetHeight - 30 + "px";
17
+ }
18
+ },
19
+ },
20
+ computed: {
21
+ search() {
22
+ return this.rawSearch.toLowerCase().replace(/s+/gm, "");
23
+ },
24
+ },
25
+ };
@@ -0,0 +1,38 @@
1
+ const app = Vue.createApp({
2
+ mixins: Object.values(mixins),
3
+ data() {
4
+ return { loading: true, showMenu: false, barLocal: 0 };
5
+ },
6
+ created() {
7
+ window.addEventListener("load", () => {
8
+ this.loading = false;
9
+ });
10
+ },
11
+ mounted() {
12
+ window.addEventListener("scroll", this.handleScroll, true);
13
+ this.render();
14
+ },
15
+ methods: {
16
+ render() {
17
+ if (typeof this.renderers === "undefined") return;
18
+ for (let i of this.renderers) i();
19
+ },
20
+ handleScroll() {
21
+ let menu = this.$refs.menu,
22
+ wrap = this.$refs.homePostsWrap;
23
+ let newlocal = document.documentElement.scrollTop;
24
+ if (this.barLocal < newlocal) {
25
+ this.showMenu = false;
26
+ menu.classList.add("hidden");
27
+ } else menu.classList.remove("hidden");
28
+ if (wrap) {
29
+ if (newlocal <= window.innerHeight - 100) menu.classList.add("menu-color");
30
+ else menu.classList.remove("menu-color");
31
+ if (newlocal <= 400) wrap.style.marginTop = -newlocal / 5 + "px";
32
+ else wrap.style.marginTop = "-80px";
33
+ }
34
+ this.barLocal = newlocal;
35
+ },
36
+ },
37
+ });
38
+ app.mount("#layout");
@@ -1,9 +0,0 @@
1
- <div id="loading" style="height: 100vh; width: 100vw; left: 0; top: 0; position: fixed; display: flex; z-index: 2147483647; background: #fff; transition: opacity 0.3s ease-out; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; pointer-events: none">
2
- <div style="width: 50vmin; height: 50vmin; margin: auto; padding: 50px; border-radius: 50%; display: flex; border: solid 10px #a3ddfb">
3
- <div style="margin: auto; text-align: center">
4
- <h2>LOADING</h2>
5
- <p>加载过慢请开启缓存,浏览器默认开启</p>
6
- <img src="<%- url_for("/images/loading.gif") %>" style="height: 50px; border-radius: 0">
7
- </div>
8
- </div>
9
- </div>