其他分享
首页 > 其他分享> > 技术难点总结

技术难点总结

作者:互联网

1.景深滚轮动画切换,参考:https://blog.csdn.net/weixin_30596343/article/details/97304484

<template>
  <div class="swiper-certify">
    <div @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" class="swiper-certif-list">
      <li
        v-for="(item,index) in swiperOption.equip"
        :key="index"
        :class="classRender[index]"
        @click="slideClick(classRender[index])"
        class="centerPosition"
      >
        <div class="equip">
          <div class="equip__bottom">
            <div :style="{backgroundImage:`url(${item.img})`}" class="equip__bottom-img" />
            <div class="equip__bottom-name">
              {{ item.name }}
            </div>
          </div>
        </div>
      </li>
    </div>
    <div @click="toLeft" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" class="left">
      <div class="left__img" />
    </div>
    <div @click="toRight" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" class="right">
      <div class="right__img" />
    </div>
  </div>
</template>

<script>


export default {
  props: {
    swiperOption: {
      type: Object
    }
  },
  data () {
    return {
      max: 0,
      index: 0,
      classCenter: "p4",
      classLeft: ['p2', 'p3'],
      classRight: ['p5', 'p6'],
      leftHide: "p0",
      rightHide: "p7",
      hideNum: "",
      classRender: [],
      timerT: null
    };
  },
  created () {
    this.equip = this.swiperOption.equip || [];
    this.max = this.equip.length;
    this.startIndex = this.swiperOption.startIndex || 0;
    this.hideNum = Math.floor((this.max - 5) / 2);
    this.change(0);
  },
  mounted () {
    this.init();
    this.timer = setInterval(() => {
      this.autoClick("p5");
    }, 5000);
  },
  beforeMount () {
    clearInterval(this.timer);
  },
  methods: {
    init () {
      if (this.max <= 5) {
        this.refresh();
      } else if (this.max > 5) {
        this.refresh();
      }
    },
    goDetail (e, url) {
      if (e === this.classCenter) {
        window.open(url);
      }
    },
    change (dir) {
      let index = this.index;
      index = index + dir;
      if (index < 0) {
        index = this.max - 1;
      }
      if (index >= this.max) {
        index = 0;
      }
      this.index = index;
      // 当前展示第 index 个
      this.refresh();
    },
    refresh () {
      const index = this.index;
      if (index < 0 || index >= this.max) {
        return;
      }
      // 因为只展示五个
      const arr = new Array(this.max);
      let left = index - 1;
      let right = index + 1;
      arr[index] = this.classCenter;
      let count = this.hideNum + 1; // 左右都需要减两次
      const classLeft = this.classLeft.slice(0);
      while (count >= 0) {
        if (left < 0) {
          left = this.max - 1;
        }
        if (classLeft.length >= 0) {
          arr[left] = classLeft.pop();
        } else {
          arr[left] = this.leftHide;
        }
        left--;
        count--;
      }
      count = this.hideNum + 1;
      const classRight = this.classRight.slice(0);
      while (count >= 0) {
        if (right >= this.max) {
          right = 0;
        }
        if (classRight.length) {
          arr[right] = classRight.shift();
        } else {
          arr[right] = this.rightHide;
        }
        right++;
        count--;
      }

      for (let i = 0; i < arr.length; i++) {
        if (!arr[i]) {
          arr[i] = this.rightHide;
        }
      }
      this.classRender = arr;
    },
    slideClick (cls) {
      if (cls === this.classLeft[1]) {
        // 左
        this.change(-1);
        this.$emit("change", this.index);
      } else if (cls === this.classLeft[0]) {
        this.change(-1);
        setTimeout(() => {
          this.change(-1);
        }, 100);
        this.$emit("change", this.index - 1);
      } else if (cls === this.classRight[0]) {
        // 右
        this.change(1);
        this.$emit("change", this.index);
      } else if (cls === this.classRight[1]) {
        this.change(1);
        setTimeout(() => {
          this.change(1);
        }, 100);
        this.$emit("change", this.index + 1);
      }
    },
    autoClick (cls) {
      if (cls === this.classLeft[1]) {
        // 左
        this.change(-1);
        this.$emit("change", this.index);
      } else if (cls === this.classLeft[0]) {
        this.change(-1);
        setTimeout(() => {
          this.change(-1);
        }, 100);
        this.$emit("change", this.index - 1);
      } else if (cls === this.classRight[0]) {
        // 右
        this.change(1);
        this.$emit("change", this.index);
      } else if (cls === this.classRight[1]) {
        this.change(1);
        setTimeout(() => {
          this.change(1);
        }, 100);
        this.$emit("change", this.index + 1);
      }
    },
    toLeft () {
      this.change(-1);
      this.$emit("change", this.index);
    },
    toRight () {
      this.change(1);
      this.$emit("change", this.index);
    },
    onm ouseEnter (e) {
      clearInterval(this.timer);
    },
    onm ouseLeave () {
      clearInterval(this.timer);
      this.timer = setInterval(() => {
        this.autoClick("p5");
      }, 5000);
    }
  }
};
</script>
<style lang="scss" scoped>
.swiper-certify {
  height: 400px;
  width: 100%;

  .centerPosition {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .swiper-certif-list {
    width: 100%;
    height: 100%;
    margin: auto;
    position: relative;

    li {
      width: 400px;
      position: absolute;
      transition: all 0.5s ease-out;
      cursor: pointer;

      .equip {
        width: 400px;
        height: 400px;
        background-size: cover;
        background-image: url("~@/assets/images/equip-bottom.png");

        &__bottom {
          padding: 43px 100px;

          &-img {
            width: 200px;
            height: 200px;
            background-size: cover;
            background-image: url("~@/assets/images/equip-02.png");
          }

          &-name {
            margin-top: 22px;
            font-family: pingfang SC, helvetica neue, arial, hiragino sans gb, microsoft yahei ui, microsoft yahei, simsun, sans-serif;
            font-size: 18px;
            color: #191919;
            text-align: center;
            line-height: 24px;
            font-weight: 700;
          }

          &-des {
            margin-top: 12px;
            font-family: pingfang SC, helvetica neue, arial, hiragino sans gb, microsoft yahei ui, microsoft yahei, simsun, sans-serif;
            font-size: 14px;
            color: #0a28e5;
            letter-spacing: 0;
            text-align: center;
            line-height: 20px;
            font-weight: 400;

            .go {
              margin-top: -20px;
              margin-left: 74px;
              transform: translateX(0);
              transition: all 0.5s ease-out;
            }
          }

          &-wait {
            margin-top: 12px;
            font-family: pingfang SC, helvetica neue, arial, hiragino sans gb, microsoft yahei ui, microsoft yahei, simsun, sans-serif;
            font-size: 14px;
            color: rgba(0, 0, 0, 0.3);
            letter-spacing: 0;
            text-align: center;
            line-height: 20px;
            font-weight: 400;
          }
        }
      }
    }
  }

  .left {
    position: absolute;
    left: 40px;
    top: 498px;
    width: 64px;
    height: 64px;
    padding: 20px;
    background: rgba(255, 255, 255, 0.5);
    border-radius: 50%;
    cursor: pointer;
    z-index: 2;

    &__img {
      width: 24px;
      height: 24px;
      opacity: 0.4;
      background-image: url("~@/assets/icons/arrow-left.svg");
    }

    &:hover {
      background: rgba(255, 255, 255, 0.9);

      .left__img {
        opacity: 0.7;
      }
    }
  }

  .right {
    position: absolute;
    top: 498px;
    right: 40px;
    width: 64px;
    height: 64px;
    padding: 20px;
    background: rgba(255, 255, 255, 0.5);
    border-radius: 50%;
    cursor: pointer;
    z-index: 2;

    &__img {
      width: 24px;
      height: 24px;
      opacity: 0.4;
      background-image: url("~@/assets/icons/arrow-right.svg");
    }

    &:hover {
      background: rgba(255, 255, 255, 0.9);

      .right__img {
        opacity: 0.7;
      }
    }
  }

  .p0 {
    opacity: 0;
    transform: translate3d(-202%, -59%, 0) scale(0.4);
    z-index: 0;
  }

  .p2 {
    opacity: 0.4;
    transform: translate3d(-202%, -59%, 0) scale(0.5625);
    z-index: 1;
  }

  .p3 {
    transform: translate3d(-137%, -54%, 0) scale(0.75);
    opacity: 0.7;
    z-index: 2;
  }

  .p4 {
    transform: translate3d(-50%, -50%, 0) scale(1);
    z-index: 3;
    opacity: 1;

    &:hover {
      .go {
        transform: translateX(8px) !important;
      }
    }
  }

  .p5 {
    transform: translate3d(37%, -54%, 0) scale(0.75);
    opacity: 0.7;
    z-index: 2;
  }

  .p6 {
    opacity: 0.4;
    transform: translate3d(102%, -59%, 0) scale(0.5625);
    z-index: 1;
  }

  .p7 {
    opacity: 0;
    transform: translate3d(102%, -59%, 0) scale(0.5625);
    z-index: 0;
  }
}
</style>

 

2.卡片切换,参考:https://blog.csdn.net/weixin_30596343/article/details/97304484

<template>
  <div class="swiper-certify">
    <div class="swiper-certif-list">
      <div class="label" />
      <li
        v-for="(item,index) in swiperOption.open"
        :key="index"
        :class="classRender[index]"
        @click="slideClick(classRender[index],swiperOption.open[index])"
        class="centerPosition"
      >
        
      </li>
    </div>
  </div>
</template>

<script>


export default {
  props: {
    swiperOption: {
      type: Object
    }
  },
  data () {
    return {
      currentIndex: 0,
      modelList: [
        {
          children: []
        }
      ],
      max: 3,
      index: 0,
      classCenter: "modelCenter",
      classLeft: "modelLeft",
      classRight: "modelRight",
      classRender: [],
      timerT: null,
      icon: require("@/assets/icons/arrow-point.svg")
    };
  },
  created () {
    this.change(0);
  },
  mounted () {
    this.$nextTick(() => {
      this.modelList = this.swiperOption.open[0].model;
    });
  },
  methods: {
    goPath (path) {

      window.open(path);
    },
    change (dir) {
      this.currentIndex = 0;
      let index = this.index;
      index = index + dir;
      if (index < 0) {
        index = this.max - 1;
      }
      if (index >= this.max) {
        index = 0;
      }
      this.index = index;

      // 当前展示第 index 个
      this.refresh();
      this.$emit("change", this.index);
    },
    refresh () {
      const index = this.index;
      if (index < 0 || index >= this.max) {
        return;
      }

      const arr = new Array(this.max);
      let left = index - 1;
      let right = index + 1;
      arr[index] = this.classCenter;
      if (left < 0) {
        left = this.max - 1;
      }
      arr[left] = this.classLeft;
      if (right === this.max) {
        right = 0;
      }
      arr[right] = this.classRight;
      this.classRender = arr;
    },
    slideClick (cls, list) {
      this.modelList = list.model;
      if (cls == this.classLeft) {
        // 左
        this.change(-1);
      }
      if (cls == this.classRight) {
        // 右
        this.change(1);
      }
    },
    modelChange (e, list) {
      this.currentIndex = e;
      this.modelList = list;
    }

  }
};
</script>
<style lang="scss" scoped>
.swiper-certify {
  height: 100%;
  width: 100%;

  .swiper-certif-list {
    position: relative;
    width: 1520px;
    height: 100%;
    margin: auto;
    padding-top: 114px;

    .title {
      font-family: Microsoft YaHei;
      font-size: 36px;
      color: #000;
      letter-spacing: 0;
      text-align: center;
      font-weight: 400;
    }

    .des {
      margin-top: 20px;
      font-family: Microsoft YaHei;
      font-size: 16px;
      color: #000;
      letter-spacing: 0;
      text-align: center;
      font-weight: 400;
    }

    .label {
      position: absolute;
      width: 254px;
      height: 84px;
      left: 50%;
      top: 62px;
      background-image: url("~@/assets/images/open-label.png");
      background-size: cover;
      transform: translateX(-50%);
    }

    li {
      position: absolute;
      transition: all 0.5s ease-out;

      .imgs {
        width: 100%;
        height: 100%;
        display: block;
        box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.16);
        border-radius: 16px;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }

  @media screen and (max-width: 1600px) {
    .swiper-certif-list {
      width: 1242px !important;
    }
  }

  .centerPosition {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);

    .inner {
      position: relative;
      width: 100%;
      height: 522px;
      overflow: hidden;
      background-size: 992px 822px;
      padding: 0 0 64px 0;
      box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.12), 0 4px 24px -8px rgba(0, 0, 0, 0.24);
      border-radius: 16px;

      &__title {
        margin-top: 32px;
        font-family: Microsoft YaHei;
        font-size: 20px;
        color: #000;
        letter-spacing: 0;
        text-align: center;
        font-weight: 400;
        transition: all 0.5s ease-out;
        transform: translateY(280px);
      }

      .flag {
        position: relative;
        display: block;
        margin: auto;
        opacity: 1;
        transition: all 0.5s ease-out;
        transform: translateY(277px);

        &__title {
          position: relative;
          font-family: Microsoft YaHei;
          font-size: 20px;
          color: #000;
          letter-spacing: 0;
          text-align: center;
          font-weight: 400;
        }

        &__des {
          position: relative;
          margin: 9px auto 0 auto;
          font-family: Microsoft YaHei;
          font-size: 14px;
          color: #4c4c4c;
          letter-spacing: 0;
          text-align: center;
          line-height: 20px;
          font-weight: 400;
          transition: all 0.5s ease-out;
        }
      }

      &__button {
        margin: 0 auto 0 auto;
        display: flex;
        justify-content: center;
        opacity: 0;
        transform: translateY(293px);
        transition: all 0.5s ease-out;
        cursor: pointer;

        &-item {
          min-width: 108px;
          height: 48px;
          margin-right: 14px;
          padding: 12px 22px;
          font-family: Microsoft YaHei;
          font-size: 16px;
          color: #4c4c4c;
          letter-spacing: 0;
          text-align: center;
          line-height: 24px;
          font-weight: 400;

          &:hover {
            background: rgba(255, 255, 255, 0.5);
            border-radius: 24px;
            color: #006734;
          }
        }

        &-point {
          min-width: 108px;
          height: 48px;
          margin-right: 14px;
          padding: 12px 22px;
          font-family: Microsoft YaHei;
          font-size: 16px;
          color: #000;
          letter-spacing: 0;
          text-align: center;
          line-height: 24px;
          font-weight: 400;
          opacity: 0.7;

          img {
            transform: translate(0, 2px);
            transition: transform 0.2s ease-in-out;
          }

          &:hover {
            opacity: 0.9;
            color: #000;

            img {
              transform: translate(4px, -2px);
            }
          }
        }

        .check {
          color: #006734;
          background: #fff;
          border-radius: 24px;
        }
      }

      &__model {
        position: relative;
        display: flex;
        justify-content: center;
        margin: 40px auto 0 auto;

        &-block {
          position: relative;
          width: 222px;
          height: 288px;
          margin-left: 8px;
          padding: 4px;
          background: rgba(255, 255, 255, 0.4);
          border: 0 solid rgba(255, 255, 255, 0.6);
          transform: translateY(50%) scale(0.01);
          transition: all 0.1s ease-out;
          cursor: pointer;

          .content {
            position: relative;
            width: 214px;
            height: 280px;
            padding: 24px 16px;
            background: #fff;
            text-align: center;

            .shading {
              position: absolute;
              width: 67px;
              height: 65px;
              top: 215px;
              right: 0;
              background-image: url("~@/assets/images/open-shading.png");
              background-size: cover;
              opacity: 0;
              transition: all 0.3s ease-out;
            }

            .img {
              width: 48px;
              height: 48px;
              margin: auto;
              background-size: cover;
            }

            .title {
              margin-top: 12px;
              font-family: Microsoft YaHei-Bold;
              font-size: 14px;
              color: #191919;
              letter-spacing: 0;
              text-align: center;
              line-height: 20px;
              font-weight: 700;
            }

            .des {
              margin: 8px auto 0 auto;
              font-family: Microsoft YaHei;
              font-size: 14px;
              color: #4c4c4c;
              letter-spacing: 0;
              text-align: justify;
              line-height: 20px;
              font-weight: 400;
            }

            .detail {
              position: absolute;
              width: 71px;
              left: 50%;
              top: 244px;
              font-family: Microsoft YaHei;
              font-size: 14px;
              color: #244cf5;
              letter-spacing: 0;
              text-align: center;
              line-height: 24px;
              font-weight: 400;
              transform: translateX(-50%);
              cursor: pointer;

              .go {
                margin-top: -24px;
                margin-left: 68px;
                transform: translateX(0);
                transition: all 0.5s ease-out;
              }
            }

            .wait {
              position: absolute;
              width: 71px;
              left: 50%;
              top: 244px;
              font-family: Microsoft YaHei;
              font-size: 14px;
              color: rgba(0, 0, 0, 0.4);
              letter-spacing: 0;
              text-align: center;
              line-height: 24px;
              font-weight: 400;
              transform: translateX(-50%);
            }

            &:hover {
              box-shadow: 0 6px 24px -8px rgba(0, 0, 0, 0.4);

              .shading {
                opacity: 1;
              }

              .go {
                transform: translateX(8px);
              }
            }
          }

          &:nth-child(1) {
            margin-left: 0;
          }
        }
      }
    }

    @media screen and (max-width: 1600px) {
      .inner__model-block {
        width: 190px;

        .content {
          width: 182px;
        }
      }
    }
  }

  .modelLeft {
    width: 280px;
    height: 440px;
    transform: translate3d(2px, -37%, 0);
    transform-origin: 0 50%;
    z-index: 1;
    cursor: pointer;

    .imgs {
      background-position: center;
      background-repeat: no-repeat;
    }

    .inner {
      height: 440px;
      background-position-x: -359px;
      transition: all 0.5s ease-out;
    }

    .flag {
      width: 200px;
    }
  }

  .modelCenter {
    width: 992px;
    height: 522px;
    transform: translate3d(268px, -37%, 0);
    transform-origin: 0 50%;
    z-index: 5;
    opacity: 1;
    background-position: top;

    .inner__model-block {
      transform: translateY(0%) scale(1);
      transition: all 0.7s ease-out;
    }

    .flag {
      transform: translateY(0) !important;
      opacity: 0 !important;
      transition: all 0.5s ease-out;
    }

    .inner__button {
      transform: translateY(0) !important;
      opacity: 1;
    }

    .inner__title {
      transform: translateY(0) !important;
    }

    .inner {
      background-position-y: -300px;
      transition: all 0.5s ease-out;
    }

    .margin64 {
      margin-top: 64px !important;
      margin-bottom: -32px !important;
    }
  }

  .modelRight {
    width: 280px;
    height: 440px;
    transform: translate3d(1247px, -37%, 0);
    cursor: pointer;
    z-index: 1;

    .imgs {
      background-position: center;
      background-repeat: no-repeat;
    }

    .inner {
      height: 440px;
      background-position-x: -359px;
      transition: all 0.5s ease-out;
    }

    .flag {
      width: 200px;
    }
  }

  @media screen and (max-width: 1600px) {
    .modelLeft {
      width: 216px;

      .flag {
        width: 152px !important;
      }

      .inner {
        background-position-x: -388px;
      }
    }

    .modelCenter {
      width: 832px;
      transform: translate3d(205px, -37%, 0);

      .inner {
        background-position-x: -80px;
      }
    }

    .modelRight {
      width: 216px;
      transform: translate3d(1023px, -37%, 0);

      .flag {
        width: 152px !important;
      }

      .inner {
        background-position-x: -388px;
      }
    }
  }
}
</style>

 


