This is the third article I’ve been involved with getting started
preface
I have written an article about JsDoc that front-end people need to know. If you want to leave a comment, you would like to add more details about JsDoc. However, after writing some, I felt that some of the content added in the back was dull and boring, and it was like a document. After thinking about it, students should find the JsDoc document by themselves, which would be more appropriate. Today let’s take a look at Lottie, an interesting library of animations.
Lottie profile
Lottie is a library that resolves animations made with AE (export to JSON with BodyMovie) for web, ios, Android, Flutter and React Native. On the Web side, the Lottie-Web library can parse the exported animated JSON file and draw the animation on our page in SVG or canvas mode.
The advantages of Lottie
- Animation by design using professional animation tools AE to achieve, make animation more convenient, and better effect
- The front end can easily call animation, and animation control, reduce the front-end animation workload
- Design animation, front-end display animation, clear division of labor
- Using the Lottie scheme, JSON files are much smaller than GIF files and perform better
Lottie – The use of Web on the front end
- Lottie – web installation
npm install lottie-web
Copy the code
- Lottie – Basic use of web
const animation = lottie.loadAnimation({
container: document.getElementById('domId'), // Bind the DOM node
renderer: 'svg'.// Rendering mode: SVG, Canvas
loop: true.// Whether to loop. Default: false
autoplay: true.// Whether to play automatically. Default: true
animationData: // After Effects animation is exported as JSON data using BodyMovie
})
Copy the code
- Lottie – A common approach to Web
We have already initialized a Lottie object. Then we will introduce some common methods of it
animation.play(); // Play, starting from the current frame
animation.stop(); // Stop and go back to frame 0
animation.pause(); // Pause and hold the current frame
animation.goToAndStop(value, isFrame); // Skip to a time/frame and stop isFrame(default false) indicating whether value represents a frame or a time (milliseconds)
animation.goToAndPlay(value, isFrame); // Skip to a moment/frame and play
animation.goToAndStop(30.true); // Jump to frame 30 and stop
animation.goToAndPlay(300); // Jump to the 300th millisecond and play
animation.playSegments(arr, forceFlag); // Arr can contain two digits or an array of two digits. ForceFlag indicates whether to force the segment to play immediately
animation.playSegments([10.20].false); // After playing the previous clip, play 10-20 frames
animation.playSegments([[0.5], [10.18]], true); // Play frames 0-5 and 10-18 directly
animation.setSpeed(speed); // Set the playback speed. Speed 1 indicates the normal speed
animation.setDirection(direction); // Set the playback direction. 1 indicates forward playback and -1 indicates reverse playback
animation.destroy(); // Delete the animation, remove the corresponding element tag, etc.
Copy the code
Lottie- A common web event
animation.addEventListener('data_ready'.() = > {}) // The animation data is loaded
animation.addEventListener('config_ready'.() = > {}) // After the initial configuration
animation.addEventListener('data_failed'.() = > {}) // Failed to load animation data
animation.addEventListener('loaded_images'.() = > {}) // All images loaded successfully or failed
animation.addEventListener('DOMLoaded'.() = > {}) // After the element is added to the DOM
Copy the code
Lottie’s free resource
Earlier we said that Lottie’s animations were made after Effects and exported to JSON format using BodyMovie. In fact, there is a website that provides some free (and paid) animations directly with the json data we need for animations.
In the following GIF, we find the animation we want, and then click after the popup window, click download, the format is JSON. Then we can use the json data of the animation in our own project.
After introducing its usage, we are now going to do a real combat in vue
Use Lottie in VUE
- Use vite to run vue
npm init @vitejs/app <project-name>
Copy the code
- Lottie – web installation
npm install lottie-web
Copy the code
- Encapsulates an underlying component
lottie.vue
The main thing is to initialize Lottie objects and then pass them to other components
<template>
<div :style="style" ref="lavContainer"></div>
</template>
<script>
import lottie from 'lottie-web'
export default {
name: 'lottie'.props: {
options: {
type: Object.required: true,},height: Number.width: Number,},computed: {
style() {
return {
width: this.width ? `The ${this.width}px` : '100%'.height: this.height ? `The ${this.height}px` : '100%',}}},mounted() {
this.anim = lottie.loadAnimation({
container: this.$refs.lavContainer,
renderer: 'svg'.loop: this.options.loop ! = =false.autoplay: this.options.autoplay ! = =false.animationData: this.options.animationData,
})
this.$emit('animCreated'.this.anim)
},
unmounted () {
this.anim && this.anim.destroy()
}
}
</script>
Copy the code
- Based on the above component, we encapsulate a more concrete component
clickIcon
, this component is also a generic component, adding logic such as how the animation interaction needs to go after a click.
<template>
<div class="clickIcon">
<div
class="iconBox"
:style="{ width: width + 'px', height: height + 'px' }"
>
<slot name="svg" v-bind:data="{ toggle, flag, iconWidth, iconHeight }"></slot>
<lottie
@click="toggle"
:class="{ show: flag === true || ! defaultSlot }"
class="like"
style="display: none;"
:options="options"
:height="height"
:width="width"
v-on:animCreated="handleAnimation"
/>
</div>
</div>
</template>
<script>
import { computed, ref, defineComponent } from "vue";
import Lottie from "./lottie.vue";
let anim = null
/** * Click the icon and play an animation component * suitable for collecting, liking and other small functions */
export default defineComponent({
name: "clickIcon".props: {
/ / width
width: {
type: Number.default: 100,},/ / height
height: {
type: Number.default: 100,},// Initialize the parameters required by Lottie
options: {
type: Object.default: () = >{},},// Whether a slot is required to display a default icon
defaultSlot: {
type: Boolean.default: true
},
// The desired interaction after a click is passed from the outside
toggleFun: {
type: Function.default: null}},components: {
lottie: Lottie,
},
emits: ['init'].setup(props, { emit }) {
// Animation speed
const animationSpeed = 2
// Click the interactive logo
let flag = ref(false);
// Icon height
const iconWidth = computed(() = > {
return props.width;
});
// Icon width
const iconHeight = computed(() = > {
return props.height;
});
// Click the icon to interact
const toggle = function() {
if(! props.defaultSlot) { props.toggleFun && props.toggleFun(anim) }else{ flag.value = ! flag.value;if (flag.value) {
anim.play();
} else{ anim.stop(); }}};// Get the anim object
const handleAnimation = function(animated) {
anim = animated;
onSpeedChange()
emit('init', animated)
}
// Stop the animation
const stop = function() {
anim.stop();
}
// Play the animation
const play = function() {
anim.play();
}
// Pause the animation
const pause = function() {
anim.pause();
}
// Control the playback speed
const onSpeedChange = function() {
anim.setSpeed(animationSpeed);
}
return{ iconWidth, iconHeight, handleAnimation, flag, toggle, stop, play, pause }; }});</script>
<style scoped>
.iconBox {
position: relative;
}
.show {
display: inline-block ! important;
}
.hidden {
display: none ! important;
}
.like {
cursor: pointer;
}
.icon {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
Copy the code
So let’s write onelike
componentlike.vue
As we saw earlierPut the downloaded animated JSON file into the resource file directory, and then call it with code.
<template>
<lottie
class="like"
:options="defaultOptions"
:height="height"
:defaultSlot="false"
:width="width"
@init="init"
:toggleFun="toggle"
ref="lottie"
>
</lottie>
</template>
<script>
import Lottie from ".. /common/clickIcon.vue";
import animationData from "/public/like.json";
export default {
name: "app".components: {
lottie: Lottie,
},
props: {
width: {
type: Number.default: 60,},height: {
type: Number.default: 60,}},methods: {
init (animation) {
animation && animation.goToAndStop(0.true)
},
toggle (animation) {
if (this.toggleFlag) {
animation.playSegments([50.90].true); // Play from frame 50 to the end
} else {
animation && animation.playSegments([0.50].true); // Play from frame 0 to frame 50
}
this.toggleFlag = !this.toggleFlag
}
},
data() {
return {
toggleFlag: false.defaultOptions: {
name: "like".animationData: animationData,
autoplay: false.loop: false,}}; }};</script>
<style scoped>
.hidden {
display: none;
}
</style>
Copy the code
The above effect is done because the JSON file we downloaded for the ‘like’ animation is made up of two states: 0-50 frames are from unchecked to selected, and 50->90 frames are from selected to unchecked. The exact number of frames can be seen in the progress window below the download JSON file from the website.
- use
like
component
<template>
<div id="app">
<like></like>
</div>
</template>
<script>
import { defineComponent } from "vue";
import like from "./components/like/index.vue";
export default defineComponent({
components: {
like,
},
});
Copy the code
The specific effects are as follows
conclusion
So that’s implementing a favorite component in VUE with Lottie. In fact, I just wrote such a demo, if you are interested, you can implement it again, now the component is not to record the default state of the component, it may be selected by default. And this time we get the animation component is selected and not just selected two kinds of state, before to introduce the animation json file download site containing some animation is only to a selected animation effects, no not selected state, then we can find a similar SVG icon, and then as the default icon, When clicked, the selected animation effect is triggered. If it’s a corporate project, you can ask the artist to do two state animations. If it’s a personal project, and you come across a free animation that you like, but it only provides one state, then it’s useful. I’ve actually taken this into account for the component by setting defaultSlot to true and then adding a slot as a default component when writing to the component.
Write in the last
Can we give a thumbs up to encourage MOE new? Hahaha, thanks in advance