Compare commits

..

9 Commits

Author SHA1 Message Date
雨奇晴好
d25776ea38
Fix 1px scroll offset on page navigation when Pjax is enabled (#995) 2026-09-08 10:35:06 +08:00
Mimi
3e4d43597d Update _vendors.yml 2026-09-02 09:26:54 +08:00
Mimi
6037f68b7a New animation next-bounce 2026-08-25 01:36:07 +08:00
Mimi
6468f139cb Update default icon 2026-08-20 22:10:51 +08:00
Mimi
d62fdfa759 Simplify site-nav-toggle element 2026-08-20 14:10:46 +08:00
Mimi
96d34a0bb9 Update site-nav-toggle style 2026-08-20 11:12:58 +08:00
Mimi
6560fa6dd6 Fix sidebar-dimmer animation 2026-08-14 17:39:50 +08:00
Mimi
66e3095a31 Fix search-popup animation using template 2026-08-14 16:45:16 +08:00
Mimi
120d41d0fa Fix preload condition for theme preconnect option 2026-08-14 01:20:31 +08:00
17 changed files with 81 additions and 63 deletions

View File

@ -104,7 +104,7 @@ menu:
#home: / || fa fa-home #home: / || fa fa-home
#about: /about/ || fa fa-user #about: /about/ || fa fa-user
#tags: /tags/ || fa fa-tags #tags: /tags/ || fa fa-tags
#categories: /categories/ || fa fa-th #categories: /categories/ || fa fa-layer-group
#archives: /archives/ || fa fa-archive #archives: /archives/ || fa fa-archive
#schedule: /schedule/ || fa fa-calendar #schedule: /schedule/ || fa fa-calendar
#sitemap: /sitemap.xml || fa fa-sitemap #sitemap: /sitemap.xml || fa fa-sitemap

View File

@ -3,10 +3,10 @@
fontawesome: fontawesome:
name: '@fortawesome/fontawesome-free' name: '@fortawesome/fontawesome-free'
version: 7.0.0 version: 7.3.1
file: css/all.min.css file: css/all.min.css
alias: font-awesome alias: font-awesome
integrity: sha256-VHqXKFhhMxcpubYf9xiWdCiojEbY9NexQ4jh8AxbvcM= integrity: sha256-4Lad8m4ZWW1Lgb9+sMVLYEfnIh7BjV1NQMEe79Pviks=
prism: prism:
name: prismjs name: prismjs
version: 1.30.0 version: 1.30.0
@ -32,16 +32,16 @@ mathjax:
integrity: sha256-ihPtDDm7pTmSF9ViEsItlvsrBTsNkz0MOXMchzOwCQw= integrity: sha256-ihPtDDm7pTmSF9ViEsItlvsrBTsNkz0MOXMchzOwCQw=
katex: katex:
name: katex name: katex
version: 0.16.9 version: 0.18.4
file: dist/katex.min.css file: dist/katex.min.css
alias: KaTeX alias: KaTeX
integrity: sha256-UF1fgpAiu3tPJN/uCqEUHNe7pnr+QR0SQDNfgglgtcM= integrity: sha256-GAwtd9Q019pR1mJcUKlk1P1v29ubyHlqCgFsMMSZMfs=
copy_tex_js: copy_tex_js:
name: katex name: katex
version: 0.16.9 version: 0.18.4
file: dist/contrib/copy-tex.min.js file: dist/contrib/copy-tex.min.js
alias: KaTeX alias: KaTeX
integrity: sha256-Us54+rSGDSTvIhKKUs4kygE2ipA0RXpWWh0/zLqw3bs= integrity: sha256-xXHEm1IMuOkEAoczgoayF4Pjm0dmYLi1bZ4cA37q6v8=
pjax: pjax:
name: '@next-theme/pjax' name: '@next-theme/pjax'
version: 0.6.0 version: 0.6.0
@ -78,9 +78,9 @@ pangu:
integrity: sha256-kRsxecBnwG6mULFPe2E6UKnNm8XfDOuDwCOprjLZuX8= integrity: sha256-kRsxecBnwG6mULFPe2E6UKnNm8XfDOuDwCOprjLZuX8=
quicklink: quicklink:
name: quicklink name: quicklink
version: 3.0.1 version: 3.0.2
file: dist/quicklink.umd.js file: dist/quicklink.umd.js
integrity: sha256-44BednzIpUeQJcY8qtLyarFu0UCCTbgmWOvaoehiFQQ= integrity: sha256-Qo2BTvlsBVXIr5fEHp8xlBpUmkbDINr5cQZeSfMTES8=
disqusjs_js: disqusjs_js:
name: disqusjs name: disqusjs
version: 3.2.1 version: 3.2.1
@ -103,9 +103,9 @@ gitalk_css:
integrity: sha256-AJnUHL7dBv6PGaeyPQJcgQPDjt/Hn/PvYZde1iqfp8U= integrity: sha256-AJnUHL7dBv6PGaeyPQJcgQPDjt/Hn/PvYZde1iqfp8U=
algolia_search: algolia_search:
name: algoliasearch name: algoliasearch
version: 5.36.0 version: 5.57.0
file: dist/lite/builds/browser.umd.js file: dist/lite/builds/browser.umd.js
integrity: sha256-o49zoHLDPBm9WLg6AiliAVi3axCRTqe3ltTxLvhzAVg= integrity: sha256-NJrnXIMFVRGMM2IieD83YpTvsPPIFKKyj4K/MNyTRQU=
local_search: local_search:
name: hexo-generator-searchdb name: hexo-generator-searchdb
version: 1.5.0 version: 1.5.0

View File

@ -10,7 +10,7 @@
{{- meta_generator() }} {{- meta_generator() }}
{%- endif %} {%- endif %}
{%- if config.preconnect %} {%- if theme.preconnect %}
<link rel="preload" href="{{ url_for(theme.css) }}/main.css" as="style"> <link rel="preload" href="{{ url_for(theme.css) }}/main.css" as="style">
{%- endif %} {%- endif %}
{{ next_pre() }} {{ next_pre() }}

View File

@ -1,12 +1,8 @@
<div class="site-brand-container"> <div class="site-brand-container">
<div class="site-nav-toggle"> <div class="site-nav-search popup-trigger" aria-label="{{ __('menu.search') }}" role="button">
<div class="toggle" aria-label="{{ __('accessibility.nav_toggle') }}" role="button"> {%- if theme.algolia_search.enable or theme.local_search.enable %}
{%- if theme.menu %} <i class="fa fa-search fa-fw fa-lg"></i>
<span class="toggle-line"></span> {%- endif %}
<span class="toggle-line"></span>
<span class="toggle-line"></span>
{%- endif %}
</div>
</div> </div>
<div class="site-meta"> <div class="site-meta">
@ -27,11 +23,9 @@
{%- endif %} {%- endif %}
</div> </div>
<div class="site-nav-right"> <div class="site-nav-toggle" aria-label="{{ __('accessibility.nav_toggle') }}" role="button">
<div class="toggle popup-trigger" aria-label="{{ __('menu.search') }}" role="button"> {%- if theme.menu %}
{%- if theme.algolia_search.enable or theme.local_search.enable %} <i class="fa fa-ellipsis fa-fw fa-lg"></i>
<i class="fa fa-search fa-fw fa-lg"></i> {%- endif %}
{%- endif %}
</div>
</div> </div>
</div> </div>

View File

@ -88,7 +88,7 @@
{%- if config.symbols_count_time.symbols %} {%- if config.symbols_count_time.symbols %}
<span class="post-meta-item" title="{{ __('symbols_count_time.count') }}"> <span class="post-meta-item" title="{{ __('symbols_count_time.count') }}">
<span class="post-meta-item-icon"> <span class="post-meta-item-icon">
<i class="far fa-file-word"></i> <i class="far fa-file-lines"></i>
</span> </span>
<span class="post-meta-item-text">{{ __('symbols_count_time.count') + __('symbol.colon') }}</span> <span class="post-meta-item-text">{{ __('symbols_count_time.count') + __('symbol.colon') }}</span>
<span>{{ symbolsCount(post) }}</span> <span>{{ symbolsCount(post) }}</span>

View File

@ -1,5 +1,7 @@
{%- if theme.algolia_search.enable or theme.local_search.enable %} {%- if theme.algolia_search.enable or theme.local_search.enable %}
<div class="search-pop-overlay"> {# Keep the popup out of the render tree to prevent Safari from animating it before main.css is applied.
When main.css loads slowly, the unstyled search popup briefly appears and shrinks away. #}
<template id="search-popup-template"><div class="search-pop-overlay">
<div class="popup search-popup"> <div class="popup search-popup">
<div class="search-header"> <div class="search-header">
<span class="search-icon"> <span class="search-icon">
@ -20,5 +22,5 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div></template>
{%- endif %} {%- endif %}

View File

@ -6,7 +6,6 @@
<span class="toggle-line"></span> <span class="toggle-line"></span>
<span class="toggle-line"></span> <span class="toggle-line"></span>
</div> </div>
<div class="sidebar-dimmer"></div>
{%- endif %} {%- endif %}
{%- if theme.back2top.enable and not theme.back2top.sidebar %} {%- if theme.back2top.enable and not theme.back2top.sidebar %}

View File

@ -28,11 +28,21 @@
} }
if (hexo-config('reward_settings.animation')) { if (hexo-config('reward_settings.animation')) {
span {
transform-origin: center bottom;
}
&:hover span { &:hover span {
animation: next-roll .1s infinite linear; animation: next-bounce 1.4s infinite ease-in-out;
// The animation may affect :hover of img in dark mode // The animation may affect :hover of img in dark mode
pointer-events: none; pointer-events: none;
} }
@media (prefers-reduced-motion: reduce) {
&:hover span {
animation: none;
}
}
} }
} }
@ -44,12 +54,28 @@
} }
} }
@keyframes next-roll { @keyframes next-bounce {
from { 0%, 100% {
transform: rotateZ(30deg); transform: translateY(0) scale(1);
} }
to { 12% {
transform: rotateZ(-30deg); transform: translateY(0) scale(1.04, .96);
}
36% {
transform: translateY(-7px) scale(.98, 1.02);
}
58% {
transform: translateY(0) scale(1.03, .97);
}
72% {
transform: translateY(-2px) scale(1);
}
84% {
transform: translateY(0) scale(1);
} }
} }

