主要实现:通过鼠标移移动、触摸元素、鼠标释放、离开元素事件来进行触发

创建了一个滑动盒子,其中包含一个滑块图片。通过鼠标按下或触摸开始事件,开始跟踪滑块的位置和鼠标/触摸位置之间的偏移量。然后,通过计算偏移量和起始时的位移值,设置滑动盒子的 transform 属性来实现滑动效果。使用 transition 属性,还可以为滑块添加滑动动画。

效果:

基于vue实现滑块动画效果_ide


运行效果图


<template>
  <div id="app">
    <div class="slider-container img">
      <div class="slider-track">
        <img class="slider-handle" src="./assets/dot.svg" alt="滑块">
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
  },
  data(){
    return {
      sliderContainer:'',
      sliderTrack:'',
      sliderHandle:'',
      isDragging:false,
      startPosY:0,
      startTranslateY:0,
      minTranslateY:0,
      maxTranslateY:0,
    }
  },
  created() {

  },
  mounted() {
    this.sliderContainer = document.querySelector('.slider-container');
    this.sliderTrack = document.querySelector('.slider-track');
    this.sliderHandle = document.querySelector('.slider-handle');

    this.isDragging = false;
    this.startPosY = 0;
    this.startTranslateY = 0;
    this.minTranslateY = 0; // 顶部限制为30px,css样式修改后默认为0
    this.maxTranslateY = this.sliderContainer.clientHeight - this.sliderHandle.offsetHeight - 20; // 底部限制为20px

    this.sliderHandle.addEventListener('mousedown', this.startDrag);
    this.sliderHandle.addEventListener('touchstart', this.startDrag);
  },
  methods: {
    startDrag(event) {
      event.preventDefault();

      if (event.type === 'mousedown') {
        this.startPosY = event.clientY;
      } else if (event.type === 'touchstart') {
        this.startPosY = event.touches[0].clientY;
      }

      this.startTranslateY = this.getTranslateY();
      this.isDragging = true;

      document.addEventListener('mousemove', this.drag);
      document.addEventListener('touchmove', this.drag);
      document.addEventListener('mouseup', this.stopDrag);
      document.addEventListener('touchend', this.stopDrag);
    },
    drag(event) {
      if (!this.isDragging) return;

      var currentPosY = 0;

      if (event.type === 'mousemove') {
        currentPosY = event.clientY;
      } else if (event.type === 'touchmove') {
        currentPosY = event.touches[0].clientY;
      }

      var offsetY = currentPosY - this.startPosY;
      var translateY = this.startTranslateY + offsetY;

      // 边缘限制
      if (translateY < this.minTranslateY) {
        translateY = this.minTranslateY;
      } else if (translateY > this.maxTranslateY) {
        translateY = this.maxTranslateY;
      }

      this.setTranslateY(translateY);
    },
    stopDrag() {
      this.isDragging = false;

      document.removeEventListener('mousemove', this.drag);
      document.removeEventListener('touchmove', this.drag);
      document.removeEventListener('mouseup', this.stopDrag);
      document.removeEventListener('touchend', this.stopDrag);
    },

    getTranslateY() {
      var style = window.getComputedStyle(this.sliderTrack);
      var transform = style.transform || style.webkitTransform;
      var matrix = transform.match(/^matrix\((.+)\)$/);

      if (matrix) {
        return parseFloat(matrix[1].split(', ')[5]); // 获取Y轴位移值
      } else {
        return 0;
      }
    },
    setTranslateY(translateY) {
      let y = translateY
      if (y > 30 && y < 60) {
        console.log("午间");
        y = 60
      } else if (y > 60 && y < 90 ) {
        console.log("午间");
        y = 60
      } else if (y > 90 && y <= 130) {
        console.log("晚间");
        y = 120
      } else if (y < 30) {
        console.log("早间");
        y = 0
      }
      this.sliderTrack.style.transform = 'translate3d(0, ' + y + 'px, 0)'; // 设置Y轴位移值
    }

  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}

.img {
  width: 100px;
  height: 200px;
  background-color: antiquewhite;
  background: url("./assets/TimeOfDay.svg") no-repeat;
  background-size: contain;
  position: relative;
  transition: all 0.5s;
}

.hk_img {
  position: absolute;
  top: 30px;
}

.slider-container {
  width: 100px;
  height: 200px;
  overflow: hidden;
  position: relative;
  background-color: #f0f0f0;
}

.slider-track {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 0.3s ease-out;
  touch-action: none;
  /* 禁用默认的滑动行为 */
}

.slider-handle {
  width: 50px;
  height: 50px;
  position: absolute;
  top: 15px;
  /* 距离顶部30px */
  left: 50%;
  transform: translateX(-50%);
}

.slider-handle:hover {
  cursor: pointer;
}</style>