marc-leopold/components/BackgroundImageLoader.vue

174 lines
3.1 KiB
Vue
Raw Normal View History

2019-01-18 13:33:13 +00:00
<template>
<div class="background-image-loader">
<div class="background-container">
<div class="background background-default"></div>
<transition name="fade-fast">
<div v-if="loadedImageUrl !== null"
class="background background-img background-blur"
:style="backgroundBlurStyle"
>
</div>
</transition>
2019-01-22 12:54:21 +00:00
<transition name="fade">
<div class="background background-img"
:key="loadedImageUrl"
:style="backgroundStyle"
>
</div>
</transition>
</div>
2019-01-18 13:33:13 +00:00
</div>
</template>
<script>
import imageLoader from '~/mixins/imageLoader.js'
export default {
mixins: [ imageLoader ],
2019-01-18 13:33:13 +00:00
props: {
2019-01-22 12:54:21 +00:00
imageUrl: {
type: String,
required: false,
default: function () {
2019-01-22 12:54:21 +00:00
return null
}
},
2019-01-18 13:33:13 +00:00
},
data () {
return {
2019-01-22 12:54:21 +00:00
loadedImageUrl: null,
2019-01-18 13:33:13 +00:00
}
},
computed: {
backgroundStyle () {
let style = {}
if (this.loadedImageUrl) {
style.backgroundImage = `url(${this.loadedImageUrl})`
}
return style
},
backgroundBlurStyle () {
2019-01-22 12:54:21 +00:00
let style = {}
if (this.loadedImageUrl) {
style.backgroundImage = `url(${this.loadedImageUrl})`
}
2019-01-22 12:54:21 +00:00
return style
}
},
2019-01-22 12:54:21 +00:00
watch: {
imageUrl () {
if (this.imageUrl) {
this.setImage(this.imageUrl)
}
},
},
mounted () {
this.setImage(this.imageUrl)
},
2019-01-18 13:33:13 +00:00
methods: {
2019-01-22 12:54:21 +00:00
setImage(url) {
if (url === null) { return }
this.loadImage(url)
.then(img => {
this.loadedImageUrl = img.src
this.$emit('imageLoaded', img)
})
.catch(err => {
this.$emit('imageLoadError', err)
})
},
},
2019-01-18 13:33:13 +00:00
}
</script>
<style lang="scss" scoped>
.background-image-loader {
position: relative;
width: 100%;
height: 100%;
}
.background {
2019-01-18 13:33:13 +00:00
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.background-img {
background-size: cover;
background-position: center center;
2019-01-22 12:54:21 +00:00
opacity: 1;
}
.background-default {
$shadow-opacity: .6;
2019-01-22 17:45:45 +00:00
$shadow-color: $color__neutral-100;
background:
linear-gradient(
to right,
2019-01-22 17:45:45 +00:00
rgba($shadow-color, $shadow-opacity),
rgba($shadow-color, 0) 20%,
rgba($shadow-color, 0) 80%,
rgba($shadow-color, $shadow-opacity)
),
linear-gradient(
to bottom,
2019-01-22 17:45:45 +00:00
rgba($shadow-color, $shadow-opacity),
rgba($shadow-color, 0) 20%,
rgba($shadow-color, 0) 80%,
rgba($shadow-color, $shadow-opacity)
),
linear-gradient(
to top,
$color__neutral-100,
2019-01-22 17:45:45 +00:00
$color__neutral-300
)
;
overflow: hidden;
}
.background-blur {
filter: blur(30px);
}
2019-01-22 12:54:21 +00:00
.fade {
$timing: .7;
2019-01-22 12:54:21 +00:00
&-enter-active {
transition: opacity 4s * $timing 1s * $timing ease-in;
2019-01-22 12:54:21 +00:00
}
&-leave-active {
transition: opacity 2s * $timing ease-out;
2019-01-22 12:54:21 +00:00
}
&-enter, &-leave-to {
opacity: 0;
}
2019-01-18 13:33:13 +00:00
}
.fade-fast {
$timing: 1;
&-enter-active {
transition: opacity 3s * $timing ease-in;
transition-delay: .2s;
}
&-enter {
opacity: 0;
}
}
2019-01-18 13:33:13 +00:00
</style>