Search code examples
javascriptvue.jslottie

generate animations randomly on button click in vue.js


I have three lottie player json animation files - congratulations1.json, congratulations2.json and congratulations3.json The animations are as follows:

congratulations1:

<lottie-player
          v-if="showPlayer1"
          class="justify-content-center"
          src="../../../congratulations.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;

congratulations2:

<lottie-player
          v-if="showPlayer2"
          class="justify-content-center"
          src="../../../congratulations2.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;

congratulations3:

<lottie-player
          v-if="showPlayer3"
          class="justify-content-center"
          src="../../../congratulations3.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;

Note: The path of the json files are mentioned in src in those lottie-player tag.

I want to display them randomly when a single button is clicked.

Things I have done:

I have taken three variables for each of those three animations. Variables are - showPlayer1, showPlayer2 and showPlayer3. I have kept them inside an array named showPlayer and set their values as false. I dont know if my procedure is correct or not. What to do next I have no idea.

My array:

<script>
export default {
  data() {
    return {
      showPlayer: [
        (showPlayer1 = false),
        (showPlayer2 = false),
        (showPlayer3 = false),
      ],
    };
  },

I have done upto this. What to include inside the button tag to display those three animations randomly from an array, I have no idea. Please help.

Updated code:

<div class="justify-content-center anim">
        <lottie-player
          v-if="showPlayer === 1"
          class="justify-content-center"
          src="../../../congratulations.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;
      </div>
      <div class="justify-content-center anim">
        <lottie-player
          v-if="showPlayer === 2"
          class="justify-content-center"
          src="../../../congratulations_2.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;
      </div>
      <div class="justify-content-center anim">
        <lottie-player
          v-if="showPlayer === 3"
          class="justify-content-center"
          src="../../../congratulations_3.json"
          background="transparent"
          speed="1"
          style="width: 300px; height: 300px"
          loop
          controls
          autoplay
        ></lottie-player
        >;
      </div>

Solution

  • As I've shown below there are serveral other ways to achieve this. But if you want to do it like you suggest I would not use showPlayer as an array of boolean but rather as a number.

    <template>
    <div v-if="showPlayer === 1"> DIV 1 </div>
    <div v-if="showPlayer === 2"> DIV 3 </div>
    <div v-if="showPlayer === 3"> DIV 3 </div>
    <button @click="onRandomButtonPress">Random!</button>
    </template>
    <script>
    export default {
      data() {
        return {
          showPlayer: 1
        };
      },
    methods: {
    onRandomButtonPress() {
      this.showPlayer = Math.floor(Math.random()*3 + 1);
    },
    }
    </script>
    

    There are multiple ways to deal with this. If you only want to use one component and toggle the source you can do something like this: First, set the src of your components to a variable:

    <lottie-player
              class="justify-content-center"
              :src="animationSrc"
              background="transparent"
              speed="1"
              style="width: 300px; height: 300px"
              loop
              controls
              autoplay
            ></lottie-player
            >;
    

    Set an array with the strings you have in your data() like this:

      animations: [
        '../../../congratulations.json',
        '../../../congratulations2.json',
        '../../../congratulations3.json',
      ],
      animationSrc: ''
    

    Then set a methon for the randomButton like this:

    onRandomButtonPress() {
      this.animationSrc = this.animations[Math.floor(Math.random()*this.animations.length)];
    },
    

    I have hacked a codesandbox together real quick: https://codesandbox.io/s/elastic-dijkstra-o7ety?file=/src/components/HelloWorld.vue

    You can also use the :is attribute in vue to load a dynamic component and set in code which component you want to be loaded. https://v2.vuejs.org/v2/guide/components-dynamic-async.html