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