美文网首页
vue实现弧形轮播图,动态数据,固定元素个数

vue实现弧形轮播图,动态数据,固定元素个数

作者: Victor_818 | 来源:发表于2019-12-25 19:31 被阅读0次

    实现弧形轮播图,无论多少数据,都在固定的几个元素上切换,不影响渲染性能

    只考虑数据在六个以上,六个以下的需要自己考虑。

    <template>
      <div class="venue-wrap">
        <div class="nav-wrap">
          <span
            class="prev"
            @click="prevItem"
          ></span>
          <span
            class="next"
            @click="nextItem"
          ></span>
          <ul
            class="nav-list"
            ref="nav"
          >
            <li
              v-for="(item, index) in showData"
              :key="index"
              class="item"
              :class="'item'+index"
            >
              {{showData[index].name}}
            </li>
          </ul>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      components: {
    
      },
      props: {
    
      },
      data () {
        return {
          navList: [
            {
              name: '场馆1',
              id: 1
            },
            {
              name: '场馆2',
              id: 2
            },
            {
              name: '场馆3',
              id: 3
            },
            {
              name: '场馆4',
              id: 4
            },
            {
              name: '场馆5',
              id: 5
            },
            {
              name: '场馆6',
              id: 6
            },
            {
              name: '场馆7',
              id: 7
            },
            {
              name: '场馆8',
              id: 8
            },
            {
              name: '场馆9',
              id: 9
            },
            {
              name: '场馆10',
              id: 10
            }
          ],
          showData: [],
          positionArr: [],
          itemArr: [],
          num: 0,
          preActive: 6,
          nextActive: 0
        };
      },
      computed: {
    
      },
      created () {
    
      },
      mounted () {
        this.nextActive = this.navList.length;
        // this.navList = [...this.navList, ...this.navList];
        this.showData = Array.from(this.navList.filter((item, index) => {
          if (index < 6) {
            return item;
          }
        }));
        this.$nextTick(() => {
          this.init();
        });
      },
      watch: {
    
      },
      methods: {
        init () {
          this.positionArr = [];
          let oPic = this.$refs.nav;
          this.itemArr = oPic.getElementsByTagName('li');
          for (let i = 0; i < this.itemArr.length; i++) {
            this.positionArr.push([
              parseInt(this.getStyle(this.itemArr[i], 'left')),
              parseInt(this.getStyle(this.itemArr[i], 'top')),
              parseFloat(this.getStyle(this.itemArr[i], 'opacity')),
              this.itemArr[i].offsetWidth
            ]);
          }
        },
        getStyle (obj, name) {
          if (obj.currentStyle) {
            return obj.currentStyle[name];
          } else {
            return getComputedStyle(obj, false)[name];
          }
        },
        prevItem () {
          if (this.num === this.showData.length) {
            this.num = 0;
          }
          if (this.preActive === this.navList.length) {
            this.preActive = 0;
          }
          if (this.nextActive === this.navList.length) {
            this.nextActive = 0;
          }
          this.showData.splice(this.num, 1, this.navList[this.preActive]);
          this.num++;
          this.preActive++;
          this.nextActive++;
          this.$nextTick(() => {
            this.positionArr.unshift(this.positionArr[this.positionArr.length - 1]);
            this.positionArr.pop();
            for (let i = 0; i < this.itemArr.length; i++) {
              this.startMove(this.itemArr[i], {
                left: this.positionArr[i][0],
                top: this.positionArr[i][1],
                opacity: this.positionArr[i][2]
              });
            }
          });
        },
        nextItem () {
          if (this.num === 0) {
            this.num = this.showData.length;
          }
          if (this.nextActive === 0) {
            this.nextActive = this.navList.length;
          }
          if (this.preActive === 0) {
            this.preActive = this.navList.length;
          }
          this.num--;
          this.preActive--;
          this.nextActive--;
          this.showData.splice(this.num, 1, this.navList[this.nextActive]);
          this.$nextTick(() => {
            this.positionArr.push(this.positionArr[0]);
            this.positionArr.shift();
            for (let i = 0; i < this.itemArr.length; i++) {
              this.startMove(this.itemArr[i], {
                left: this.positionArr[i][0],
                top: this.positionArr[i][1],
                opacity: this.positionArr[i][2]
              });
            }
          });
        },
        startMove (obj, json) {
          for (let attr in json) {
            let cur = 0;
            if (attr === 'opacity') {
              cur = Math.round(parseFloat(this.getStyle(obj, attr)) * 100);
            } else {
              cur = parseInt(this.getStyle(obj, attr));
            }
            let speed = (json[attr] - cur);
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            if (attr === 'opacity') {
              obj.style.opacity = cur + speed;
            } else {
              obj.style[attr] = cur + speed + 'px';
            }
          }
        }
      }
    };
    </script>
    
    <style scoped lang="scss">
    $url: '~@/assets/images/importantEvent/';
    .venue-wrap {
      position: relative;
      z-index: 10;
      height: 100%;
      .nav-wrap {
        position: relative;
        height: 100%;
        padding-top: 268px;
        .prev,
        .next {
          position: absolute;
          width: 66px;
          height: 66px;
          top: 450px;
          background: rgba(0, 186, 255, 0.1);
          border-radius: 50%;
          background-repeat: no-repeat no-repeat;
          background-position: center center;
          border: 1px solid transparent;
          cursor: pointer;
          &:hover {
            border-color: #00baff;
          }
        }
        .prev {
          background-image: url($url+'home/icon_banner_left.png');
          left: 150px;
        }
        .next {
          background-image: url($url+'home/icon_banner_right.png');
          right: 150px;
        }
        .nav-list {
          position: relative;
          width: 1202px;
          height: 100%;
          margin: 0 auto;
          overflow: hidden;
        }
        .item {
          position: absolute;
          width: 263px;
          height: 324px;
          background-image: url($url+'venueSecurity/border_out.png');
          background-repeat: no-repeat no-repeat;
          background-size: 100% 100%;
          transition: all 0.5s;
          left: -313px;
          top: 424px;
          opacity: 0;
          &.item0 {
            left: -313px;
            top: 424px;
            opacity: 0;
          }
          &.item1 {
            left: 0;
            top: 82px;
            opacity: 1;
          }
          &.item2 {
            left: 313px;
            top: 0;
            opacity: 1;
          }
          &.item3 {
            left: 626px;
            top: 0;
            opacity: 1;
          }
          &.item4 {
            left: 939px;
            top: 82px;
            opacity: 1;
          }
          &.item5 {
            left: 1252px;
            top: 424px;
            opacity: 0;
          }
        }
      }
    }
    </style>
    
    

    相关文章

      网友评论

          本文标题:vue实现弧形轮播图,动态数据,固定元素个数

          本文链接:https://www.haomeiwen.com/subject/dzqhoctx.html