marc-leopold/app/pages/index.vue

233 lines
4.6 KiB
Vue
Raw Permalink Normal View History

2019-02-24 16:42:27 +00:00
<template>
<section class="home">
<div class="background background-img">
<BackgroundImageLoader slot="background"
:image-url="currentImageUrl"
@imageLoaded="handleImageLoaded"
@imageLoadError="handleImageLoadError"
/>
<div class="background background-overlay"></div>
</div>
<div class="content">
<transition name="fade">
<h1 v-if="showHeading" class="heading">Marc Leopold Photography</h1>
</transition>
<transition name="fade" mode="out-in">
<p class="tagline"
:key="currentTaglineIndex">
{{ tagline }}
</p>
</transition>
</div>
</section>
</template>
<script>
import ContentPage from '@/components/ContentPage'
import BackgroundImageLoader from '@/components/BackgroundImageLoader'
export default {
name: 'HomePage',
components: {
ContentPage,
BackgroundImageLoader
},
data() {
return {
showHeading: false,
currentImageIndex: -1,
currentTaglineIndex: -1,
}
},
computed: {
currentImageUrl () {
let url = null
if (this.currentImageIndex > -1) {
url = this.bgImages[this.currentImageIndex]
}
return url
},
tagline () {
return this.currentTaglineIndex > -1 ? this.taglines[this.currentTaglineIndex].text : ''
}
},
head () {
return {
title: 'Home',
meta: [{
hid: 'description',
name: 'description',
content: 'Photographer, Marc Leopold has images in numerous collections and publications. Here is a glimpse of his work, an insight into his philosophy and motivations.'
}],
}
},
mounted () {
if (this.bgImages.length > 0) {
this.setNextIndex()
this.showHeading = true
}
},
async asyncData({ $axios }) {
try {
const { bgImages, taglines } = await $axios.$get('/api/v1/home')
if (bgImages.length < 1) {
throw new Error('bgImages empty')
}
return { bgImages, taglines }
} catch {
return {
bgImages: ['/img/default-home.jpg'],
taglines: [''],
}
}
},
methods: {
setNextIndex () {
this.currentImageIndex =
this.currentImageIndex < this.bgImages.length - 1 ? this.currentImageIndex + 1 : 0
},
nextTagline () {
this.currentTaglineIndex =
this.currentTaglineIndex < this.taglines.length - 1 ? this.currentTaglineIndex + 1 : 0
},
handleImageLoaded () {
window.setTimeout(() => {
this.nextTagline()
}, 700)
window.setTimeout(() => {
this.setNextIndex()
}, 6000)
},
handleImageLoadError () {
this.setNextIndex()
},
}
}
</script>
<style scoped lang="scss">
$heading-height: 4em;
$tagline-height: 2.5em;
$padding: 1rem;
.home {
position: relative;
width: 100%;
height: 100%;
padding: $site-menu__header-height + $padding $padding $padding;
font-size: .5rem;
@media (min-width: $bp__layout) {
padding: $padding $padding $padding $site-menu__header-width + $padding;
font-size: 1rem;
}
}
.background {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.background-img {
z-index: -1;
}
.background-overlay {
$color: $color__neutral-100;
background-color: rgba($color, .4);
background: linear-gradient(
to bottom left,
rgba($color, .1),
rgba($color, .5)
),
linear-gradient(
to bottom,
rgba($color, .9),
rgba($color, .7) $heading-height * 1.5,
rgba($color, .4) $heading-height * 3,
rgba($color, 0) $heading-height * 6,
rgba($color, 0)
),
linear-gradient(
to top,
rgba($color, .6),
rgba($color, 0) $tagline-height * 4,
rgba($color, 0)
),
linear-gradient(
to right,
rgba($color, .4),
rgba($color, 0) 20%,
rgba($color, 0) 80%,
rgba($color, .4)
),
radial-gradient(
at 100% 100%,
rgba($color, .4) 0,
rgba($color, 0) 40%
);
}
.content {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
width: 100%;
max-width: 80rem;
margin: 0 auto;
padding: 1rem 0 0;
@media (min-width: $bp__layout) {
padding: 2rem 3rem 1rem;
}
}
.heading {
color: $color__neutral-900;
font-size: $heading-height;
@include font-title(400);
text-align: center;
}
.tagline {
color: $color__neutral-600;
font-size: $tagline-height;
text-align: right;
@include font-cursive;
}
.fade {
$timing: .7;
&-enter-active {
transition: opacity 5s * $timing .5s ease-in;
}
&-leave-active {
transition: opacity 2s * $timing ease-out;
}
&-enter, &-leave-to {
opacity: 0;
}
}
</style>