3.滚动动画

lineClick (nav) {
      this.tabIndex = nav;
      const ele = document.documentElement;
      this.lineTop = this.$parent.$el.querySelector(`#${this.requestData.ids[this.tabIndex]}`).offsetTop;
      const targetTop = this.lineTop;
      const step = Math.abs((ele.scrollTop - targetTop) / 15);
      const smoothDown = () => {
        if (ele.scrollTop < targetTop) {
          // console.log(100)
          if (ele.scrollTop + step < targetTop) {
            ele.scrollTop += step;
            if (ele.scrollTop === (ele.scrollHeight - ele.clientHeight) || ele.scrollTop + ele.clientHeight + 1 >= ele.scrollHeight) { cancelAnimationFrame(smoothDown); } else { requestAnimationFrame(smoothDown); }
          } else {
            ele.scrollTop = targetTop;
            cancelAnimationFrame(smoothDown);
          }
        }
      };
      const smoothUp = () => {
        if (ele.scrollTop > targetTop) {
          if (targetTop + step < ele.scrollTop) {
            ele.scrollTop -= step;
            requestAnimationFrame(smoothUp);
          } else {
            ele.scrollTop = targetTop;
            cancelAnimationFrame(smoothUp);
          }
        }
      };
      if (ele.scrollTop < targetTop) { smoothDown(); } else { smoothUp(); }
    }

 

