UNPKG

vue3-ts-picker

Version:
547 lines (533 loc) 21.1 kB
/*! * vue3-ts-picker v2.2.4 * (c) 2022 * @license MIT */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); /** * * rgb转化为hsv */ const rgbtohsv = (r, g, b) => { r = r / 255; g = g / 255; b = b / 255; let h = 0; let s = 0; let v = 0; const min = Math.min(r, g, b); const max = v = Math.max(r, g, b); const difference = max - min; if (max == min) { h = 0; } else { switch (max) { case r: h = (g - b) / difference + (g < b ? 6 : 0); break; case g: h = 2.0 + (b - r) / difference; break; case b: h = 4.0 + (r - g) / difference; break; } h = Math.round(h * 60); } if (max == 0) { s = 0; } else { s = 1 - min / max; } s = Math.round(s * 100); v = Math.round(v * 100); return [h, s, v]; }; /** * hsv转化为rgb */ const hsvtorgb = (h, s1, v1) => { const s = s1 / 100; const v = v1 / 100; const h1 = Math.floor(h / 60) % 6; const f = h / 60 - h1; const p = v * (1 - s); const q = v * (1 - f * s); const t = v * (1 - (1 - f) * s); let r = 0; let g = 0; let b = 0; switch (h1) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; }; /** * 16进制颜色值转化为rgb */ const colorToRgba = (sHex, alpha = 1) => { const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; let sColor = sHex.toLowerCase(); if (sColor && reg.test(sColor)) { if (sColor.length === 4) { let sColorNew = '#'; for (let i = 1; i < 4; i += 1) { sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)); } sColor = sColorNew; } const sColorChange = []; for (let i = 1; i < 7; i += 2) { sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2))); } return sColorChange; } else { return []; } }; /** * rgba转化为16进制 */ const rgbaTocolor = (color) => { const values = color.replace(/rgba?\(/, '').replace(/\)/, '').replace(/[\s+]/g, '').split(','); const a = parseFloat(values[3] || 1); const r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255); const g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255); const b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255); return '#' + ('0' + r.toString(16)).slice(-2) + ('0' + g.toString(16)).slice(-2) + ('0' + b.toString(16)).slice(-2); }; var usePickerSvpanel = (pickerColorHsv, hsv) => { const pickerColorSvpanel = vue.ref(); const pickerColorSvpCursor = vue.ref({ top: 0, left: 0 }); const hsvPop = vue.computed(() => hsv.value); vue.onMounted(() => { vue.watchEffect(() => { if (!hsvPop.value.length && hsvPop.value.length <= 1) { pickerColorSvpCursor.value.top = 0; pickerColorSvpCursor.value.left = 0; return; } if (!pickerColorSvpanel.value) { pickerColorSvpCursor.value.top = 0; pickerColorSvpCursor.value.left = 0; return; } const { width, height } = pickerColorSvpanel.value.getBoundingClientRect(); let left = width / 100 * hsvPop.value[1]; let top = (100 - hsvPop.value[2]) / 100 * height; pickerColorSvpCursor.value.left = Math.round(left / width * 100); pickerColorSvpCursor.value.top = Math.round(top / height * 100); }); }); const handleChangePickerSvpanel = (e) => { if (!pickerColorSvpanel.value) return; const { width, height, x, y } = pickerColorSvpanel.value.getBoundingClientRect(); pickerColorSvpCursor.value.top = (e.clientY - y) / height * 100; pickerColorSvpCursor.value.left = (e.clientX - x) / width * 100; pickerColorHsv.s = (e.clientX - x) / width * 100; pickerColorHsv.v = (1 - ((e.clientY - y) / height)) * 100; let moveX = 0; let moveY = 0; document.onmousemove = (e) => { moveX = (e.clientX - x) / width * 100; moveY = (e.clientY - y) / height * 100; pickerColorHsv.s = (e.clientX - x) / width * 100; pickerColorHsv.v = (1 - ((e.clientY - y) / height)) * 100; if (e.clientX <= x) { moveX = 0; pickerColorHsv.s = 0; } if ((e.clientX - x) >= width) { moveX = 100; pickerColorHsv.s = 100; } if (e.clientY <= y) { moveY = 0; pickerColorHsv.v = 100; } if (e.clientY >= (y + height)) { moveY = 100; pickerColorHsv.v = 0; } pickerColorSvpCursor.value.top = moveY; pickerColorSvpCursor.value.left = moveX; }; document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; }; }; return { handleChangePickerSvpanel, pickerColorSvpCursor, pickerColorSvpanel }; }; var useColorBar = (pickerColorHsv, hsv) => { const pickerSliderBarEle = vue.ref(); const pickerColorBar = vue.ref(0); const hsvPop = vue.computed(() => hsv.value); vue.onMounted(() => { vue.watchEffect(() => { if (!hsvPop.value.length && hsvPop.value.length <= 1) { pickerColorBar.value = 0; return; } if (!pickerSliderBarEle.value) { pickerColorBar.value = 0; return; } const { width } = pickerSliderBarEle.value.getBoundingClientRect(); let left = width / 360 * hsvPop.value[0]; pickerColorBar.value = Math.round(left / width * 100); }); }); const handleChangePickerBar = (e) => { if (!pickerSliderBarEle.value) return; const { width, x } = pickerSliderBarEle.value.getBoundingClientRect(); pickerColorBar.value = ((e.clientX - x) / width) * 100; pickerColorHsv.h = Math.round((e.clientX - x) / width * 360); document.onmousemove = (e) => { if (e.clientX <= x) { pickerColorBar.value = 0; pickerColorHsv.h = 0; } else if ((e.clientX - x) >= width) { pickerColorBar.value = 100; pickerColorHsv.h = 0; } else { pickerColorBar.value = ((e.clientX - x) / width) * 100; pickerColorHsv.h = Math.round((e.clientX - x) / width * 360); } }; document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; }; }; return { pickerSliderBarEle, pickerColorBar, handleChangePickerBar }; }; var useColorSlider = (pickerColorHsv, hsv) => { const pickerSliderSliderEle = vue.ref(); const pickerSliderSlider = vue.ref(100); const hsvPop = vue.computed(() => hsv.value); vue.onMounted(() => { vue.watchEffect(() => { if (!hsvPop.value.length && hsvPop.value.length <= 1) { pickerSliderSlider.value = 1; return; } if (hsvPop.value.length > 3) { pickerSliderSlider.value = Math.round(hsvPop.value[3] * 100); } }); }); const pickerSliderBar = vue.computed(() => { let bent = hsvtorgb(pickerColorHsv.h, pickerColorHsv.s, pickerColorHsv.v); return `linear-gradient(to right,rgba(${bent[0]},${bent[1]},${bent[2]},0) 0%, rgb(${bent[0]},${bent[1]},${bent[2]}) 100%)`; }); const handleChangePickerSlider = (e) => { if (!pickerSliderSliderEle.value) return; const { width, x } = pickerSliderSliderEle.value.getBoundingClientRect(); pickerSliderSlider.value = ((e.clientX - x) / width) * 100; pickerColorHsv.a = Math.round(pickerSliderSlider.value) / 100; document.onmousemove = (e) => { if (e.clientX <= x) { pickerSliderSlider.value = 0; } else if ((e.clientX - x) >= width) { pickerSliderSlider.value = 100; } else { pickerSliderSlider.value = ((e.clientX - x) / width) * 100; } pickerColorHsv.a = Math.round(pickerSliderSlider.value) / 100; }; document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; }; }; return { handleChangePickerSlider, pickerSliderSliderEle, pickerSliderSlider, pickerSliderBar }; }; var script = vue.defineComponent({ name: 'colorPicker', props: { color: { type: String, required: true, } }, setup(props, { emit }) { const pickerColorHsv = vue.ref({ h: 0, s: 0, v: 100, a: 1 }); const titleColorDefault = vue.ref(["#ff3b30", "#ff9500", "#ffcc00", "#4cd964", "#5ac8fa", "#007aff", "#5856d6", "#bd10e0"]); const colorPredefine = vue.ref([ "#ffd8d6", "#ffeacc", "#fff5cc", "#dbf7e0", "#def4fe", "#cce4ff", "#deddf7", "#f2cff9", "#ffb1ac", "#ffd599", "#ffeb99", "#bff1c7", "#bde9fd", "#99caff", "#bcbbef", "#e59ff3", "#ff766f", "#ffb54d", "#ffdb4d", "#82e493", "#8cd9fc", "#4da2ff", "#8a89e2", "#d158e9", "#b22922", "#b26800", "#b28e00", "#359746", "#3f8caf", "#0055b2", "#3d3c95", "#840b9c", "#661813", "#663c00", "#665200", "#1e5728", "#245064", "#003166", "#232256", "#4c065a" ]); const hsv = vue.ref([0]); const isRgbMode = vue.ref(true); const pickerColorSvpanelBg = vue.computed(() => { let pickerColorBg = hsvtorgb(pickerColorHsv.value.h, 100, 100); return `rgb(${pickerColorBg[0]},${pickerColorBg[1]},${pickerColorBg[2]})`; }); const adsorbentColor = vue.computed(() => { let pickerColorAdsorbent = hsvtorgb(pickerColorHsv.value.h, pickerColorHsv.value.s, pickerColorHsv.value.v); let rgba = `rgba(${pickerColorAdsorbent[0]},${pickerColorAdsorbent[1]},${pickerColorAdsorbent[2]},${pickerColorHsv.value.a})`; emit("changePickerColorBen", isRgbMode.value ? rgba : rgbaTocolor(rgba)); return rgba; }); const colorMode = vue.computed(() => { let pickerColorAdsorbent = hsvtorgb(pickerColorHsv.value.h, pickerColorHsv.value.s, pickerColorHsv.value.v); let rgba = `rgba(${pickerColorAdsorbent[0]},${pickerColorAdsorbent[1]},${pickerColorAdsorbent[2]},${pickerColorHsv.value.a})`; return rgbaTocolor(rgba); }); const changePredeine = (value) => { if (/rgba\(.*\)$/g.test(value)) { let rgbaArr = value.replace(/rgba?\(/, '').replace(/\)/, '').replace(/[\s+]/g, '').split(','); if (rgbaArr.length && rgbaArr.length == 4) { pickerColorHsv.value.a = Number(rgbaArr[3]); value = `rgba(${rgbaArr[0]},${rgbaArr[1]},${rgbaArr[2]})`; } value = rgbaTocolor(value); } if (!value) return; let rgb = colorToRgba(value); if (rgb && rgb.length) { hsv.value = rgbtohsv(rgb[0], rgb[1], rgb[2]); pickerColorHsv.value.h = hsv.value[0]; pickerColorHsv.value.s = hsv.value[1]; pickerColorHsv.value.v = hsv.value[2]; hsv.value[3] = pickerColorHsv.value.a; } }; const changeColorMode = () => { isRgbMode.value = !isRgbMode.value; }; vue.onMounted(() => { changePredeine(props.color); }); const changePickerColor = (value) => { pickerColorHsv.value.h = value.h; pickerColorHsv.value.s = value.s; pickerColorHsv.value.v = value.v; pickerColorHsv.value.a = value.a; }; const hsvC = vue.computed(() => hsv.value); const pickerSvpanel = usePickerSvpanel(pickerColorHsv.value, hsvC); const colorBar = useColorBar(pickerColorHsv.value, hsvC); const colorSlider = useColorSlider(pickerColorHsv.value, hsvC); return { pickerColorSvpanelBg, adsorbentColor, pickerColorHsv, changePickerColor, titleColorDefault, colorPredefine, changePredeine, hsv, colorMode, isRgbMode, changeColorMode, ...pickerSvpanel, ...colorBar, ...colorSlider }; } }); const _withScopeId = n => (vue.pushScopeId("data-v-0747681c"),n=n(),vue.popScopeId(),n); const _hoisted_1 = { class: "color-picker" }; const _hoisted_2 = { class: "svpanel" }; const _hoisted_3 = { class: "pickerSvpanel" }; const _hoisted_4 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/vue.createElementVNode("div", { class: "picker-color-svpanel__white picker-com" }, null, -1 /* HOISTED */)); const _hoisted_5 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/vue.createElementVNode("div", { class: "picker-color-svpanel__black picker-com" }, null, -1 /* HOISTED */)); const _hoisted_6 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/vue.createElementVNode("div", { class: "pointer" }, null, -1 /* HOISTED */)); const _hoisted_7 = [ _hoisted_6 ]; const _hoisted_8 = { class: "picker-color-bar" }; const _hoisted_9 = { class: "color-content" }; const _hoisted_10 = { class: "color-slider" }; const _hoisted_11 = { class: "picker-color-barWraper" }; const _hoisted_12 = { class: "colorBar" }; const _hoisted_13 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/vue.createElementVNode("div", { class: "content" }, null, -1 /* HOISTED */)); const _hoisted_14 = { class: "colorSlider" }; const _hoisted_15 = { class: "picker-color-dropdown__btns" }; const _hoisted_16 = /*#__PURE__*/vue.createStaticVNode("<svg width=\"18\" height=\"18\" viewBox=\"0 0 48 48\" fill=\"none\" data-v-0747681c><rect width=\"48\" height=\"48\" fill=\"white\" fill-opacity=\"0.01\" data-v-0747681c></rect><path d=\"M42 19H5.99998\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"square\" stroke-linejoin=\"round\" data-v-0747681c></path><path d=\"M30 7L42 19\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"square\" stroke-linejoin=\"round\" data-v-0747681c></path><path d=\"M6.79897 29H42.799\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"square\" stroke-linejoin=\"round\" data-v-0747681c></path><path d=\"M6.79895 29L18.799 41\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"square\" stroke-linejoin=\"round\" data-v-0747681c></path></svg>", 1); const _hoisted_17 = [ _hoisted_16 ]; const _hoisted_18 = { class: "picker-color-predefine" }; const _hoisted_19 = ["onClick"]; const _hoisted_20 = { class: "picker-color-predefine-box" }; const _hoisted_21 = ["onClick"]; function render(_ctx, _cache, $props, $setup, $data, $options) { return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createElementVNode("div", _hoisted_2, [ vue.createElementVNode("div", _hoisted_3, [ vue.createElementVNode("div", { class: "picker-color-svpanel", style: vue.normalizeStyle({'background': _ctx.pickerColorSvpanelBg}), ref: "pickerColorSvpanel", onMousedown: _cache[0] || (_cache[0] = vue.withModifiers($event => _ctx.handleChangePickerSvpanel($event), ["stop"])) }, [ _hoisted_4, _hoisted_5, vue.createElementVNode("div", { class: "picker-color-svpanel__cursor", style: vue.normalizeStyle({ top: _ctx.pickerColorSvpCursor.top + '%', left: _ctx.pickerColorSvpCursor.left + '%' }) }, _hoisted_7, 4 /* STYLE */) ], 36 /* STYLE, HYDRATE_EVENTS */) ]) ]), vue.createElementVNode("div", _hoisted_8, [ vue.createElementVNode("div", _hoisted_9, [ vue.createElementVNode("div", { class: "picker-current-color", style: vue.normalizeStyle({'background': _ctx.adsorbentColor}) }, null, 4 /* STYLE */) ]), vue.createElementVNode("div", _hoisted_10, [ vue.createElementVNode("div", _hoisted_11, [ vue.createElementVNode("div", _hoisted_12, [ _hoisted_13, vue.createElementVNode("div", { class: "picker-color-content-bar", ref: "pickerSliderBarEle", onMousedown: _cache[1] || (_cache[1] = $event => _ctx.handleChangePickerBar($event)) }, [ vue.createElementVNode("div", { class: "bar", style: vue.normalizeStyle({ left: _ctx.pickerColorBar + '%' }) }, null, 4 /* STYLE */) ], 544 /* HYDRATE_EVENTS, NEED_PATCH */) ]) ]), vue.createElementVNode("div", _hoisted_14, [ vue.createElementVNode("div", { class: "picker-color-alpha-slider", ref: "pickerSliderSliderEle", onMousedown: _cache[2] || (_cache[2] = $event => _ctx.handleChangePickerSlider($event)) }, [ vue.createElementVNode("div", { class: "picker-color-alpha-slider__bar", style: vue.normalizeStyle({background: _ctx.pickerSliderBar}) }, null, 4 /* STYLE */), vue.createElementVNode("div", { class: "picker-color-alpha-slider__thumb", style: vue.normalizeStyle({ left: _ctx.pickerSliderSlider + '%' }) }, null, 4 /* STYLE */) ], 544 /* HYDRATE_EVENTS, NEED_PATCH */) ]) ]) ]), vue.createElementVNode("div", _hoisted_15, [ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.isRgbMode ? _ctx.adsorbentColor : _ctx.colorMode), 1 /* TEXT */), vue.createElementVNode("div", { class: "picker-color-mode", onClick: _cache[3] || (_cache[3] = (...args) => (_ctx.changeColorMode && _ctx.changeColorMode(...args))) }, _hoisted_17) ]), vue.createElementVNode("div", _hoisted_18, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.titleColorDefault, (item, index) => { return (vue.openBlock(), vue.createElementBlock("div", { class: "picker-color-title", key: index, style: vue.normalizeStyle({background: item}), onClick: $event => (_ctx.changePredeine(item)) }, null, 12 /* STYLE, PROPS */, _hoisted_19)) }), 128 /* KEYED_FRAGMENT */)) ]), vue.createElementVNode("div", _hoisted_20, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.colorPredefine, (item, index) => { return (vue.openBlock(), vue.createElementBlock("div", { class: "picker-color-box", key: index, style: vue.normalizeStyle({background: item}), onClick: $event => (_ctx.changePredeine(item)) }, null, 12 /* STYLE, PROPS */, _hoisted_21)) }), 128 /* KEYED_FRAGMENT */)) ]) ])) } script.render = render; script.__scopeId = "data-v-0747681c"; script.__file = "src/color/colorPicker.vue"; script.install = (Vue) => { Vue.component(script.name, script); }; function install(Vue) { Vue.component(script.name, script); } var index = { install }; exports.ColorPicker = script; exports["default"] = index;