View File

@ -12,11 +12,10 @@
.site-brand-container { .site-brand-container {
display: flex; display: flex;
flex-shrink: 0; flex-shrink: 0;
padding: 0 10px;
} }
.use-motion { .use-motion {
.column, .site-brand-container .toggle { .column {
opacity: 0; opacity: 0;
} }
} }

View File

@ -1,20 +1,19 @@
.site-nav-toggle, .site-nav-right { .site-nav-toggle, .site-nav-search {
color: var(--text-color);
display: none; display: none;
padding: 0 10px;
.fa {
transition: transform .5s;
}
+mobile() { +mobile() {
flex-column(); flex-column();
} }
}
.toggle { .site-nav-on .site-nav-toggle .fa {
color: var(--text-color); transform: rotate(-90deg);
padding: 10px;
width: 22px;
.toggle-line {
background: var(--text-color);
border-radius: 1px;
}
}
} }
.site-nav { .site-nav {

View File

@ -20,16 +20,10 @@
padding: 20px 0; padding: 20px 0;
} }
.site-nav-toggle, .site-nav-right { .site-nav-toggle, .site-nav-search {
color: white;
+tablet() { +tablet() {
flex-column(); flex-column();
} }
.toggle {
color: white;
.toggle-line {
background: white;
}
}
} }

