大屏手写table轮播表(vue)

文件下载:https://download.csdn.net/download/zluz_/86406404

作为components组件引入进来,使用:

<Scroll
  v-if="peopleConfigData.length > 0"
  :is-hover="true"
  :list="peopleConfigData"
  :time-space="3000"
  :show-count="5"
  :length="peopleConfigData.length"
  :interval-time="2000"
  class="table-item"
>
  <div v-for="(i, index) in peopleConfigData" :key="index" class="flex-ac">
    <div
      style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 1%;"
    >
      <div class="info-name">{{ i.name }}</div>
      <div>{{ i.value }}%</div>
    </div>
    <el-progress :percentage="i.value" :show-text="false" />
  </div>
</Scroll>
<template>
  <div
    ref="banner"
    :class="`banner ${className}`"
    @mouseenter="mouseenterFunc"
    @mouseleave="mouseleaveFunc"
  >
    <div ref="originDom" class="originDom">
      <div
        v-for="n in repeatTime"
        ref="originDomItem"
        :key="n"
        class="originDomItem"
      >
        <slot />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    // 是否反向
    reverse: {
      type: [Boolean],
      default: function() {
        return false
      }
    },

    // 偏移的百分比
    offsetPrecent: {
      type: [Number],
      default: function() {
        return 10
      }
    },

    // 滚动模式,单条或者整页,可选值为 item 或者 page
    mode: {
      type: [String],
      default: function() {
        return 'item'
      }
    },

    // 动画的持续时间,ms为单位
    transitionDuration: {
      type: [Number],
      default: function() {
        return 500
      }
    },

    // 单条动画之间的间隔时间
    animationInterval: {
      type: [Number],

      default: function() {
        return 100
      }
    },

    // 轮播的间隔时间,ms为单位
    intervalTime: {
      type: [Number],
      default: function() {
        return 3000
      }
    },

    // 显示的条数
    showCount: {
      type: [Number],
      default: function() {
        return 10
      }
    },

    // 鼠标悬停的时候是否暂停
    hoverPause: {
      type: [Boolean],
      default: function() {
        return true
      }
    },

    // 起始模糊程度
    startBlur: {
      type: [Number],
      default: function() {
        return 0
      }
    },

    // 结束模糊程度
    endBlur: {
      type: [Number],
      default: function() {
        return (0 * window.innerHeight) / 1440
      }
    },

    // 起始透明度
    startOpacity: {
      type: [Number],
      default: function() {
        return 1
      }
    },

    // 结束透明度
    endOpacity: {
      type: [Number],
      default: function() {
        return 1
      }
    },

    // 类名
    className: {
      type: [String],
      default: function() {
        return ''
      }
    },

    // 是否使用复制模式,即传入的数据小于等于要显示的条数的时候,自动复制
    repeat: {
      type: [Boolean],
      default: function() {
        return false
      }
    }
  },

  data: function() {
    return {
      msg: 'banner',
      enable: true,
      childrenDom: [],
      repeatTime: 1,
      active: 0,
      originLength: 0,
      timer: 0,
      alive: true
    }
  },

  methods: {
    mouseenterFunc() {
      /* eslint-disable */
      this.hoverPause && (this.enable = false);
    },

    mouseleaveFunc() {
      /* eslint-disable */
      this.hoverPause && (this.enable = true);
    },

    computeChildrenDom() {
      return new Promise((resolve) => {
        // console.log(this.$refs.originDomItem[0].children)
        console.log(this.$refs.originDomItem[0].children.length)
        if (this.$refs.originDomItem[0].children.length) {
          let origin = [...this.$refs.originDomItem[0].children];
          // console.log('origin', origin)
          this.originLength = origin.length;

          let repeatTime = 1;

          if (!this.repeat && this.childrenDom.length < this.showCount) {
            console.log();
          } else {
            while (repeatTime * this.originLength < this.showCount + 2) {
              repeatTime = repeatTime + 1;
            }
          }

          this.repeatTime = repeatTime;

          this.childrenDom = [];

          this.$nextTick(() => {
            let list = [...this.$refs.originDomItem];

            list.forEach((item) => {
              [...item.children].forEach((dom) => {
                dom.style.position = "absolute";

                dom.style.transition = `all ${this.transitionDuration / 1000}s`;

                dom.style.width = "100%";

                dom.style.opacity = 1;

                this.childrenDom.push(dom);
              });
            });

            resolve();
          });
        }
      });
    },

    computeContainerHeight() {
      if (!this.childrenDom.length) {
        return false;
      }
      let sum = 0;
      for (let i = 0; i < this.showCount; i++) {
        let index = (this.active + i) % this.childrenDom.length;
        sum = sum + this.childrenDom[index].offsetHeight;
      }

      /* eslint-disable */
      this.$refs.banner && (this.$refs.banner.style.height = `${sum}px`);
    },

    computeItemStyle() {
      if (!this.childrenDom.length) {
        return false;
      }

      if (!this.repeat && this.childrenDom.length < this.showCount + 1) {
        let sum = 0;

        this.childrenDom.forEach((item, index) => {
          item.style.top = `${sum}px`;

          item.style.left = 0;

          item.style.opacity =
            this.startOpacity +
            ((this.endOpacity - this.startOpacity) /
              (this.childrenDom.length - 1)) *
              index;

          item.style.filter = `blur(${
            this.startBlur +
            ((this.endBlur - this.startBlur) / (this.childrenDom.length - 1)) *
              index
          }px)`;

          sum = sum + this.childrenDom[index].offsetHeight;
        });
      } else {
        // 当使用非重复模式,并且 当前的数据数量 < 显示条数 + 1

        let sum = 0;

        let indexList = [];

        let prevIndex =
          (this.active + this.childrenDom.length - 1) % this.childrenDom.length;

        let prev = this.childrenDom[prevIndex];

        prev.style.top = 0;

        prev.style[this.reverse ? "left" : "right"] = `${
          (this.offsetPrecent / 100) * this.$refs.banner.offsetWidth
        }px`;

        prev.style.opacity = 0;

        prev.style.pointerEvents = "none";

        indexList.push(prevIndex);

        for (let i = 0; i < this.showCount; i++) {
          setTimeout(() => {
            let index = (this.active + i) % this.childrenDom.length;

            indexList.push(index);

            this.childrenDom[index].style.top = `${sum}px`;

            this.childrenDom[index].style[this.reverse ? "left" : "right"] = 0;

            this.childrenDom[index].style.pointerEvents = "auto";

            if (this.showCount > 1) {
              // console.log(this.startOpacity + (this.endOpacity - this.startOpacity) / (this.showCount - 1) * i)

              this.childrenDom[index].style.opacity =
                this.startOpacity +
                ((this.endOpacity - this.startOpacity) / (this.showCount - 1)) *
                  i;

              this.childrenDom[index].style.filter = `blur(${
                this.startBlur +
                ((this.endBlur - this.startBlur) / (this.showCount - 1)) * i
              }px)`;
            } else {
              console.log(this.startOpacity);

              this.childrenDom[index].style.opacity = this.startOpacity;

              this.childrenDom[
                index
              ].style.filter = `blur(${this.startBlur}px)`;
            }

            sum = sum + this.childrenDom[index].offsetHeight;
          }, this.animationInterval * (i + 1));
        }

        setTimeout(() => {
          for (let i = 0; i < this.childrenDom.length; i++) {
            if (indexList.indexOf(i) < 0) {
              this.childrenDom[i].style[this.reverse ? "left" : "right"] = 0;

              this.childrenDom[i].style.top = `${sum}px`;

              this.childrenDom[i].style.opacity = 0;

              this.childrenDom[i].style.pointerEvents = "none";
            }
          }
        }, this.showCount * this.animationInterval);
      }
    },

    animationFrame() {
      window.requestAnimationFrame(() => {
        if (this.enable) {
          this.timer = this.timer + 1000 / 60;

          if (this.timer > this.intervalTime) {
            this.timer = 0;

            this.active = (this.active + 1) % this.childrenDom.length;

            this.$emit("changeActive", this.active % this.originLength);

            this.computeContainerHeight();

            this.computeItemStyle();
          }
        }

        /* eslint-disable */

        this.alive && this.animationFrame();
      });
    },

    init() {
      setTimeout(() => {
        this.computeChildrenDom().then(() => {
          this.computeContainerHeight();

          this.computeItemStyle();
        });
      }, 0);
    },
  },

  mounted() {
    this.alive = true;
    /* eslint-disable */
    this.intervalTime !== 0 && this.animationFrame();
    this.init()
  },

  watch: {
    // activeIndex: function (newVal) {
    //     this.$emit('changeActive', (newVal + 1) % this.children.length)
    // }
  },

  beforeUpdate() {},

  beforeDestroy() {
    this.alive = false;
  },
};
</script>
 
<style lang="scss" scoped>
.banner {
  position: relative;

  overflow: visible;

  .originDom {
    .originDomItem {
      > * {
        opacity: 0;
      }
    }
  }
}
</style>
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值