vue3-ts-picker
Version:
547 lines (533 loc) • 21.1 kB
JavaScript
/*!
* vue3-ts-picker v2.2.4
* (c) 2022
* @license MIT
*/
;
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;