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