|
@@ -1,7 +1,7 @@
|
|
|
import { IconPicker } from "@/assets/icons";
|
|
|
import iro from "@jaames/iro";
|
|
|
-import { css } from "@linaria/core";
|
|
|
-import { Input } from "ant-design-vue";
|
|
|
+import { css, cx } from "@linaria/core";
|
|
|
+import { Input, InputNumber } from "ant-design-vue";
|
|
|
import Color from "color";
|
|
|
import { nanoid } from "nanoid";
|
|
|
import { defineComponent, nextTick, onMounted, reactive, ref } from "vue";
|
|
@@ -13,9 +13,11 @@ declare global {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const colorReg = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
|
|
|
+
|
|
|
export default defineComponent({
|
|
|
props: {
|
|
|
- value: string().def("#fff"),
|
|
|
+ value: string().def("#ffffffff"),
|
|
|
},
|
|
|
emits: ["change"],
|
|
|
setup(props, { emit }) {
|
|
@@ -24,6 +26,9 @@ export default defineComponent({
|
|
|
|
|
|
const state = reactive({
|
|
|
showPicker: false,
|
|
|
+ hex: "",
|
|
|
+ opacity: 100,
|
|
|
+ color: props.value,
|
|
|
});
|
|
|
|
|
|
function initPicker() {
|
|
@@ -62,20 +67,21 @@ export default defineComponent({
|
|
|
],
|
|
|
});
|
|
|
|
|
|
- pickr.value.on("color:change", function (color: any) {
|
|
|
- if (color.alpha == 1) {
|
|
|
- emit("change", color.hexString);
|
|
|
- return;
|
|
|
- }
|
|
|
- emit("change", color.hex8String);
|
|
|
- });
|
|
|
+ pickr.value.on("input:end", changePickerColor);
|
|
|
+ pickr.value.on("input:move", changePickerColor);
|
|
|
}
|
|
|
|
|
|
- onMounted(() => {
|
|
|
- nextTick(() => {
|
|
|
- initPicker();
|
|
|
- });
|
|
|
- });
|
|
|
+ function changePickerColor(color: any) {
|
|
|
+ let res = "";
|
|
|
+ if (color.alpha == 1) {
|
|
|
+ res = color.hexString;
|
|
|
+ } else {
|
|
|
+ res = color.hex8String;
|
|
|
+ }
|
|
|
+ emit("change", res);
|
|
|
+ state.color = res;
|
|
|
+ parseColor();
|
|
|
+ }
|
|
|
|
|
|
function pickColor() {
|
|
|
if (!window.EyeDropper) {
|
|
@@ -85,32 +91,86 @@ export default defineComponent({
|
|
|
eyeDropper
|
|
|
.open()
|
|
|
.then((result: any) => {
|
|
|
- emit("change", result.sRGBHex);
|
|
|
+ state.hex = result.sRGBHex;
|
|
|
+ state.opacity = 100;
|
|
|
+ setPickerColor();
|
|
|
})
|
|
|
.catch((e: any) => {
|
|
|
console.log("e: ", e);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ const changeColor = (e: any) => {
|
|
|
+ const value = e.target.value;
|
|
|
+ if (value.indexOf("#") !== -1) {
|
|
|
+ state.hex = value;
|
|
|
+ setPickerColor();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const colorBlur = () => {
|
|
|
+ if (!colorReg.test(state.hex)) {
|
|
|
+ parseColor();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const changeOpacity = (v: any) => {
|
|
|
+ state.opacity = v;
|
|
|
+ setPickerColor();
|
|
|
+ };
|
|
|
+
|
|
|
+ function parseColor() {
|
|
|
+ const colorObj = Color(state.color);
|
|
|
+ const opacity = (colorObj.alpha() * 100).toFixed(0);
|
|
|
+ const hex = colorObj.hex();
|
|
|
+ // @ts-ignore
|
|
|
+ state.opacity = opacity;
|
|
|
+ state.hex = hex;
|
|
|
+ }
|
|
|
+
|
|
|
+ function setPickerColor() {
|
|
|
+ if (!colorReg.test(state.hex)) return;
|
|
|
+ const op = state.opacity / 100;
|
|
|
+ const res = Color(state.hex).alpha(op).hexa();
|
|
|
+ pickr.value.color.set(res);
|
|
|
+ state.color = res;
|
|
|
+ emit("change", state.color);
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ initPicker();
|
|
|
+ parseColor();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
return () => {
|
|
|
- const colorObj = Color(props.value);
|
|
|
- const opacity = (colorObj.alpha() * 100).toFixed(0) + "%";
|
|
|
+ const { opacity, hex } = state;
|
|
|
|
|
|
return (
|
|
|
<div class={styles}>
|
|
|
<div class={containerId}></div>
|
|
|
<div class="mt-15px flex items-center justify-between">
|
|
|
<Input
|
|
|
- readonly
|
|
|
bordered={false}
|
|
|
- value={colorObj.hex()}
|
|
|
- class="flex-1 bg-[#3B3B3B] h-36px text-center cursor-pointer hover:opacity-80"
|
|
|
+ value={hex}
|
|
|
+ maxlength={7}
|
|
|
+ class="flex-1 bg-[#3B3B3B] h-36px text-center cursor-pointer hover:bg-[#3B3B3B] focus:bg-[#3B3B3B]"
|
|
|
+ onChange={changeColor}
|
|
|
+ onBlur={colorBlur}
|
|
|
/>
|
|
|
- <Input
|
|
|
- readonly
|
|
|
- value={opacity}
|
|
|
- class="w-60px ml-10px bg-[#3B3B3B] h-36px text-center hover:opacity-80"
|
|
|
+ <InputNumber
|
|
|
bordered={false}
|
|
|
+ value={opacity}
|
|
|
+ min={0}
|
|
|
+ max={100}
|
|
|
+ formatter={(v) => v + "%"}
|
|
|
+ onChange={changeOpacity}
|
|
|
+ controls={false}
|
|
|
+ class={cx(
|
|
|
+ inputStyle,
|
|
|
+ "w-60px !ml-10px bg-[#3B3B3B] h-36px text-center hover:bg-[#3B3B3B] focus:bg-[#3B3B3B]"
|
|
|
+ )}
|
|
|
/>
|
|
|
{state.showPicker && (
|
|
|
<IconPicker
|
|
@@ -141,3 +201,11 @@ const styles = css`
|
|
|
border-radius: 6px !important;
|
|
|
}
|
|
|
`;
|
|
|
+
|
|
|
+const inputStyle = css`
|
|
|
+ .ant-input-number-input {
|
|
|
+ height: 36px;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #3b3b3b;
|
|
|
+ }
|
|
|
+`;
|