Compare commits
3 Commits
stage
...
nav-animat
Author | SHA1 | Date |
---|---|---|
syuilo | a0e1ae80b4 | |
syuilo | 06d33ec520 | |
syuilo | 91643db0a4 |
|
@ -9,7 +9,7 @@ import { defineComponent } from 'vue';
|
|||
import { faExpandAlt, faColumns, faExternalLinkAlt, faLink, faWindowMaximize } from '@fortawesome/free-solid-svg-icons';
|
||||
import * as os from '@client/os';
|
||||
import copyToClipboard from '@client/scripts/copy-to-clipboard';
|
||||
import { router } from '@client/router';
|
||||
import { router, setNavigationInfo } from '@client/router';
|
||||
import { url } from '@client/config';
|
||||
import { popout } from '@client/scripts/popout';
|
||||
import { ColdDeviceStorage } from '@client/store';
|
||||
|
@ -130,6 +130,10 @@ export default defineComponent({
|
|||
if (this.$router.currentRoute.value.path === this.to) {
|
||||
window.scroll({ top: 0, behavior: 'smooth' });
|
||||
} else {
|
||||
setNavigationInfo({
|
||||
from: this.$router.currentRoute.value.path,
|
||||
to: this.to
|
||||
});
|
||||
this.$router.push(this.to);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { defineAsyncComponent, markRaw } from 'vue';
|
||||
import { defineAsyncComponent, markRaw, ref } from 'vue';
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import MkLoading from '@client/pages/_loading_.vue';
|
||||
import MkError from '@client/pages/_error_.vue';
|
||||
|
@ -13,6 +13,16 @@ const page = (path: string) => defineAsyncComponent({
|
|||
|
||||
let indexScrollPos = 0;
|
||||
|
||||
export const navigationInfo = ref(null);
|
||||
export function setNavigationInfo(info) {
|
||||
navigationInfo.value = info;
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', (event) => {
|
||||
console.log('popstate');
|
||||
navigationInfo.value = null;
|
||||
});
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
|
@ -91,7 +101,7 @@ export const router = createRouter({
|
|||
// 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする
|
||||
scrollBehavior(to) {
|
||||
window._scroll = () => { // さらにHacky
|
||||
if (to.name === 'index') {
|
||||
if (location.pathname === '/') {
|
||||
window.scroll({ top: indexScrollPos, behavior: 'instant' });
|
||||
const i = setInterval(() => {
|
||||
window.scroll({ top: indexScrollPos, behavior: 'instant' });
|
||||
|
@ -106,11 +116,11 @@ export const router = createRouter({
|
|||
}
|
||||
});
|
||||
|
||||
router.afterEach((to, from) => {
|
||||
if (from.name === 'index') {
|
||||
export function saveScrollPosition() {
|
||||
if (navigationInfo.value?.from === '/') {
|
||||
indexScrollPos = window.scrollY;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function resolve(path: string) {
|
||||
const resolved = router.resolve(path);
|
||||
|
|
|
@ -322,6 +322,8 @@ hr {
|
|||
box-sizing: border-box;
|
||||
margin: var(--root-margin, 32px) auto;
|
||||
max-width: min(var(--baseContentWidth), calc(100% - (var(--root-margin, 32px) * 2)));
|
||||
background: var(--bg);
|
||||
min-height: 100%;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
--root-margin: 10px;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</header>
|
||||
<div class="content" :class="{ _flat_: !fullView }">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
||||
<transition :name="$store.state.animation && navigationInfo ? 'page' : ''" @before-enter="saveScrollPosition" @enter="onTransition">
|
||||
<keep-alive :include="['timeline']">
|
||||
<component :is="Component" :ref="changePage"/>
|
||||
</keep-alive>
|
||||
|
@ -64,6 +64,7 @@ import XHeader from './_common_/header.vue';
|
|||
import * as os from '@client/os';
|
||||
import { sidebarDef } from '@client/sidebar';
|
||||
import * as symbols from '@client/symbols';
|
||||
import { saveScrollPosition, navigationInfo } from '@client/router';
|
||||
|
||||
const DESKTOP_THRESHOLD = 1100;
|
||||
const MOBILE_THRESHOLD = 600;
|
||||
|
@ -85,6 +86,7 @@ export default defineComponent({
|
|||
isDesktop: window.innerWidth >= DESKTOP_THRESHOLD,
|
||||
widgetsShowing: false,
|
||||
fullView: false,
|
||||
navigationInfo,
|
||||
wallpaper: localStorage.getItem('wallpaper') != null,
|
||||
faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt,
|
||||
};
|
||||
|
@ -152,6 +154,10 @@ export default defineComponent({
|
|||
this.$refs.drawerNav.show();
|
||||
},
|
||||
|
||||
saveScrollPosition() {
|
||||
saveScrollPosition();
|
||||
},
|
||||
|
||||
onTransition() {
|
||||
if (window._scroll) window._scroll();
|
||||
},
|
||||
|
@ -215,6 +221,39 @@ export default defineComponent({
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
.page-enter-active {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
transition: transform 500ms cubic-bezier(0.23, 1, 0.32, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||
}
|
||||
.page-leave-active {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
transition: transform 500ms cubic-bezier(0.23, 1, 0.32, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||
}
|
||||
.page-enter-from {
|
||||
//opacity: 0;
|
||||
transform: translateX(128px);
|
||||
|
||||
/* iOSはoverflow: clipをサポートしていない */
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
.page-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(-64px);
|
||||
|
||||
/* iOSはoverflow: clipをサポートしていない */
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.mk-app {
|
||||
$header-height: 50px;
|
||||
$ui-font-size: 1em;
|
||||
|
@ -294,6 +333,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
> .content {
|
||||
position: relative;
|
||||
background: var(--bg);
|
||||
--stickyTop: #{$header-height};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue