[+] Bookmarks
This commit is contained in:
+75
-13
@@ -1,22 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="nav" class="fbox-v font-code">
|
<div id="nav" class="fbox-v">
|
||||||
<router-link class="router-link" to="/"><span>Home</span></router-link>
|
<router-link class="router-link" to="/"><span>Home</span></router-link>
|
||||||
<router-link class="router-link" to="/about"><span>About</span></router-link>
|
<router-link class="router-link" to="/about"><span>About</span></router-link>
|
||||||
|
<router-link class="router-link" to="/blog"><span>Blog</span></router-link>
|
||||||
|
<router-link class="router-link" to="/projects"><span>Projects</span></router-link>
|
||||||
|
|
||||||
|
<div id="nav-bookmark" ref="bookmark" :style="bookmarkCss"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-view/>
|
<router-view/>
|
||||||
|
|
||||||
<MeruIcon/>
|
<MeruIcon/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import MeruIcon from "@/components/MeruIcon";
|
import MeruIcon from "@/components/MeruIcon.vue";
|
||||||
import {Options, Vue} from "vue-class-component";
|
import {Options, Vue} from "vue-class-component";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
function runAfter(condition: () => boolean, callback: () => void, timeout=10): void
|
||||||
|
{
|
||||||
|
let times = 0
|
||||||
|
let id = setInterval(() => {
|
||||||
|
if (times <= timeout && !condition())
|
||||||
|
{
|
||||||
|
times ++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
callback()
|
||||||
|
clearInterval(id)
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
@Options({
|
@Options({
|
||||||
components: {MeruIcon}
|
components: {MeruIcon}
|
||||||
})
|
})
|
||||||
export default class App extends Vue
|
export default class App extends Vue
|
||||||
{
|
{
|
||||||
|
currentLink!: Element
|
||||||
|
bookmarkCss: {[id: string]: string} = {}
|
||||||
|
|
||||||
|
updateBookmark(): void
|
||||||
|
{
|
||||||
|
runAfter(() => document.querySelector('.router-link-active span') != this.currentLink, () =>
|
||||||
|
{
|
||||||
|
let el = document.querySelector('.router-link-active span')
|
||||||
|
if (el != null) this.currentLink = el
|
||||||
|
this.calculateBookmarkCss()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted(): void
|
||||||
|
{
|
||||||
|
router.afterEach(() => this.updateBookmark())
|
||||||
|
this.updateBookmark()
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateBookmarkCss(): void
|
||||||
|
{
|
||||||
|
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
|
||||||
|
let box = this.currentLink.getBoundingClientRect()
|
||||||
|
let h = box.bottom - box.top
|
||||||
|
this.bookmarkCss = {
|
||||||
|
top: `${box.top - 8}px`,
|
||||||
|
border: `${Math.round(h / 2) + 8}px solid rgba(255, 216, 224, 0.49)`,
|
||||||
|
'border-right': '20px solid transparent',
|
||||||
|
'border-left': '50px solid rgba(255, 216, 224, 0.49)'
|
||||||
|
}
|
||||||
|
console.log(this.bookmarkCss)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -27,27 +80,36 @@ export default class App extends Vue
|
|||||||
position: absolute
|
position: absolute
|
||||||
left: 20px
|
left: 20px
|
||||||
height: 100vh
|
height: 100vh
|
||||||
font-size: 1.2em
|
font-size: 1.4em
|
||||||
|
flex-direction: column-reverse
|
||||||
|
|
||||||
|
#nav-bookmark
|
||||||
|
position: absolute
|
||||||
|
left: -40px
|
||||||
|
width: 30px
|
||||||
|
height: 0
|
||||||
|
z-index: 0
|
||||||
|
|
||||||
.router-link
|
.router-link
|
||||||
color: #80705c
|
color: rgba(128, 112, 92, 0.71)
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
writing-mode: vertical-rl
|
writing-mode: vertical-rl
|
||||||
text-orientation: sideways
|
text-orientation: sideways
|
||||||
transform: scale(-1)
|
transform: scale(-1)
|
||||||
|
|
||||||
.router-link.router-link-active span
|
|
||||||
text-decoration: underline
|
|
||||||
|
|
||||||
.router-link:before
|
.router-link:before
|
||||||
content: '·'
|
content: '·'
|
||||||
margin-top: 10px
|
margin: 20px 0
|
||||||
margin-bottom: 10px
|
|
||||||
|
|
||||||
.router-link:last-child:before
|
.router-link
|
||||||
content: none
|
position: relative
|
||||||
|
z-index: 10
|
||||||
|
|
||||||
#nav::before, #nav::after
|
#nav::after
|
||||||
content: " "
|
content: " "
|
||||||
flex-grow: 1
|
flex-grow: 1
|
||||||
|
|
||||||
|
#nav::before
|
||||||
|
content: " "
|
||||||
|
height: 180px
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+11
-1
@@ -14,10 +14,20 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
// this generates a separate chunk (about.[hash].js) for this route
|
// this generates a separate chunk (about.[hash].js) for this route
|
||||||
// which is lazy-loaded when the route is visited.
|
// which is lazy-loaded when the route is visited.
|
||||||
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
|
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/blog',
|
||||||
|
name: 'Blog',
|
||||||
|
component: () => import('../views/About.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/projects',
|
||||||
|
name: 'Projects',
|
||||||
|
component: () => import('../views/About.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
export const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes
|
routes
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user