background
In the project, the commonly used animation scheme for loading is Gif animation.
There are some problems with Gif animation, such as: large file size, inability to scale to match different screen sizes and densities, prone to aliasing, inability to control animation, etc.
Other commonly used animation schemes are:
- Png sequence frames: large file size, may be distorted on different screen resolutions
- SVG animation: high implementation cost, prone to low animation restoration
At present, the project needs to be investigated, and Lottie animation is a highly feasible solution.
Introduction to Lottie
Lottie is an open source animation library of airbnb, which supports multiple platforms such as Android, iOS, Web, React Native and Windows. It provides a complete tool flow from AE to each terminal. Designers can export animations through AE's Bodymovin plug-in json 文件
, and then through Lottie 实现动画效果
, 确保动画的还原度
.
lottie实现的动画效果:
lottie-web
lottie-web supports a variety of features and provides complex animation control and monitoring functions.
An example of use is as follows:
lottie.loadAnimation({
container: animationWindow,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'https://linwu-hi.github.io/lottie/animation_ll2ddfyg.json'
});
How to control animation playback:
name | describe |
---|---|
animation.play | Play the animation, starting from the currently stopped frame |
stop | Stop playing the animation and go back to frame 0 |
pause | Pauses the animation, stopping at the current frame and holding |
goToAndStop | animation.goToAndStop(value, isFrame); Jump to a certain moment/frame and stop. isFrame (default false) indicates whether value represents frame or time (milliseconds) |
goToAndPlay | animation.goToAndPlay(value, isFrame); Jump to a certain moment/frame and play it |
goToAndStop | animation.goToAndStop(30, true); Jump to frame 30 and stop |
playSegments | animation.playSegments(arr, forceFlag); arr can contain two numbers or an array of two numbers, forceFlag indicates whether to force the segment to be played immediately animation.playSegments([10,20], false); after playing the previous segment, Play 10-20 frames animation.playSegments([[0,5],[10,18]], true); directly play 0-5 frames and 10-18 frames |
setSpeed | animation.setSpeed(speed); set the playback speed, speed is 1 means normal speed |
setDirection | animation.setDirection(direction); Set the playback direction, 1 means forward playback, -1 means reverse playback |
destroy | animation.destroy(); Delete the animation, remove the corresponding element label, etc. When unmounting, this method needs to be called |
Listen for events:
name | describe |
---|---|
data_ready | After loading the json animation |
complete | The playback is complete (it will not be triggered under loop playback) |
loopComplete | Triggered when the current loop playback (loop playback/non-loop playback) ends |
enterFrame | It will be triggered every time a frame is entered, every frame will be triggered during playback, and the stop method will also be triggered |
segmentStart | It will be triggered every time a frame is entered, every frame will be triggered during playback, and the stop method will also be triggered |
DOMLoaded | Triggered after animation-related dom has been added to html |
destroy | will fire when the animation is removed |
Lottie animation performance
Comparing Lottie and Gif animations, the data shows that Lottie animations have smaller files, higher frame rates, and better performance.
- GIF animation
- LottieAnimation
react-lottie
react-lottie encapsulates lottie-web into a React component, making it easier to use in React.
import React from 'react'
import Lottie from 'react-lottie';
import * as animationData from './pinjump.json'
export default class LottieControl extends React.Component {
constructor(props) {
super(props);
this.state = {isStopped: false, isPaused: false};
}
render() {
const buttonStyle = {
display: 'block',
margin: '10px auto'
};
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
};
return <div>
<Lottie options={defaultOptions}
height={400}
width={400}
isStopped={this.state.isStopped}
isPaused={this.state.isPaused}/>
<button style={buttonStyle} onClick={() => this.setState({isStopped: true})}>stop</button>
<button style={buttonStyle} onClick={() => this.setState({isStopped: false})}>play</button>
<button style={buttonStyle} onClick={() => this.setState({isPaused: !this.state.isPaused})}>pause</button>
</div>
}
}
view-lottie
vue-lottie encapsulates lottie-web into a vue component, making it easier to use in vue.
also havevue3-lottie
<template>
<div id="app">
<lottie :options="defaultOptions" :height="400" :width="400" v-on:animCreated="handleAnimation"/>
<div>
<p>Speed: x{{animationSpeed}}</p>
<input type="range" value="1" min="0" max="3" step="0.5"
v-on:change="onSpeedChange" v-model="animationSpeed">
</div>
<button v-on:click="stop">stop</button>
<button v-on:click="pause">pause</button>
<button v-on:click="play">play</button>
</div>
</template>
<script>
import Lottie from './lottie.vue';
import * as animationData from './assets/pinjump.json';
export default {
name: 'app',
components: {
'lottie': Lottie
},
data() {
return {
defaultOptions: {animationData: animationData},
animationSpeed: 1
}
},
methods: {
handleAnimation: function (anim) {
this.anim = anim;
},
stop: function () {
this.anim.stop();
},
play: function () {
this.anim.play();
},
pause: function () {
this.anim.pause();
},
onSpeedChange: function () {
this.anim.setSpeed(this.animationSpeed);
}
}
}
</script>