浏览代码

color picker

bianjiang 1 年之前
父节点
当前提交
54f01a4cd8
共有 1 个文件被更改,包括 148 次插入49 次删除
  1. 148 49
      src/modules/editor/components/CompUI/basicUI/Text/ToolbarComp.tsx

+ 148 - 49
src/modules/editor/components/CompUI/basicUI/Text/ToolbarComp.tsx

@@ -12,80 +12,158 @@ import Select from "@queenjs-modules/queditor/components/FormUI/Items/Select";
 import Pickr from "@simonwep/pickr";
 import "@simonwep/pickr/dist/themes/nano.min.css";
 import { queenApi } from "queenjs";
-import { defineComponent, onMounted, ref, watch, onUnmounted } from "vue";
+import {
+  defineComponent,
+  onMounted,
+  onUnmounted,
+  reactive,
+  ref,
+  watch,
+} from "vue";
 import { any, bool, string } from "vue-types";
+import _ from "lodash";
+
+// export const TextColor = defineComponent({
+//   props: {
+//     value: string().def("#666666"),
+//   },
+//   emits: ["change"],
+//   setup(props, { emit }) {
+//     let picker: any = null;
+
+//     let emitFlagRef = ref(true);
+//     const color = HSLToHex(props.value);
+//     function HSLToHex(hslStr: string): string {
+//       const isHsl = hslStr.indexOf("hsl");
+//       if (isHsl == -1) {
+//         return hslStr;
+//       }
+//       const reg = /(?<=hsl\()(\W|\w)*(?=\))/g;
+//       let hsl: any = hslStr.match(reg);
+//       if (!hsl) {
+//         return hslStr;
+//       }
+//       hsl = hsl[0];
+//       hsl = hsl.split(",");
+//       const [h, s, l] = hsl;
+
+//       const hDecimal = parseInt(l) / 100;
+//       const a = (parseInt(s) * Math.min(hDecimal, 1 - hDecimal)) / 100;
+//       const f = (n: number) => {
+//         const k = (n + parseInt(h) / 30) % 12;
+//         const color = hDecimal - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
+
+//         return Math.round(255 * color)
+//           .toString(16)
+//           .padStart(2, "0");
+//       };
+//       return `#${f(0)}${f(8)}${f(4)}`;
+//     }
+
+//     function initPicker() {
+//       picker = Pickr.create({
+//         el: ".color_picker",
+//         theme: "nano",
+//         default: color,
+//         i18n: {
+//           "btn:save": "确定",
+//         },
+//         components: {
+//           preview: true,
+//           opacity: false,
+//           hue: true,
+//           interaction: {
+//             hex: false,
+//             hsla: false,
+//             rgba: false,
+//             input: true,
+//             save: true,
+//           },
+//         },
+//       });
+//       // picker.on("change", (color: any) => {
+//       //   const hexa = color.toHEXA().toString();
+//       //   console.log("setChange", hexa);
+//       // });
+//       picker.on("save", (color: any) => {
+//         picker.hide();
+//         const hexa = color.toHEXA().toString();
+//         emit("change", hexa);
+//       });
+//     }
+//     watch(
+//       () => props.value,
+//       () => {
+//         const color = HSLToHex(props.value);
+//         const res = picker.setColor(color);
+//         console.log("picker change", color, res);
+//       }
+//     );
+//     onMounted(() => {
+//       initPicker();
+//     });
+//     onUnmounted(() => {
+//       if (picker) {
+//         picker.destroyAndRemove();
+//         picker = null;
+//       }
+//     });
 
+//     return () => (
+//       <div
+//         class={ColorPicker}
+//         onClick={() => {
+//           picker?.show();
+//         }}
+//       >
+//         <div class={"color_picker"} id="color_picker"></div>
+//       </div>
+//     );
+//   },
+// });
 export const TextColor = defineComponent({
   props: {
     value: string().def("#666666"),
   },
   emits: ["change"],
   setup(props, { emit }) {
-    let picker: any = null;
-    let emitFlagRef = ref(true);
-    function initPicker() {
-      picker = Pickr.create({
-        el: ".color_picker",
-        theme: "nano",
-        default: props.value,
-        i18n: {
-          "btn:save": "确定",
-        },
-        components: {
-          preview: true,
-          opacity: false,
-          hue: true,
-          interaction: {
-            hex: false,
-            rgba: false,
-            input: true,
-            save: true,
-          },
-        },
-      });
+    let pickerRef = ref();
 
-      picker.on("save", (color: any) => {
-        picker.hide();
-        const hexa = color.toHEXA().toString();
-        if (!emitFlagRef.value) {
-          emitFlagRef.value = true;
-          return;
-        }
-        emit("change", hexa);
-      });
-    }
+    const state = reactive({
+      color: props.value,
+    });
     watch(
       () => props.value,
       () => {
-        console.log(props.value);
-        emitFlagRef.value = false;
-        picker.setColor(props.value);
+        state.color = props.value;
       }
     );
-    onMounted(() => {
-      initPicker();
-    });
-    onUnmounted(() => {
-      console.log("destroy");
-      if (picker) {
-        picker.destroyAndRemove();
-        picker = null;
-      }
-    });
+    const colorChange = (e: any) => {
+      const hexa = e.target.value;
+      emit("change", hexa);
+      state.color = hexa;
+    };
 
     return () => (
       <div
         class={ColorPicker}
         onClick={() => {
-          picker?.show();
+          pickerRef?.value.click();
         }}
       >
-        <div class={"color_picker"} id="color_picker"></div>
+        <div class="color_picker" style={{ backgroundColor: state.color }}>
+          <input
+            type="color"
+            class="color_input"
+            ref={pickerRef}
+            value={state.color}
+            onInput={_.debounce(colorChange, 300)}
+          />
+        </div>
       </div>
     );
   },
 });
-
 export const AlignComp = defineComponent({
   props: {
     value: string<"left" | "right" | "center" | "justify">().def("left"),
@@ -295,6 +373,27 @@ const ColorPicker = css`
   height: 32px;
   border-radius: 2px;
   cursor: pointer;
+  .color_picker {
+    width: 100%;
+    height: 100%;
+    border-radius: 2px;
+    border: 1px solid transparent;
+    &:focus,
+    &:hover {
+      border-color: @inf-primary-color;
+      box-shadow: 0 0 0 2px rgba(232, 139, 0, 0.2);
+    }
+  }
+  .color_input {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    height: 0;
+    padding: 0;
+    border: none;
+    visibility: hidden;
+  }
   .pickr {
     width: 100%;
     height: 100%;