View File

@ -15,7 +15,6 @@ body { margin-top: 2rem; }
} }
.use-motion .column, .use-motion .column,
.use-motion .site-brand-container .toggle,
.use-motion .footer { opacity: initial; } .use-motion .footer { opacity: initial; }
.use-motion .site-title, .use-motion .site-title,

View File

@ -9,8 +9,7 @@ NexT.boot.registerEvents = function() {
NexT.utils.updateFooterPosition(); NexT.utils.updateFooterPosition();
// Mobile top menu bar. // Mobile top menu bar.
document.querySelector('.site-nav-toggle .toggle').addEventListener('click', event => { document.querySelector('.site-nav-toggle').addEventListener('click', event => {
event.currentTarget.classList.toggle('toggle-close');
const siteNav = document.querySelector('.site-nav'); const siteNav = document.querySelector('.site-nav');
if (!siteNav) return; if (!siteNav) return;
siteNav.style.setProperty('--scroll-height', siteNav.scrollHeight + 'px'); siteNav.style.setProperty('--scroll-height', siteNav.scrollHeight + 'px');

View File

@ -26,7 +26,8 @@ const pjax = new Pjax({
}, },
analytics: false, analytics: false,
cacheBust: false, cacheBust: false,
scrollTo : !CONFIG.bookmark.enable // scrollTo accepts a number (vertical offset), a number array ([x, y]), or false (do not scroll).
scrollTo : CONFIG.bookmark.enable ? false : 0
}); });
document.addEventListener('pjax:success', () => { document.addEventListener('pjax:success', () => {

View File

@ -3,13 +3,17 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const isRight = CONFIG.sidebar.position === 'right'; const isRight = CONFIG.sidebar.position === 'right';
// Create the dimmer dynamically to prevent an unwanted animation before main.css is applied.
const sidebarDimmer = document.createElement('div');
sidebarDimmer.className = 'sidebar-dimmer';
document.body.appendChild(sidebarDimmer);
const sidebarToggleMotion = { const sidebarToggleMotion = {
mouse: {}, mouse: {},
init() { init() {
window.addEventListener('mousedown', this.mousedownHandler.bind(this)); window.addEventListener('mousedown', this.mousedownHandler.bind(this));
window.addEventListener('mouseup', this.mouseupHandler.bind(this)); window.addEventListener('mouseup', this.mouseupHandler.bind(this));
document.querySelector('.sidebar-dimmer').addEventListener('click', this.clickHandler.bind(this)); sidebarDimmer.addEventListener('click', this.clickHandler.bind(this));
document.querySelector('.sidebar-toggle').addEventListener('click', this.clickHandler.bind(this)); document.querySelector('.sidebar-toggle').addEventListener('click', this.clickHandler.bind(this));
window.addEventListener('sidebar:show', this.showSidebar); window.addEventListener('sidebar:show', this.showSidebar);
window.addEventListener('sidebar:hide', this.hideSidebar); window.addEventListener('sidebar:hide', this.hideSidebar);

View File

@ -1,6 +1,7 @@
/* global CONFIG, NexT, pjax */ /* global CONFIG, NexT, pjax */
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(document.querySelector('#search-popup-template').content.cloneNode(true));
const { indexName, appID, apiKey, hits } = CONFIG.algolia; const { indexName, appID, apiKey, hits } = CONFIG.algolia;
const client = window['algoliasearch/lite'].liteClient(appID, apiKey); const client = window['algoliasearch/lite'].liteClient(appID, apiKey);

View File

@ -6,6 +6,7 @@ document.addEventListener('DOMContentLoaded', () => {
console.warn('`hexo-generator-searchdb` plugin is not installed!'); console.warn('`hexo-generator-searchdb` plugin is not installed!');
return; return;
} }
document.body.appendChild(document.querySelector('#search-popup-template').content.cloneNode(true));
const localSearch = new LocalSearch({ const localSearch = new LocalSearch({
path : CONFIG.path, path : CONFIG.path,
top_n_per_article: CONFIG.localsearch.top_n_per_article, top_n_per_article: CONFIG.localsearch.top_n_per_article,