4.图片压缩,图片裁切:lzr插件,vue-cropper插件(cropper.js)
5.雪碧图帧动画:参考https://gitee.com/larntin/d-sprite



mounted () {
    this.logo();
  },


methods: {

logo () { /* * obj:指定的父容器节点,其下运动对象是img * timespan: 动画播放,每一帧的时间间隔 * deltay:每一帧移动的高度 * maxHeight:图片的最大高度 */ const dsprite = (obj, timespan, deltay, maxHeight) => { // 获取 img 的 delta y const getCurDeltay = (obj) => { const img = obj.querySelector("img"); const _transform = img.style.transform; const reg = _transform.match(/\((.*?)px\)/); const deltay = parseInt(reg[1]) || 0; return deltay; }; // 设置 img 的 delta y const setCurDeltay = (obj, deltay) => { const img = obj.querySelector("img"); img.style.transform = `translateY(${deltay}px)`; }; let ani_time = null; const _maxHeight = maxHeight - deltay; let ani_diret = 1; // 1是正向,-1是反向 obj.addEventListener("mouseenter", (event) => { this.logoshow = false; // console.log("enter"); ani_diret = 1; if (!ani_time) { // 没有运行时间函数,就开始动画 // console.log("setup time"); ani_time = setInterval(() => { const _curY = getCurDeltay(obj); let newY = _curY - ani_diret * deltay; // console.log(`newY=${newY}`); if (newY <= -_maxHeight) { newY = -_maxHeight; setCurDeltay(obj, newY); } else if (newY >= 0) { newY = 0; setCurDeltay(obj, newY); if ((ani_diret === -1)) { clearInterval(ani_time); ani_time = null; } } else { setCurDeltay(obj, newY); } }, timespan); } }); obj.addEventListener("mouseleave", (event) => { if (ani_time) { this.logoshow = true; clearInterval(ani_time); ani_time = null; } }); }; const spr = document.querySelector(".header__top-spr"); dsprite(spr, 33, 40, 6000); } }

 

标签:总结,难点,index,技术,transform,height,width,font,change
来源: https://www.cnblogs.com/xiayihaoqing/p/16140031.html