基于vue实现滑块动画效果
主要实现:通过鼠标移移动、触摸元素、鼠标释放、离开元素事件来进行触发创建了一个滑动盒子,其中包含一个滑块图片。通过鼠标按下或触摸开始事件,开始跟踪滑块的位置和鼠标/触摸位置之间的偏移量。然后,通过计算偏移量和起始时的位移值,设置滑动盒子的 transform 属性来实现滑动效果。使用 transition 属性,还可以为滑块添加滑动动画。
·
主要实现:通过鼠标移移动、触摸元素、鼠标释放、离开元素事件来进行触发
创建了一个滑动盒子,其中包含一个滑块图片。通过鼠标按下或触摸开始事件,开始跟踪滑块的位置和鼠标/触摸位置之间的偏移量。然后,通过计算偏移量和起始时的位移值,设置滑动盒子的 transform 属性来实现滑动效果。使用 transition 属性,还可以为滑块添加滑动动画。
效果:
运行效果图
<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>
更多推荐
已为社区贡献7条内容
所有评论(0)