Prepare sliders, need to be fully completed and tested

This commit is contained in:
2025-11-28 14:27:45 +01:00
parent 283a1a4b4d
commit 2c470625a7
16 changed files with 1375 additions and 10 deletions

View File

@@ -0,0 +1,158 @@
<template>
<div class="vue3-slider-double">
<div
class="slider-bar"
:style="'left: ' + ( posLeft ) + 'px; width: '
+ ( 200 - posRight - posLeft ) + 'px;'
+ 'background-color: ' + $props[ 'barColor' ] + ';'"
></div>
<div
:style="'left: ' + ( posLeft - 5 ) + 'px;'
+ 'background-color: ' + $props[ 'barColor' ] + ';'"
class="slider-knob"
>
<div
:class="'drag-support' + ( isDraggingLeft ? ' dragging' : '' )"
@mousedown="( e ) => { startMove( e.screenX, 'left' ) }"
@mousemove="( e ) => { handleMove( e.screenX ) }"
@mouseup="() => endMove()"
@touchmove="( ev ) => { handleMove( ev.touches[ 0 ]!.screenX ) }"
@touchstart="( ev ) => { startMove( ev.touches[ 0 ]!.screenX, 'left' ) }"
@touchend="() => { endMove() }"
></div>
</div>
<div
:style="'right: ' + ( posRight - 5 ) + 'px;'
+ 'background-color: ' + $props[ 'barColor' ] + ';'"
class="slider-knob"
>
<div
:class="'drag-support' + ( isDraggingRight ? ' dragging' : '' )"
@mousedown="( e ) => { startMove( e.screenX, 'right' ) }"
@mousemove="( e ) => { handleMove( e.screenX ) }"
@mouseup="() => { endMove() }"
@touchmove="( e ) => { handleMove( e.touches[ 0 ]!.screenX ) }"
@touchstart="( e ) => { startMove( e.touches[ 0 ]!.screenX, 'right' ) }"
@touchend="() => { endMove() }"
></div>
</div>
</div>
</template>
<script setup lang="ts">
import {
ref
} from 'vue';
const isDraggingLeft = ref( false );
const isDraggingRight = ref( false );
const posLeft = ref( 0 );
let originalPosLeft = 0;
const posRight = ref( 0 );
let originalPosRight = 0;
const currentlyMoving = ref( '' );
let offset = 0;
const emits = defineEmits( [ 'interval' ] );
const startMove = ( x: number, slider: string ) => {
currentlyMoving.value = slider;
offset = x;
if ( slider === 'left' ) {
isDraggingLeft.value = true;
} else if ( slider === 'right' ) {
isDraggingRight.value = true;
}
};
const handleMove = ( x: number ) => {
if ( currentlyMoving.value === 'right' ) {
if ( originalPosRight - x + offset >= 0 && originalPosRight - x + offset < 200 - originalPosLeft - 20 ) {
posRight.value = originalPosRight - x + offset;
} else if ( originalPosRight - x + offset <= 0 ) {
posRight.value = 0;
} else {
posRight.value = 200 - originalPosLeft - 20;
}
emits( 'interval', [
posLeft.value / 2,
( 200 - posRight.value ) / 2
] );
} else if ( currentlyMoving.value === 'left' ) {
if ( x - offset + originalPosLeft >= 0 && x - offset + originalPosLeft < 200 - originalPosRight - 20 ) {
posLeft.value = x - offset + originalPosLeft;
} else if ( x - offset + originalPosLeft <= 0 ) {
posLeft.value = 0;
} else {
posLeft.value = 200 - originalPosRight - 20;
}
emits( 'interval', [
posLeft.value / 2,
( 200 - posRight.value ) / 2
] );
}
};
const endMove = () => {
currentlyMoving.value = '';
isDraggingLeft.value = false;
isDraggingRight.value = false;
originalPosLeft = posLeft.value;
originalPosRight = posRight.value;
};
defineProps<{
'handleColor': string,
'barColor': string
}>();
</script>
<style scoped>
.vue3-slider-double {
position: relative;
width: 200px;
height: 10px;
border: black solid 1px;
border-radius: 50px;
}
.vue3-slider-double .slider-knob {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50px;
top: -5px;
}
.vue3-slider-double .drag-support {
width: 100%;
height: 100%;
border-radius: 50px;
background: none;
cursor: pointer;
}
.vue3-slider-double .drag-support.dragging {
position: fixed;
cursor: move;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
}
.vue3-slider-double .slider-bar {
position: absolute;
background-color: var( --hover-color );
height: 10px;
}
</style>