<style type="text/css">

.ball {

  min-width: 15px;

  min-height: 15px;

  background-color: red;

  border-radius: 50%;

  transition: all 1s linear;

  z-index: 999;

}

.inner {

  /* width: 16px;

  height: 16px;

  border-radius: 50%;

  background-color: rgb(0, 160, 220);

  transition: all 1s linear; */

}

</style>

<template>

  <div id="app">

    <!-- <div class="btn" @click="drop($event)" v-for="(item, idx) in 6" :key="idx">

      加入购物车

    </div> -->

    <!-- 使用transition把元素小球包裹起来 -->

    <div class="flex_center">

      3252354353534534534523

      <div class="ball-container" style="position: relative">

        <div v-for="(ball, index) of balls" :key="index">

          <transition

            @before-enter="handleBeforeEnter"

            @enter="handleEnter"

            @after-enter="handleAfterEnter"

          >

            <div

              class="ball"

              :class="[`${'ball' + index}`]"

              style="position: fixed"

              v-show="ball.show"

              v-bind:css="false"

            >

              <!--外层盒子-->

              423

            </div>

          </transition>

        </div>

      </div>

    </div>

    <div class="flex_center">

      888888888888888888888888899993222222222222222222222222222222222222222222222222222222222222222222222222222222222999999999

      <div class="ballTo" id="ballTo" style="position: relative">到这来</div>

    </div>

    <div

      class="btn"

      @click="drop($event)"

      v-for="(item, idx) in 6"

      :key="item + 're'"

    >

      加入购物车

    </div>

  </div>

</template>

<script type="text/javascript">

export default {

  data() {

    return {

      flag: false,

      balls: [

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

        { show: false, active: false },

      ],

      dropBalls: [], // 用dropBalls来存放掉落的小球

    };

  },

  methods: {

    drop(el) {

      for (let i = 0; i < this.balls.length; i++) {

        // 遍历这5个小球

        let ball = this.balls[i];

        if (!ball.show) {

          // 当小球显示状态为隐藏时

          ball.show = true; // 将这个小球的显示状态设置为true

          ball.active = true;

          ball.el = el; // 将cartControl传过来的对象挂载到ball的el属性上

          this.dropBalls.push(ball); // 将这个小球放入到dropBalls数组中

          // console.log(this.balls, 55);

          return;

        }

      }

    },

    handleBeforeEnter: function (el) {

      let count = this.balls.length;

      let box = document.getElementsByClassName("ball-container")[0];

      //   侧边栏位置

      let leftBar = document.getElementsByClassName("scrollbar")[0];

      //   顶部侧边栏

      let navbar = document.getElementsByClassName("navbar")[0];

      if (!(navbar && navbar.clientHeight)) {

        navbar = {

          clientHeight: 0,

        };

      }

      box.style.top = "100px";

      box.style.left = "100px";

      while (count--) {

        let ball = this.balls[count];

        if (ball.show && ball.active) {

          let x = 0,

            y = 0;

          x =

            ball.el.x -

            box.offsetLeft -

            leftBar.offsetWidth -

            leftBar.offsetLeft;

          y = (ball.el.y || 0) - box.offsetTop - navbar.clientHeight;

          el.style.display = "";

          el.style.left = `${x}px`;

          el.style.top = `${y}px`;

          el.style.position = "absolute";

        }

        ball.active = false; // 重置小球的active状态

      }

    },

    // enter

    handleEnter: function (el, done) {

      let box = document.getElementsByClassName("ball-container")[0];

      let ballTo = document.getElementById("ballTo");

      /* eslint-disable no-unused-vars */

      // 触发浏览器重绘

      let rf = el.offsetHeight;

      this.$nextTick(() => {

        let x = 0,

          y = 0,

          z = 0;

        y = ballTo.offsetTop - box.offsetTop;

        x = ballTo.offsetLeft - box.offsetLeft;

        // 让动画效果异步执行,提高性能

        el.style.left = `${x}px`;

        el.style.top = `${y}px`;

        // el.style.animation = "drop 1s cubic-bezier(.1,-0.15,0,.42)";

        el.style.transition =

          "left .6s linear, top .6s cubic-bezier(.1,.7,.71,1.52)";

        // "left .6s linear, top .6s cubic-bezier(0.1, 1.21, 1, 1)";

        el.addEventListener("transitionend", done); // Vue为了知道过渡的完成,必须设置相应的事件监听器。它可以是transitionend或 animationend

      });

    },

    handleAfterEnter: function (el) {

      let ball = this.dropBalls.shift(); // 完成一次动画就删除一个dropBalls的小球

      // 结束的时候装金币的篮子放大一下

      let ballTo = document.getElementById("ballTo");

      ballTo.style.transform = "scale(1.2)";

      ballTo.style.webkitTransform = "scale(1.2)";

      ballTo.style.opacity = 0.7;

      ballTo.style.transition = "all .2s ease-in-out";

      ballTo.style.webkitTransition = "all .2s ease-in-out";

      // 结束的时候装金币的篮子缩小一下

      setTimeout(() => {

        ballTo.style.transform = "scale(1)";

        ballTo.style.opacity = 1;

        ballTo.style.webkitTransform = "scale(1)";

      }, 500);

      if (ball) {

        ball.show = false;

        el.style.display = "none";

      }

    },

  },

  mounted() {

    // setInterval(() => {

    //   this.drop({ x: Math.random(0, 1) * 700, y: Math.random(0, 1) * 900 });

    // }, 500);

  },

};

</script>

<style lang="less" scoped>

.btn {

  height: 80px;

}

.flex_center {

  display: flex;

  align-content: center;

}

</style>

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