Browse Source

colorpicker

qinyan 1 year ago
parent
commit
6b46af8c95

+ 92 - 25
src/modules/editor/components/CompUI/formItems/NewColorPicker/Picker.tsx

@@ -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,33 +91,86 @@ export default defineComponent({
       eyeDropper
         .open()
         .then((result: any) => {
-          emit("change", result.sRGBHex);
-          pickr.value.color.set(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()}
+              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:bg-[#3B3B3B] focus:bg-[#3B3B3B]"
+            <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
@@ -142,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;
+  }
+`;