[S] Make router responsive
This commit is contained in:
@@ -15,4 +15,9 @@
|
|||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Load this last */
|
||||||
|
* { transition: all .25s ease }
|
||||||
|
</style>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+118
-24
@@ -1,16 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="nav" class="fbox-v">
|
<div id="nav" class="fbox-v"
|
||||||
<div id="hamburger"></div>
|
:class="(this.currentLink ? this.currentLink.textContent.toLowerCase() : '') + ' ' + (menuOpen ? 'open' : '')">
|
||||||
<div class="spacer f-grow1"/>
|
<div id="menu" @click="showMenu"><i class="fas fa-bars"></i></div>
|
||||||
|
|
||||||
<router-link class="router-link" to="/projects">{{ $t('nav.projects') }}</router-link>
|
<div id="items" class="fbox-v">
|
||||||
<div class="dot">·</div>
|
<router-link class="router-link" to="/projects">{{ $t('nav.projects') }}</router-link>
|
||||||
<router-link class="router-link" to="/blog">{{ $t('nav.blog') }}</router-link>
|
<div class="dot">·</div>
|
||||||
<div class="dot">·</div>
|
<router-link class="router-link" to="/blog">{{ $t('nav.blog') }}</router-link>
|
||||||
<router-link class="router-link" to="/about">{{ $t('nav.about') }}</router-link>
|
<div class="dot">·</div>
|
||||||
<div class="dot">·</div>
|
<router-link class="router-link" to="/about">{{ $t('nav.about') }}</router-link>
|
||||||
<router-link class="router-link" to="/">{{ $t('nav.home') }}</router-link>
|
<div class="dot">·</div>
|
||||||
<div class="dot">·</div>
|
<router-link class="router-link" to="/">{{ $t('nav.home') }}</router-link>
|
||||||
|
<div class="dot">·</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="nav-bookmark" ref="bookmark" :style="bookmarkCss"></div>
|
<div id="nav-bookmark" ref="bookmark" :style="bookmarkCss"></div>
|
||||||
<div id="nav-background"></div>
|
<div id="nav-background"></div>
|
||||||
@@ -46,18 +48,35 @@ function runAfter(condition: () => boolean, callback: () => void, timeout=10): v
|
|||||||
})
|
})
|
||||||
export default class App extends Vue
|
export default class App extends Vue
|
||||||
{
|
{
|
||||||
currentLink!: Element
|
currentLink: Element = null as never as Element
|
||||||
bookmarkCss: {[id: string]: string} = {}
|
bookmarkCss = ""
|
||||||
bookmarkUpdateIntervalId!: number
|
bookmarkUpdateIntervalId!: number
|
||||||
lastTop = 0
|
lastTop = 0
|
||||||
|
|
||||||
|
menuOpen = false
|
||||||
|
|
||||||
|
showMenu(): void
|
||||||
|
{
|
||||||
|
this.menuOpen = !this.menuOpen
|
||||||
|
|
||||||
|
// Auto close
|
||||||
|
if (this.menuOpen)
|
||||||
|
{
|
||||||
|
setTimeout(() => this.menuOpen = false, 2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateBookmark(): void
|
updateBookmark(): void
|
||||||
{
|
{
|
||||||
|
// On page change
|
||||||
runAfter(() => document.querySelector('.router-link-active') != this.currentLink, () =>
|
runAfter(() => document.querySelector('.router-link-active') != this.currentLink, () =>
|
||||||
{
|
{
|
||||||
let el = document.querySelector('.router-link-active')
|
let el = document.querySelector('.router-link-active')
|
||||||
if (el != null) this.currentLink = el
|
if (el != null) this.currentLink = el
|
||||||
this.calculateBookmarkCss()
|
this.calculateBookmarkCss()
|
||||||
|
|
||||||
|
// Close menu
|
||||||
|
this.menuOpen = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,21 +97,20 @@ export default class App extends Vue
|
|||||||
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
|
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
|
||||||
let box = this.currentLink.getBoundingClientRect()
|
let box = this.currentLink.getBoundingClientRect()
|
||||||
if (box.top == this.lastTop) return
|
if (box.top == this.lastTop) return
|
||||||
|
this.lastTop = box.top
|
||||||
|
|
||||||
let h = box.bottom - box.top
|
let h = box.bottom - box.top
|
||||||
this.bookmarkCss = {
|
let width = Math.round(h / 2) + 8
|
||||||
top: `${box.top - 8}px`,
|
|
||||||
border: `${Math.round(h / 2) + 8}px solid var(--bookmark-color)`,
|
this.bookmarkCss = `top: ${box.top - 8}px;` +
|
||||||
'border-right': '20px solid transparent',
|
`border-width: ${width}px 20px ${width}px 50px;`
|
||||||
'border-left': '50px solid var(--bookmark-color)'
|
|
||||||
}
|
|
||||||
console.log(this.bookmarkCss)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="sass">
|
<style lang="sass">
|
||||||
@import "css/global"
|
@import "css/global"
|
||||||
|
@import "css/animations"
|
||||||
|
|
||||||
#nav
|
#nav
|
||||||
position: fixed
|
position: fixed
|
||||||
@@ -101,6 +119,17 @@ export default class App extends Vue
|
|||||||
font-size: 1.4em
|
font-size: 1.4em
|
||||||
align-items: flex-start
|
align-items: flex-start
|
||||||
|
|
||||||
|
#menu
|
||||||
|
padding: 5px 10px
|
||||||
|
margin: 15px 10px
|
||||||
|
background-color: rgba(255, 255, 255, 0.49)
|
||||||
|
border-radius: 10px
|
||||||
|
text-shadow: -1px -1px 1px rgba(255,255,255,.1), 1px 1px 1px rgba(0,0,0,.5)
|
||||||
|
filter: drop-shadow(0 0 30px rgb(255, 255, 255))
|
||||||
|
z-index: 100
|
||||||
|
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
#nav-bookmark
|
#nav-bookmark
|
||||||
position: absolute
|
position: absolute
|
||||||
left: 0
|
left: 0
|
||||||
@@ -108,6 +137,13 @@ export default class App extends Vue
|
|||||||
height: 0
|
height: 0
|
||||||
z-index: 5
|
z-index: 5
|
||||||
--bookmark-color: rgb(255, 225, 230)
|
--bookmark-color: rgb(255, 225, 230)
|
||||||
|
border-color: var(--bookmark-color) transparent var(--bookmark-color) var(--bookmark-color)
|
||||||
|
border-style: solid
|
||||||
|
border-width: 20px
|
||||||
|
|
||||||
|
#items
|
||||||
|
justify-content: flex-end
|
||||||
|
z-index: 10
|
||||||
|
|
||||||
.router-link
|
.router-link
|
||||||
color: rgba(128, 112, 92, 0.71)
|
color: rgba(128, 112, 92, 0.71)
|
||||||
@@ -129,13 +165,71 @@ export default class App extends Vue
|
|||||||
position: absolute
|
position: absolute
|
||||||
height: 100%
|
height: 100%
|
||||||
width: 100px
|
width: 100px
|
||||||
left: -40px
|
left: 0
|
||||||
background: linear-gradient(to right, rgba(247, 169, 121, 0.42), transparent)
|
$nav-bg-color: #f9f2e0
|
||||||
z-index: 10
|
//$nav-bg-color: rgb(255, 230, 214)
|
||||||
|
border-left: 20px solid $nav-bg-color
|
||||||
|
background: linear-gradient(to right, $nav-bg-color, transparent)
|
||||||
|
z-index: 4
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
#meru
|
#meru
|
||||||
height: 160px
|
height: 160px
|
||||||
|
z-index: 100
|
||||||
|
|
||||||
|
// Tablet layout
|
||||||
|
@media screen and (max-width: 800px)
|
||||||
|
#nav #menu
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
#nav.home
|
||||||
|
#nav-background
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
#nav.home #menu
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
#nav:not(.home).open
|
||||||
|
#items, #nav-bookmark, #nav-background, #meru
|
||||||
|
opacity: 1
|
||||||
|
animation: fade-in-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both
|
||||||
|
|
||||||
|
#nav:not(.home)
|
||||||
|
#items, #nav-bookmark, #nav-background, #meru
|
||||||
|
opacity: 0
|
||||||
|
animation: fade-out-left 1s 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both
|
||||||
|
|
||||||
// Phone layout
|
// Phone layout
|
||||||
@media screen and (max-width: 570px)
|
@media screen and (max-width: 500px), (max-height: 660px)
|
||||||
|
#app
|
||||||
|
font-size: 14px
|
||||||
|
|
||||||
|
#nav
|
||||||
|
#nav-bookmark
|
||||||
|
width: 10px
|
||||||
|
|
||||||
|
#meru
|
||||||
|
height: 120px
|
||||||
|
|
||||||
|
// Smaller phone layout
|
||||||
|
@media screen and (max-width: 400px)
|
||||||
|
#nav
|
||||||
|
.items
|
||||||
|
opacity: 0
|
||||||
|
animation: fade-out-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both
|
||||||
|
|
||||||
|
// Phone Height
|
||||||
|
@media screen and (max-height: 600px)
|
||||||
|
#nav
|
||||||
|
.dot
|
||||||
|
margin: 10px 0
|
||||||
|
|
||||||
|
// Phone Height
|
||||||
|
@media screen and (max-height: 500px)
|
||||||
|
#nav
|
||||||
|
.router-link
|
||||||
|
margin-bottom: 10px
|
||||||
|
|
||||||
|
.dot
|
||||||
|
display: none
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -115,9 +115,6 @@ body
|
|||||||
.nowrap.e
|
.nowrap.e
|
||||||
text-overflow: ellipsis
|
text-overflow: ellipsis
|
||||||
|
|
||||||
*
|
|
||||||
transition: all .25s ease
|
|
||||||
|
|
||||||
#app
|
#app
|
||||||
font-family: $font
|
font-family: $font
|
||||||
-webkit-font-smoothing: antialiased
|
-webkit-font-smoothing: antialiased
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ export default class Blog extends Vue
|
|||||||
border-radius: 0
|
border-radius: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
background: unset
|
background: unset
|
||||||
|
margin: 20px 20px 0
|
||||||
|
width: unset
|
||||||
|
|
||||||
.post
|
.post
|
||||||
background-color: #fdf9f1
|
background-color: #fdf9f1
|
||||||
|
|||||||
Reference in New Issue
Block a user