27 개발 실패한 컴포넌트 - range (결국 Vuetify 활용 - 단 IE에서 작동하는지 봐야됨)
source: categories/study/vue-experiance/vue-experiance_9-17.md
27. 개발 실패한 컴포넌트 - range (결국 Vuetify 활용 - 단 IE에서 작동하는지 봐야됨)
실패 코드 (어렵다..)
<template>
<div>
<input type="text" :value="left">
<br/>
<br/>
<br/>
<div class="range_area" >
<div class="stick" ref="Stick"></div>
<div class="point left" ref="PointLeft" @mousedown="mouseDownLeft"></div>
<div class="between_stick" ref="BetweenStick"></div>
<div class="point right" ref="PointRight" @mousedown="mouseDownRight"></div>
</div>
<br/>
<br/>
<br/>
<input type="text" :value="right">
</div>
</template>
<script>
export default {
name: "RangeSlider",
data() {
return {
min: -100,
max: 100,
left: -10,
right: 10,
acc: 0.05,
leftToRight: false,
rightToLeft: false,
clientX: null,
// value: 0,
// reqAni: null,
// nowLeftPosition: 0,
// nowRightPosition: 0,
// nowCursor: 0,
}
},
mounted() {
const left = Math.round((this.left - this.min) * 100 / (Math.abs(this.min) + Math.abs(this.max)));
const right = Math.round((this.right - this.min) * 100 / (Math.abs(this.min) + Math.abs(this.max)));
this.$refs.PointLeft.style.left = `${left}%`;
this.$refs.PointRight.style.left = `${right}%`;
this.$refs.BetweenStick.style.left = `${left}%`;
this.$refs.BetweenStick.style.right = `${100 - right}%`;
window.addEventListener('mouseup', this.mouseUp);
// this.nowLeftPosition = parseInt(this.$refs.PointLeft.style.left) * this.$refs.Stick.getBoundingClientRect().width / 100;
// this.nowRightPosition = parseInt(this.$refs.PointRight.style.left) * this.$refs.Stick.getBoundingClientRect().width / 100;
},
beforeDestroy() {
window.removeEventListener('mouseup', this.mouseUp);
},
methods: {
// moveLeft() {
// this.nowLeftPosition = this.nowLeftPosition + (this.nowCursor - this.nowLeftPosition) * 0.1;
// this.$refs.PointLeft.style.left = `${this.nowLeftPosition * 100 / this.$refs.Stick.getBoundingClientRect().width}%`;
// if (Math.abs(this.nowCursor - this.nowLeftPosition) < 1) return;
// this.reqAni = requestAnimationFrame(this.moveLeft);
// },
// moveRight() {
// this.nowRightPosition = this.nowRightPosition + (this.nowCursor - this.nowRightPosition) * 0.1;
// this.$refs.PointRight.style.left = `${this.nowRightPosition * 100 / this.$refs.Stick.getBoundingClientRect().width}%`;
// if (Math.abs(this.nowCursor - this.nowRightPosition) < 1) return;
// this.reqAni = requestAnimationFrame(this.moveRight);
// },
onMouseDragLeft({clientX}) {
if (this.stopEvent) return;
const eventRangeLeft = this.$refs.Stick.getBoundingClientRect().left;
const eventRangeRight = eventRangeLeft + this.$refs.Stick.getBoundingClientRect().width;
if (clientX < eventRangeLeft || clientX > eventRangeRight) {
if (clientX < eventRangeLeft) {
this.$refs.PointLeft.style.left = '0%';
this.$refs.BetweenStick.style.left = '0%';
this.left = this.min;
} else {
this.$refs.PointLeft.style.left = '100%';
this.$refs.BetweenStick.style.right = '0%';
this.right = this.max;
}
return;
}
// this.clientX = clientX;
// this.nowCursor = this.clientX - this.$refs.Stick.getBoundingClientRect().left;
// cancelAnimationFrame(this.reqAni);
// this.moveLeft();
const value = (clientX - eventRangeLeft) * 100 / (eventRangeRight - eventRangeLeft);
this.$refs.PointLeft.style.left = `${value}%`
const inputValue = Math.round(value * 200 / 100 + this.min);
if (this.$refs.PointLeft.getBoundingClientRect().left < this.$refs.PointRight.getBoundingClientRect().left) {
if (this.leftToRight) {
this.right = this.left;
this.$refs.BetweenStick.style.right = `${100 - ((this.left - this.min) * 100 / (this.max - this.min))}%`;
this.leftToRight = false;
}
this.$refs.BetweenStick.style.left = `${value}%`;
this.left = inputValue;
} else {
if (!this.leftToRight) {
this.left = this.right;
this.$refs.BetweenStick.style.left = `${(this.right - this.min) * 100 / (this.max - this.min)}%`;
this.leftToRight = true;
}
this.$refs.BetweenStick.style.right = `${100 - value}%`;
this.right = inputValue;
}
},
onMouseDragRight({clientX}) {
const eventRangeLeft = this.$refs.Stick.getBoundingClientRect().left;
const eventRangeRight = eventRangeLeft + this.$refs.Stick.getBoundingClientRect().width;
if (clientX < eventRangeLeft || clientX > eventRangeRight) {
if (clientX < eventRangeLeft) {
this.$refs.PointRight.style.left = '0%';
this.$refs.BetweenStick.style.left = '0%';
this.left = this.min;
} else {
this.$refs.PointRight.style.left = '100%';
this.$refs.BetweenStick.style.right = '0%';
this.right = this.max;
}
return;
}
// this.clientX = clientX;
// this.nowCursor = this.clientX - this.$refs.Stick.getBoundingClientRect().left;
// cancelAnimationFrame(this.reqAni);
// this.moveRight();
const value = (clientX - eventRangeLeft) * 100 / (eventRangeRight - eventRangeLeft);
this.$refs.PointRight.style.left = `${value}%`
const inputValue = Math.round(value * 200 / 100 + this.min);
if (this.$refs.PointRight.getBoundingClientRect().left > this.$refs.PointLeft.getBoundingClientRect().left) {
if (this.rightToLeft) {
this.left = this.right;
this.$refs.BetweenStick.style.left = `${(this.right - this.min) * 100 / (this.max - this.min)}%`;
this.rightToLeft = false;
}
this.$refs.BetweenStick.style.right = `${100 - value}%`;
this.right = inputValue;
} else {
if (!this.rightToLeft) {
this.right = this.left;
this.$refs.BetweenStick.style.right = `${100 - ((this.left - this.min) * 100 / (this.max - this.min))}%`;
this.rightToLeft = true;
}
this.$refs.BetweenStick.style.left = `${value}%`;
this.left = inputValue;
}
},
mouseDownLeft() {
window.addEventListener('mousemove', this.onMouseDragLeft);
},
mouseDownRight() {
window.addEventListener('mousemove', this.onMouseDragRight);
},
mouseUp() {
window.removeEventListener('mousemove', this.onMouseDragLeft);
window.removeEventListener('mousemove', this.onMouseDragRight);
}
}
}
</script>
<style scoped>
.range_area {
position: relative;
user-select: none;
}
.stick {
height: 5px;
background-color: #959494;
}
.point {
position: absolute;
top: 50%;
left: 0;
z-index: 100;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #1A1A1A;
transform: translate(-50%, -50%);
cursor: pointer;
}
.point.right {
left: 100%;
}
.between_stick {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: #1A1A1A;
}
</style>