Prepare sliders, need to be fully completed and tested
This commit is contained in:
158
src/components/DoubleSlider.vue
Normal file
158
src/components/DoubleSlider.vue
Normal 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>
|
||||
Reference in New Issue
Block a user