Implemented ColorPicker

pull/146/head
cagataycivici 2020-01-13 11:43:29 +03:00
parent d97f647988
commit 5c3fe243c3
2 changed files with 72 additions and 43 deletions

View File

@ -1,17 +1,17 @@
<template> <template>
<div :class="containerClass"> <div :class="containerClass">
<input ref="input" type="text" :class="inputClass" :style="inputStyle" readonly="readonly" :tabindex="tabindex" :disabled="disabled" <input ref="input" type="text" :class="inputClass" readonly="readonly" :tabindex="tabindex" :disabled="disabled"
@click="onInputClick" @keydown="onInputKeydown" v-if="!inline"/> @click="onInputClick" @keydown="onInputKeydown" v-if="!inline"/>
<transition name="p-input-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-input-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div ref="picker" :class="pickerClass" v-if="inline ? true : overlayVisible"> <div ref="picker" :class="pickerClass" v-if="inline ? true : overlayVisible">
<div class="p-colorpicker-content"> <div class="p-colorpicker-content">
<div ref="colorSelector" class="p-colorpicker-color-selector" @mousedown="onColorMousedown" :style="colorSelectorStyle"> <div ref="colorSelector" class="p-colorpicker-color-selector" @mousedown="onColorMousedown">
<div class="p-colorpicker-color"> <div class="p-colorpicker-color">
<div ref="colorHandle" class="p-colorpicker-color-handle" :style="colorHandleStyle"></div> <div ref="colorHandle" class="p-colorpicker-color-handle"></div>
</div> </div>
</div> </div>
<div ref="hueView" class="p-colorpicker-hue" @mousedown="onHueMousedown"> <div ref="hueView" class="p-colorpicker-hue" @mousedown="onHueMousedown">
<div ref="hueHandle" class="p-colorpicker-hue-handle" :style="hueHandleStyle"></div> <div ref="hueHandle" class="p-colorpicker-hue-handle"></div>
</div> </div>
</div> </div>
</div> </div>
@ -62,16 +62,34 @@ export default {
overlayVisible: false overlayVisible: false
}; };
}, },
hsbValue: null,
outsideClickListener: null, outsideClickListener: null,
documentMouseMoveListener: null, documentMouseMoveListener: null,
documentMouseUpListener: null, documentMouseUpListener: null,
hueDragging: null, hueDragging: null,
colorDragging: null, colorDragging: null,
selfUpdate: null,
beforeDestroy() { beforeDestroy() {
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
this.unbindDocumentMouseMoveListener(); this.unbindDocumentMouseMoveListener();
this.unbindDocumentMouseUpListener(); this.unbindDocumentMouseUpListener();
}, },
mounted() {
this.updateUI();
},
watch: {
value: {
immediate: true,
handler(newValue) {
this.hsbValue = this.toHSB(newValue);
if (this.selfUpdate)
this.selfUpdate = false;
else
this.updateUI();
}
}
},
methods: { methods: {
pickColor(event) { pickColor(event) {
let rect = this.$refs.colorSelector.getBoundingClientRect(); let rect = this.$refs.colorSelector.getBoundingClientRect();
@ -79,36 +97,42 @@ export default {
let left = rect.left + document.body.scrollLeft; let left = rect.left + document.body.scrollLeft;
let saturation = Math.floor(100 * (Math.max(0, Math.min(150, (event.pageX - left)))) / 150); let saturation = Math.floor(100 * (Math.max(0, Math.min(150, (event.pageX - left)))) / 150);
let brightness = Math.floor(100 * (150 - Math.max(0, Math.min(150, (event.pageY - top)))) / 150); let brightness = Math.floor(100 * (150 - Math.max(0, Math.min(150, (event.pageY - top)))) / 150);
let newHSBValue = this.validateHSB({ this.hsbValue = this.validateHSB({
h: this.hsbValue.h, h: this.hsbValue.h,
s: saturation, s: saturation,
b: brightness b: brightness
}); });
this.updateModel(newHSBValue); this.selfUpdate = true;
this.updateColorHandle();
this.updateInput();
this.updateModel();
}, },
pickHue(event) { pickHue(event) {
let top = this.$refs.hueView.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0); let top = this.$refs.hueView.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
let hsbValue = this.validateHSB({ this.hsbValue = this.validateHSB({
h: Math.floor(360 * (150 - Math.max(0, Math.min(150, (event.pageY - top)))) / 150), h: Math.floor(360 * (150 - Math.max(0, Math.min(150, (event.pageY - top)))) / 150),
s: 100, s: 100,
b: 100 b: 100
}); });
this.updateModel(hsbValue); this.selfUpdate = true;
this.updateColorSelector();
this.updateHue();
this.updateModel();
}, },
updateModel(value) { updateModel() {
switch(this.format) { switch(this.format) {
case 'hex': case 'hex':
this.$emit('input', this.HSBtoHEX(value)); this.$emit('input', this.HSBtoHEX(this.hsbValue));
break; break;
case 'rgb': case 'rgb':
this.$emit('input', this.HSBtoRGB(value)); this.$emit('input', this.HSBtoRGB(this.hsbValue));
break; break;
case 'hsb': case 'hsb':
this.$emit('input', value); this.$emit('input', this.hsbValue);
break; break;
default: default:
@ -116,6 +140,38 @@ export default {
break; break;
} }
}, },
updateColorSelector() {
if (this.$refs.colorSelector) {
let hsbValue = this.validateHSB({
h: this.hsbValue.h,
s: 100,
b: 100
});
this.$refs.colorSelector.style.backgroundColor = '#' + this.HSBtoHEX(hsbValue);
}
},
updateColorHandle() {
if (this.$refs.colorHandle) {
this.$refs.colorHandle.style.left = Math.floor(150 * this.hsbValue.s / 100) + 'px';
this.$refs.colorHandle.style.top = Math.floor(150 * (100 - this.hsbValue.b) / 100) + 'px';
}
},
updateHue() {
if (this.$refs.hueHandle) {
this.$refs.hueHandle.style.top = Math.floor(150 - (150 * this.hsbValue.h / 360)) + 'px';
}
},
updateInput() {
if (this.$refs.input) {
this.$refs.input.style.backgroundColor = '#' + this.HSBtoHEX(this.hsbValue);
}
},
updateUI() {
this.updateHue();
this.updateColorHandle();
this.updateInput();
this.updateColorSelector();
},
validateHSB(hsb) { validateHSB(hsb) {
return { return {
h: Math.min(360, Math.max(0, hsb.h)), h: Math.min(360, Math.max(0, hsb.h)),
@ -257,6 +313,7 @@ export default {
return hsb; return hsb;
}, },
onOverlayEnter() { onOverlayEnter() {
this.updateUI();
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
@ -385,34 +442,6 @@ export default {
}, },
pickerClass() { pickerClass() {
return ['p-colorpicker-panel', {'p-colorpicker-overlay-panel': !this.inline, 'p-disabled': this.disabled}]; return ['p-colorpicker-panel', {'p-colorpicker-overlay-panel': !this.inline, 'p-disabled': this.disabled}];
},
inputStyle() {
return {backgroundColor: '#' + this.HSBtoHEX(this.hsbValue)};
},
colorHandleStyle() {
return {
left: Math.floor(150 * this.hsbValue.s / 100) + 'px',
top: Math.floor(150 * (100 - this.hsbValue.b) / 100) + 'px'
}
},
colorSelectorStyle() {
let hsbValue = this.validateHSB({
h: this.hsbValue.h,
s: 100,
b: 100
});
return {
backgroundColor: '#' + this.HSBtoHEX(hsbValue)
}
},
hueHandleStyle() {
return {
top: Math.floor(150 - (150 * this.hsbValue.h / 360)) + 'px'
}
},
hsbValue() {
return this.toHSB(this.value);
} }
} }
} }

View File

@ -9,10 +9,10 @@
<div class="content-section implementation"> <div class="content-section implementation">
<h3>Inline</h3> <h3>Inline</h3>
<ColorPicker v-model="color1" :inline="true" />{{color1}} <ColorPicker v-model="color1" :inline="true" />
<h3>Overlay</h3> <h3>Overlay</h3>
<ColorPicker v-model="color2" />{{color2}} <ColorPicker v-model="color2" />
</div> </div>
<ColorPickerDoc /> <ColorPickerDoc />