Add animations, add album page, add left panel autoclosing
This commit is contained in:
14
src/App.vue
14
src/App.vue
@@ -2,7 +2,7 @@
|
||||
<div id="app">
|
||||
<div class="left-panel"
|
||||
:class="{'left-panel-closed': leftPanelClosed}">
|
||||
<LeftPanel></LeftPanel>
|
||||
<LeftPanel @closeLeftPanel="closeLeftPanel()"></LeftPanel>
|
||||
</div>
|
||||
<div class="content w-100"
|
||||
:class="{'content-when-left-panel-open': !leftPanelClosed}">
|
||||
@@ -99,6 +99,18 @@ export default class App extends Vue {
|
||||
|
||||
this.leftPanelClosed = !this.leftPanelClosed;
|
||||
}
|
||||
|
||||
closeLeftPanel() {
|
||||
if (this.leftPanelClosed) {
|
||||
this.closeIcon.anim.setDirection(1);
|
||||
this.closeIcon.anim.play();
|
||||
} else {
|
||||
this.closeIcon.anim.setDirection(-1);
|
||||
this.closeIcon.anim.play();
|
||||
}
|
||||
|
||||
this.leftPanelClosed = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
<template>
|
||||
<div
|
||||
@mouseover="mouseover"
|
||||
@mouseleave="mouseleave"
|
||||
ref="element" class="album"
|
||||
:style="albumStyle">
|
||||
<div class="w-100 h-100 background-wrapper">
|
||||
<div class="w-100 h-100 backgrounds">
|
||||
<transition name="fade">
|
||||
<div v-show="showCover" class="w-100 h-100 cover" :style="coverStyle"></div>
|
||||
</transition>
|
||||
<transition name="fade" v-for="file in data.files" :key="file.id">
|
||||
<div v-show="!showCover && file === data.files[currentPhotoNumber]"
|
||||
class="w-100 h-100 cover"
|
||||
:style="{'background-image': `url('pictures/albums/${data.folderName}/${file}')`,}"></div>
|
||||
</transition>
|
||||
<transition appear name="fade">
|
||||
<div
|
||||
@click="onClick"
|
||||
@mouseover="mouseover"
|
||||
@mouseleave="mouseleave"
|
||||
ref="element" class="album"
|
||||
:style="albumStyle">
|
||||
<div class="w-100 h-100 background-wrapper">
|
||||
<div class="w-100 h-100 backgrounds">
|
||||
<transition name="fade">
|
||||
<div v-show="showCover" class="w-100 h-100 cover" :style="coverStyle"></div>
|
||||
</transition>
|
||||
<transition name="fade" v-for="file in data.files" :key="file.id">
|
||||
<div v-show="!showCover && file === data.files[currentPhotoNumber]"
|
||||
class="w-100 h-100 cover"
|
||||
:style="{'background-image': `url('pictures/albums/${data.folderName}/${file}')`,}"></div>
|
||||
</transition>
|
||||
<div :style="cacheBlockStyle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-100 h-100 background-mask">
|
||||
<div class="info text-center">
|
||||
<div class="info-name">{{ data.name }}</div>
|
||||
<hr class="info-hr">
|
||||
<div class="info-description">{{ data.description }}</div>
|
||||
<div class="w-100 h-100 background-mask">
|
||||
<div class="info text-center">
|
||||
<div class="info-name">{{ data.name }}</div>
|
||||
<hr class="info-hr">
|
||||
<div class="info-description">{{ data.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -73,6 +77,13 @@ export default class Album extends Vue {
|
||||
};
|
||||
}
|
||||
|
||||
get cacheBlockStyle() {
|
||||
const chacheImageNumber = (this.currentPhotoNumber + 1) % this.data.files.length;
|
||||
return {
|
||||
'background-image': `url('pictures/albums/${this.data.folderName}/${this.data.files[chacheImageNumber]}')`,
|
||||
}
|
||||
}
|
||||
|
||||
updateHeight(): void {
|
||||
if (this.element === undefined)
|
||||
return;
|
||||
@@ -97,6 +108,10 @@ export default class Album extends Vue {
|
||||
this.currentPhotoNumber = (this.currentPhotoNumber + 1) % this.data.files.length;
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this.$router.push({ name: 'Album Page', params: { name: this.data.folderName } })
|
||||
}
|
||||
|
||||
mouseover(event: Event) {
|
||||
this.showCover = false;
|
||||
}
|
||||
@@ -147,7 +162,9 @@ export default class Album extends Vue {
|
||||
|
||||
.background-mask > .info {
|
||||
opacity: 0;
|
||||
transition: opacity linear .3s;
|
||||
padding-top: 3em;
|
||||
|
||||
transition: all linear .3s;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -158,7 +175,9 @@ export default class Album extends Vue {
|
||||
|
||||
.background-mask:hover > .info {
|
||||
opacity: 1;
|
||||
transition: opacity linear .3s;
|
||||
padding-top: 0;
|
||||
|
||||
transition: all linear .3s;
|
||||
}
|
||||
|
||||
.info-hr {
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
</div>
|
||||
<div class="main-column links text-center">
|
||||
<div class="link-wrapper">
|
||||
<router-link class="link"
|
||||
:class="{'active-link': isActiveLink('Home')}"
|
||||
:to="{'name': 'Home'}">HOME</router-link>
|
||||
<span class="link"
|
||||
:class="{'active-link': isActiveLink('Home')}"
|
||||
@click="goToHome">
|
||||
HOME
|
||||
</span>
|
||||
</div>
|
||||
<div class="link-wrapper">
|
||||
<router-link class="link"
|
||||
:class="{'active-link': isActiveLink('About Me')}"
|
||||
:to="{'name': 'About Me'}">ABOUT ME</router-link>
|
||||
<span class="link"
|
||||
:class="{'active-link': isActiveLink('About Me')}"
|
||||
@click="goToAboutMe">
|
||||
ABOUT ME
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-column socials text-center">
|
||||
@@ -48,6 +52,18 @@ export default class LeftPanel extends Vue {
|
||||
isActiveLink(name: string): boolean {
|
||||
return this.$route.name === name;
|
||||
}
|
||||
|
||||
goToHome() {
|
||||
this.$router.push({'name': 'Home'});
|
||||
|
||||
this.$emit('closeLeftPanel');
|
||||
}
|
||||
|
||||
goToAboutMe() {
|
||||
this.$router.push({'name': 'About Me'});
|
||||
|
||||
this.$emit('closeLeftPanel');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter, { RouteConfig } from 'vue-router'
|
||||
|
||||
import Home from '@/views/Home.vue'
|
||||
import About from '@/views/About.vue'
|
||||
import Home from '@/views/Home.vue';
|
||||
import About from '@/views/About.vue';
|
||||
import Album from '@/views/Album.vue';
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
@@ -16,6 +17,11 @@ Vue.use(VueRouter)
|
||||
path: '/about',
|
||||
name: 'About Me',
|
||||
component: About
|
||||
},
|
||||
{
|
||||
path: '/album/:name',
|
||||
name: 'Album Page',
|
||||
component: Album,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
20
src/views/Album.vue
Normal file
20
src/views/Album.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
Album Page
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator';
|
||||
|
||||
@Component({
|
||||
name: 'AlbumPage',
|
||||
})
|
||||
export default class AlbumPage extends Vue {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -4,8 +4,6 @@
|
||||
<div class="albums-wrapper">
|
||||
<div class="albums">
|
||||
<Album v-for="album in albums" :key="album.folderName" :data="album"></Album>
|
||||
<!-- ToDO: Delete -->
|
||||
<Album v-for="album in albums" :key="album.folderName + 'copy'" :data="album"></Album>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +27,9 @@ import Album, { IAlbum } from '@/components/Album.vue';
|
||||
export default class Home extends Vue {
|
||||
@Prop({required: true}) public readonly leftPanelClosed!: boolean;
|
||||
|
||||
public albums: IAlbum[] = [
|
||||
public albums: IAlbum[] = [];
|
||||
|
||||
public sourceAlbums: IAlbum[] = [
|
||||
{
|
||||
name: 'Test',
|
||||
description: 'Test description',
|
||||
@@ -74,6 +74,12 @@ export default class Home extends Vue {
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
mounted() {
|
||||
this.sourceAlbums.forEach((item, index) => {
|
||||
setTimeout(() => this.albums.push(item), 300 * index);
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -93,7 +99,6 @@ export default class Home extends Vue {
|
||||
.albums-wrapper {
|
||||
width: calc(100vw - 405px);
|
||||
margin-left: 405px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user