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

  1. Animation by design using professional animation tools AE to achieve, make animation more convenient, and better effect
  2. The front end can easily call animation, and animation control, reduce the front-end animation workload
  3. Design animation, front-end display animation, clear division of labor
  4. Using the Lottie scheme, JSON files are much smaller than GIF files and perform better

Lottie – The use of Web on the front end

  1. Lottie – web installation
npm install lottie-web
Copy the code
  1. 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
  1. 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

  1. Use vite to run vue
npm init @vitejs/app <project-name>
Copy the code
  1. Lottie – web installation
npm install lottie-web
Copy the code
  1. Encapsulates an underlying componentlottie.vueThe 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
  1. Based on the above component, we encapsulate a more concrete componentclickIcon, 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 onelikecomponentlike.vueAs 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.

  1. uselikecomponent
<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