Slider vue 3
Dec. 10, 2023, 7:20 a.m.
I added my simple slider using vue 3, that can switch image by mouse and finger touching. Also in this slider I use img
for display of pictures,which is most often semantically correct, unlike div
.
In this example I used typescript, script setup, module css.
<script setup lang="ts"> import { ref } from 'vue' import Img1 from './1.jpg' import Img2 from './2.jpg' import Img3 from './3.jpg' const slider = ref<HTMLElement | null>(null) const images = ref([Img3, Img1, Img2]) const current_index = ref(0) const position = ref(0) let is_dragging = false let prev_position = 0 let start_x = 0 const slideWidth = () => { return slider.value ? slider.value.offsetWidth : 0 } const startDragging = (e: MouseEvent | TouchEvent) => { e.preventDefault() is_dragging = true start_x = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX } const onDragging = (e: MouseEvent | TouchEvent) => { if (is_dragging) { const current_x = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX const diff = current_x - start_x position.value = prev_position + diff } } const endDragging = () => { is_dragging = false const moved_by = position.value - prev_position if (moved_by < -slideWidth() / 4 && current_index.value < images.value.length - 1) current_index.value += 1 if (moved_by > slideWidth() / 4 && current_index.value > 0) current_index.value -= 1 position.value = current_index.value * -slideWidth() prev_position = position.value } </script> <template> <div ref="slider" :class="$style.slider" @mousedown="startDragging" @touchstart="startDragging" @mouseup="endDragging" @touchend="endDragging" @mousemove="onDragging" @touchmove="onDragging"> <div :class="$style.slides" :style="{ transform: `translateX(${position}px)` }"> <img v-for="(image, index) in images" :key="index" :src="image" alt="slide" /> </div> </div> </template> <style lang="scss" module> .slider {overflow: hidden;position: relative;width: 100%;aspect-ratio: 5/3} .slides {display: flex;transition: transform 0.3s ease;height: 100%} .slides img {width: 100%;height: 100%;flex-shrink: 0;object-fit: cover;} </style>
Comments: 0