Skip to content

Instantly share code, notes, and snippets.

@Jamiewarb
Last active October 23, 2018 09:27
Show Gist options
  • Save Jamiewarb/eb6f5069cc8674e1ddcfb1fe32fd9cc8 to your computer and use it in GitHub Desktop.
Save Jamiewarb/eb6f5069cc8674e1ddcfb1fe32fd9cc8 to your computer and use it in GitHub Desktop.
Vue x Lottie - animation controller
// This is an example of how we can use the above two files to add a background image to the case
// study animation data
<template>
<lottie
:class="classes"
:height="height"
:options="options"
class="v-cs-image"
@animCreated="setupAnimation"
/>
</template>
<script>
import LottieBase from './LottieBase.vue';
import * as harvardImageAnimData from '~/lottie-anims/harvard-cs-animation-data.json`;
import * as suuntoImageAnimData from '~/lottie-anims/suunto-cs-animation-data.json`;
export default {
name: CaseStudyImage,
extends: LottieBase,
props: {
client: {
type: String,
required: true,
validator(value) {
return [
// All available client names
'harvard',
'suunto',
].indexOf(value) !== -1;
}
},
},
data() {
return {
options: {
animationData: this.getAnimationData();
autoplay: false,
},
};
},
computed: {
classes() {
return {
[`v-cs-image--${this.client}`]: this.client,
};
},
},
methods: {
getAnimationData() {
switch (this.client) {
case 'harvard':
return harvardImageAnimData;
case 'suunto':
return suuntoImageAnimData;
default:
return null;
}
},
},
};
</script>
<style lang="scss">
$clients: (
'harvard': url('/path/to/file.jpg'),
'suunto': url('/path/to/file.jpg'),
);
.v-cs-image {
@each $client, $imageUrl in $clients {
&--#{$client} > svg > g > g { // This is an example of navigating the animation. This is not the correct styling
background-image: $imageUrl;
}
}
}
</style>
// This is the Animation Controller that wraps around lottie-web, to work with Vue.
<template>
<div
ref="lottieContainer"
:style="getStyles"
/>
</template>
<script>
import lottie from 'lottie-web'; // https://github.com/airbnb/lottie-web
export default {
props: {
center: {
type: Boolean,
default: true,
},
options: {
type: Object,
required: true,
},
height: {
type: String,
default: '100%',
},
width: {
type: String,
default: '100%',
},
},
computed: {
getStyles() {
const styles = {
width: this.width,
height: this.height,
overflow: 'hidden',
};
if (this.center) {
styles.margin = '0 auto';
}
return styles;
},
},
mounted() {
this.anim = lottie.loadAnimation({
container: this.$refs.lottieContainer,
renderer: 'svg',
loop: this.options.loop !== false,
autoplay: this.options.autoplay !== false,
animationData: this.options.animationData,
rendererSettings: this.options.rendererSettings,
});
this.$emit('animCreated', this.anim);
},
};
</script>
// This is the base Vue component that all other Lottie animations extend.
// It provides hooks into play/pause/segments and other functionality
<template>
<lottie
:center="center"
:height="height"
:options="options"
:width="width"
:style="styles"
class="v-lottie"
@animCreated="setupAnimation"
/>
</template>
<script>
import Lottie from './LottieAnimationController.vue';
export default {
name: 'LottieBase',
components: {
Lottie,
},
props: {
center: {
type: Boolean,
default: true,
},
height: {
type: String,
default: '100%',
},
width: {
type: String,
default: '100%',
},
},
data() {
return {
animationLoaded: false,
options: {
animationData: this.animationData,
},
};
},
methods: {
setupAnimation(anim) {
this.anim = anim;
this.anim.addEventListener('DOMLoaded', () => {
this.animationLoaded = true;
});
},
stop() {
this.anim.stop();
},
play() {
this.anim.play();
},
pause() {
this.anim.pause();
},
setSpeed(speed) {
this.anim.setSpeed(speed);
},
onSpeedChange() {
this.anim.setSpeed(this.animationSpeed);
},
getDuration(inFrames = false) {
return this.anim.getDuration(inFrames);
},
goToAndPlay(value, isFrame = false) {
this.anim.goToAndPlay(value, isFrame);
},
playSegments(segments, forceFlag) {
this.anim.playSegments(segments, forceFlag);
},
playOnce() {
this.play();
this.anim.loop = false;
this.anim.playCount = 1;
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment