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…
	
	Add table
		Add a link
		
	
		Reference in a new issue