hexo-theme-particlex 2.4.11 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
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>