取色器bug fix
This commit is contained in:
parent
66da683c0f
commit
071c2b30fb
|
@ -28,13 +28,13 @@ export default defineComponent({
|
|||
Checkboard,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
value: {
|
||||
type: Object as PropType<ColorFormats.RGBA>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const color = computed(() => props.modelValue)
|
||||
const color = computed(() => props.value)
|
||||
const gradientColor = computed(() => {
|
||||
const rgbaStr = [color.value.r, color.value.g, color.value.b].join(',')
|
||||
return `linear-gradient(to right, rgba(${rgbaStr}, 0) 0%, rgba(${rgbaStr}, 1) 100%)`
|
||||
|
@ -54,7 +54,7 @@ export default defineComponent({
|
|||
else a = Math.round(left * 100 / containerWidth) / 100
|
||||
|
||||
if(color.value.a !== a) {
|
||||
emit('update:modelValue', {
|
||||
emit('change', {
|
||||
r: color.value.r,
|
||||
g: color.value.g,
|
||||
b: color.value.b,
|
||||
|
|
|
@ -15,7 +15,7 @@ import tinycolor, { ColorFormats } from 'tinycolor2'
|
|||
export default defineComponent({
|
||||
name: 'editable-input',
|
||||
props: {
|
||||
modelValue: {
|
||||
value: {
|
||||
type: Object as PropType<ColorFormats.RGBA>,
|
||||
required: true,
|
||||
},
|
||||
|
@ -23,14 +23,14 @@ export default defineComponent({
|
|||
setup(props, { emit }) {
|
||||
const val = computed(() => {
|
||||
let _hex = ''
|
||||
if(props.modelValue.a < 1) _hex = tinycolor(props.modelValue).toHex8String().toUpperCase()
|
||||
else _hex = tinycolor(props.modelValue).toHexString().toUpperCase()
|
||||
if(props.value.a < 1) _hex = tinycolor(props.value).toHex8String().toUpperCase()
|
||||
else _hex = tinycolor(props.value).toHexString().toUpperCase()
|
||||
return _hex.replace('#', '')
|
||||
})
|
||||
|
||||
const handleInput = (e: InputEvent) => {
|
||||
const value = (e.target as HTMLInputElement).value
|
||||
if(value.length >= 6) emit('update:modelValue', tinycolor(value).toRgb())
|
||||
if(value.length >= 6) emit('change', tinycolor(value).toRgb())
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -22,25 +22,33 @@ import tinycolor, { ColorFormats } from 'tinycolor2'
|
|||
export default defineComponent({
|
||||
name: 'hue',
|
||||
props: {
|
||||
modelValue: {
|
||||
value: {
|
||||
type: Object as PropType<ColorFormats.RGBA>,
|
||||
required: true,
|
||||
},
|
||||
hue: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const oldHue = ref(0)
|
||||
const pullDirection = ref('')
|
||||
|
||||
const color = computed(() => tinycolor(props.modelValue).toHsl())
|
||||
const color = computed(() => {
|
||||
const hsla = tinycolor(props.value).toHsl()
|
||||
if(hsla.s === 0) hsla.h = props.hue
|
||||
return hsla
|
||||
})
|
||||
|
||||
const pointerLeft = computed(() => {
|
||||
if(color.value.h === 0 && pullDirection.value === 'right') return '100%'
|
||||
return color.value.h * 100 / 360 + '%'
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
const hsl = tinycolor(props.modelValue).toHsl()
|
||||
const h = hsl.h
|
||||
watch(() => props.value, () => {
|
||||
const hsla = tinycolor(props.value).toHsl()
|
||||
const h = hsla.s === 0 ? props.hue : hsla.h
|
||||
if(h !== 0 && h - oldHue.value > 0) pullDirection.value = 'right'
|
||||
if(h !== 0 && h - oldHue.value < 0) pullDirection.value = 'left'
|
||||
oldHue.value = h
|
||||
|
@ -63,14 +71,12 @@ export default defineComponent({
|
|||
h = (360 * percent / 100)
|
||||
}
|
||||
if(color.value.h !== h) {
|
||||
const rgba = tinycolor({
|
||||
emit('change', {
|
||||
h,
|
||||
l: color.value.l,
|
||||
s: color.value.s,
|
||||
a: color.value.a,
|
||||
}).toRgb()
|
||||
|
||||
emit('update:modelValue', rgba)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,20 +27,28 @@ import clamp from 'lodash/clamp'
|
|||
export default defineComponent({
|
||||
name: 'saturation',
|
||||
props: {
|
||||
modelValue: {
|
||||
value: {
|
||||
type: Object as PropType<ColorFormats.RGBA>,
|
||||
required: true,
|
||||
},
|
||||
hue: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const color = computed(() => tinycolor(props.modelValue).toHsv())
|
||||
const color = computed(() => {
|
||||
const hsva = tinycolor(props.value).toHsv()
|
||||
if(hsva.s === 0) hsva.h = props.hue
|
||||
return hsva
|
||||
})
|
||||
|
||||
const bgColor = computed(() => `hsl(${color.value.h}, 100%, 50%)`)
|
||||
const pointerTop = computed(() => (-(color.value.v * 100) + 1) + 100 + '%')
|
||||
const pointerLeft = computed(() => color.value.s * 100 + '%')
|
||||
|
||||
const emitChangeEvent = throttle(function(param) {
|
||||
emit('update:modelValue', param)
|
||||
emit('change', param)
|
||||
}, 20, { leading: true, trailing: false })
|
||||
|
||||
const saturationRef = ref<HTMLElement | null>(null)
|
||||
|
@ -57,14 +65,12 @@ export default defineComponent({
|
|||
const saturation = left / containerWidth
|
||||
const bright = clamp(-(top / containerHeight) + 1, 0, 1)
|
||||
|
||||
const rgba = tinycolor({
|
||||
emitChangeEvent({
|
||||
h: color.value.h,
|
||||
s: saturation,
|
||||
v: bright,
|
||||
a: color.value.a,
|
||||
}).toRgb()
|
||||
|
||||
emitChangeEvent(rgba)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="color-picker" @contextmenu.prevent>
|
||||
<div class="picker-saturation-wrap">
|
||||
<Saturation v-model="color" />
|
||||
<Saturation :value="color" :hue="hue" @change="value => changeColor(value)" />
|
||||
</div>
|
||||
<div class="picker-controls">
|
||||
<div class="picker-color-wrap">
|
||||
|
@ -9,12 +9,18 @@
|
|||
<Checkboard />
|
||||
</div>
|
||||
<div class="picker-sliders">
|
||||
<div class="picker-hue-wrap"><Hue v-model="color" /></div>
|
||||
<div class="picker-alpha-wrap"><Alpha v-model="color" /></div>
|
||||
<div class="picker-hue-wrap">
|
||||
<Hue :value="color" :hue="hue" @change="value => changeColor(value)" />
|
||||
</div>
|
||||
<div class="picker-alpha-wrap">
|
||||
<Alpha :value="color" @change="value => changeColor(value)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="picker-field"><EditableInput v-model="color" /></div>
|
||||
<div class="picker-field">
|
||||
<EditableInput :value="color" @change="value => changeColor(value)" />
|
||||
</div>
|
||||
|
||||
<div class="picker-presets">
|
||||
<div
|
||||
|
@ -54,7 +60,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { computed, defineComponent, ref } from 'vue'
|
||||
import tinycolor, { ColorFormats } from 'tinycolor2'
|
||||
|
||||
import Alpha from './Alpha.vue'
|
||||
|
@ -120,6 +126,8 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const hue = ref(0)
|
||||
|
||||
const color = computed({
|
||||
get() {
|
||||
return tinycolor(props.modelValue).toRgb()
|
||||
|
@ -142,12 +150,22 @@ export default defineComponent({
|
|||
emit('update:modelValue', colorString)
|
||||
}
|
||||
|
||||
const changeColor = (value: ColorFormats.RGBA | ColorFormats.HSLA | ColorFormats.HSVA) => {
|
||||
if('h' in value) {
|
||||
hue.value = value.h
|
||||
color.value = tinycolor(value).toRgb()
|
||||
}
|
||||
else color.value = value
|
||||
}
|
||||
|
||||
return {
|
||||
themeColors,
|
||||
standardColors,
|
||||
presetColors,
|
||||
color,
|
||||
hue,
|
||||
currentColor,
|
||||
changeColor,
|
||||
selectPresetColor,
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue