فهرست منبع

Merge branch 'dev' of http://124.70.149.18:10880/lianghj/queenshow into dev

qinyan 1 سال پیش
والد
کامیت
910b2156bf

+ 2 - 1
src/modules/editor/components/CompUI/basicUI/Text/EditorCustom.ts

@@ -14,7 +14,7 @@ import { Link } from "@ckeditor/ckeditor5-link";
 import { Paragraph } from "@ckeditor/ckeditor5-paragraph";
 import Heading from "@ckeditor/ckeditor5-heading/src/heading";
 import LineHeight from "ckeditor5-line-height-latest/src/lineheight";
-import LetterSpacing from "./ckeditor-letter-spacing/index";
+import { LetterSpacing, TextStroke } from "./ckeditor-plugin/index";
 import { EditorConfig } from "@ckeditor/ckeditor5-core";
 
 export class HeadlessEditor extends DecoupledEditorBase {}
@@ -37,6 +37,7 @@ HeadlessEditor.builtinPlugins = [
   Alignment,
   LineHeight,
   LetterSpacing,
+  TextStroke,
 ];
 const fontSizeOptions = [];
 const list = [12, 14, 16, 18, 20, 24, 28, 32, 38, 42, 46, 52, 60];

+ 91 - 2
src/modules/editor/components/CompUI/basicUI/Text/TextToolComp.tsx

@@ -12,7 +12,7 @@ import {
   IconTextUnderline,
 } from "@/assets/icons";
 import { css } from "@linaria/core";
-import { Button, InputNumber, Tooltip } from "ant-design-vue";
+import { Button, InputNumber, Tooltip, Checkbox } from "ant-design-vue";
 
 import { useEditor } from "@/modules/editor";
 import Select from "@queenjs-modules/queditor/components/FormUI/Items/Select";
@@ -29,6 +29,7 @@ import {
   watch,
 } from "vue";
 import { any, bool, func, number, object, string } from "vue-types";
+import Slider from "../../formItems/Slider";
 interface ColumnItem {
   label?: string;
   component?: ((...args: any[]) => any) | Record<string, any>;
@@ -313,6 +314,88 @@ export const FontSize = defineComponent({
     };
   },
 });
+
+export const TextStroke = defineComponent({
+  props: {
+    value: any().def(undefined),
+  },
+  emits: ["change"],
+  setup(props, { emit }) {
+    const state = reactive({
+      visible: props.value ? true : false,
+      width: 1,
+      color: "#666666",
+    });
+    watch(
+      () => props.value,
+      () => {
+        formatVal(props.value);
+      }
+    );
+    const formatVal = (value: any) => {
+      debugger;
+      if (!value) {
+        state.visible = false;
+        state.color = "#666666";
+        state.width = 1;
+        return;
+      }
+      state.visible = true;
+      const colorReg = /#[a-zA-Z0-9]{6}/g;
+      const color = value.match(colorReg)[0];
+      state.color = color;
+      const widthReg = /\d+px/g;
+      const width = value.match(widthReg)[0];
+      state.width = parseInt(width);
+    };
+    const colorChange = (v: string) => {
+      state.color = v;
+      buildValueSub();
+    };
+    const visibleChange = (e: any) => {
+      const checked = e.target.checked;
+      state.visible = checked;
+      buildValueSub();
+    };
+    const widthChange = (e: number) => {
+      state.width = e;
+      buildValueSub();
+    };
+    const buildValueSub = () => {
+      if (!state.visible) {
+        return;
+      }
+      const value = `${state.width}px ${state.color}`;
+      emit("change", value);
+    };
+
+    return () => {
+      return (
+        <div class={"flex-1"}>
+          <div class={"flex justify-between items-center  w-full"}>
+            <div class={"flex-1 flex items-center"}>
+              <Checkbox checked={state.visible} onChange={visibleChange} />
+
+              {state.visible && (
+                <div class={"flex-1 px-20px"}>
+                  <Slider
+                    min={1}
+                    max={5}
+                    value={state.width}
+                    step={1}
+                    onChange={widthChange}
+                  />
+                </div>
+              )}
+            </div>
+            <TextColor value={state.color} onChange={colorChange} />
+          </div>
+        </div>
+      );
+    };
+  },
+});
+
 export const LinkButton = defineComponent({
   props: {
     icon: any(),
@@ -470,6 +553,7 @@ const ColorPicker = css`
 
 const AlignCompWapper = css`
   display: flex;
+  background-color: #303030;
   .ant-btn {
     flex: 1;
     width: 100%;
@@ -485,6 +569,7 @@ const FontStyleCompWapper = css`
   align-items: center;
   margin-right: 12px;
   border-radius: 2px;
+  background-color: #303030;
   & > div {
     flex: 1;
     border-radius: 0;
@@ -502,7 +587,11 @@ const formItemStyles = css`
   height: 100%;
   flex: 1;
   margin-right: 12px;
-  background-color: #303030;
+  .ant-input-number-affix-wrapper,
+  .ant-select {
+    background-color: #303030;
+  }
+
   border-radius: 2px;
   &:last-child {
     margin-right: 0;

+ 39 - 27
src/modules/editor/components/CompUI/basicUI/Text/TextToolForm.tsx

@@ -13,6 +13,8 @@ import {
   LetterSpacingComp,
   LineHeightComp,
   TextToolItem,
+  TextColor,
+  TextStroke,
 } from "./TextToolComp";
 
 export const TextToolForm = defineComponent({
@@ -20,29 +22,7 @@ export const TextToolForm = defineComponent({
     component: any<DesignComp>().isRequired,
   },
   setup(props) {
-    const { store, actions, controls } = useEditor();
-
-    // const toolbarColumns = [
-    // {
-    //   label: "字体颜色",
-    //   dataIndex: "fontColor",
-    //   component: TextColor,
-    // },
-    // {
-    //   label: "链接",
-    //   dataIndex: "link",
-    //   component: (props: any) => (
-    //     <LinkButton icon={<LinkOutlined />} {...props} />
-    //   ),
-    //   changeExtra: (record: any) => {
-    //     record.value = record.value.value;
-    //     return record;
-    //   },
-    //   itemProps: {
-    //     class: "!mx-2px",
-    //   },
-    // },
-    // ];
+    const { controls } = useEditor();
 
     const changeVal = (e: { dataIndex: string; value: any }) => {
       let editor = controls.textEditorCtrl.state.currEditor;
@@ -61,7 +41,7 @@ export const TextToolForm = defineComponent({
     return () => {
       return (
         <div id="text_toolform">
-          <div>文本</div>
+          <div class={"text-white"}>文本</div>
           <div class={"mt-18px"}>
             <div class={formRowItem}>
               <TextToolItem
@@ -123,8 +103,30 @@ export const TextToolForm = defineComponent({
             </div>
           </div>
           <Divider class={"!my-18px"} />
-          <div>填充</div>
-          <div>描边</div>
+          <div class={[FormLabelItem, "justify-between mb-20px"]}>
+            <div class={"label"}>颜色</div>
+            <div>
+              <TextToolItem
+                column={{
+                  label: "字体颜色",
+                  dataIndex: "fontColor",
+                  component: TextColor,
+                }}
+                onChange={changeVal}
+              />
+            </div>
+          </div>
+          <div class={FormLabelItem}>
+            <div class={"label"}>描边</div>
+            <TextToolItem
+              column={{
+                label: "",
+                dataIndex: "textStroke",
+                component: TextStroke,
+              }}
+              onChange={changeVal}
+            />
+          </div>
           <Divider class={"!my-18px"} />
         </div>
       );
@@ -139,4 +141,14 @@ const formRowItem = css`
     margin-bottom: 0;
   }
 `;
-const TextToolbarStyle = css``;
+const FormLabelItem = css`
+  display: flex;
+  align-items: center;
+  .label {
+    min-width: 60px;
+    margin-right: 10px;
+    user-select: none;
+    font-size: 12px;
+    color: rgba(255, 255, 255, 0.8);
+  }
+`;

+ 0 - 12
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-letter-spacing/index.ts

@@ -1,12 +0,0 @@
-import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
-import LetterSpacingEditing from "./LetterSpacingEditing";
-
-export default class LetterSpacing extends Plugin {
-  static get requires() {
-    return [LetterSpacingEditing];
-  }
-
-  static get pluginName() {
-    return "LetterSpacing";
-  }
-}

+ 0 - 0
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-letter-spacing/LetterSpacingCommand.ts → src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/LetterSpacingCommand.ts


+ 2 - 7
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-letter-spacing/LetterSpacingEditing.ts → src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/LetterSpacingEditing.ts

@@ -1,12 +1,7 @@
 import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
-import {
-  isSupported,
-  buildDefinition,
-  Letter_Spacing,
-  normalizeOptions,
-} from "./utils";
-import LetterSpacingCommand from "./LetterSpacingCommand";
 import HeadlessEditor from "../EditorCustom";
+import LetterSpacingCommand from "./LetterSpacingCommand";
+import { Letter_Spacing, buildDefinition, normalizeOptions } from "./utils";
 
 export default class LetterSpacingEditing extends Plugin {
   constructor(editor: HeadlessEditor) {

+ 51 - 0
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/TextStrokeCommand.ts

@@ -0,0 +1,51 @@
+import Command from "@ckeditor/ckeditor5-core/src/command";
+import { Text_Stroke } from "./utils";
+
+export default class TextStrokeCommand extends Command {
+  constructor(editor: any) {
+    super(editor);
+  }
+  refresh() {
+    const model = this.editor.model;
+    const doc = model.document;
+    this.value = doc.selection.getAttribute(Text_Stroke);
+    this.isEnabled = model.schema.checkAttributeInSelection(
+      doc.selection,
+      Text_Stroke
+    );
+  }
+
+  execute(options = {} as any) {
+    const model = this.editor.model;
+    const document = model.document;
+    const selection = document.selection;
+    const value = options.value;
+    const batch = options.batch;
+
+    const updateAttribute = (writer: any) => {
+      if (selection.isCollapsed) {
+        return;
+      }
+      const ranges = model.schema.getValidRanges(
+        selection.getRanges(),
+        Text_Stroke
+      );
+      for (const range of ranges) {
+        if (value) {
+          writer.setAttribute(Text_Stroke, value, range);
+        } else {
+          writer.removeAttribute(Text_Stroke, range);
+        }
+      }
+    };
+    if (batch) {
+      model.enqueueChange(batch, (writer) => {
+        updateAttribute(writer);
+      });
+    } else {
+      model.change((writer) => {
+        updateAttribute(writer);
+      });
+    }
+  }
+}

+ 66 - 0
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/TextStrokeEditing.ts

@@ -0,0 +1,66 @@
+import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
+import HeadlessEditor from "../EditorCustom";
+import LetterSpacingCommand from "./TextStrokeCommand";
+import { Text_Stroke } from "./utils";
+
+export default class TextStrokeEditing extends Plugin {
+  constructor(editor: HeadlessEditor) {
+    super(editor);
+
+    // editor.config.define("letterSpacing", {
+    //   options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+    //   supportAllValues: false,
+    // });
+  }
+
+  /**
+   * @inheritDoc
+   */
+  init() {
+    const editor = this.editor;
+    editor.model.schema.extend("$text", {
+      allowAttributes: Text_Stroke,
+    });
+    editor.model.schema.setAttributeProperties(Text_Stroke, {
+      isFormatting: true,
+      copyOnEnter: true,
+    });
+
+    // const options = normalizeOptions(
+    //   this.editor.config.get("letterSpacing.options")
+    // ).filter((item: any) => item.model);
+
+    this._prepareAnyValueConverters();
+
+    editor.commands.add("textStroke", new LetterSpacingCommand(editor));
+  }
+  _prepareAnyValueConverters() {
+    const editor = this.editor;
+    editor.conversion.for("downcast").attributeToElement({
+      model: Text_Stroke,
+      view: (attributeValue, { writer }) => {
+        if (!attributeValue) {
+          return;
+        }
+        return writer.createAttributeElement(
+          "span",
+          { style: "-webkit-text-stroke:" + attributeValue },
+          { priority: 8 }
+        );
+      },
+    });
+    editor.conversion.for("upcast").elementToAttribute({
+      model: {
+        key: Text_Stroke,
+        value: (viewElement: any) =>
+          viewElement.getStyle("-webkit-text-stroke"),
+      },
+      view: {
+        name: "span",
+        styles: {
+          "-webkit-text-stroke": /.*/,
+        },
+      },
+    });
+  }
+}

+ 22 - 0
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/index.ts

@@ -0,0 +1,22 @@
+import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
+import LetterSpacingEditing from "./LetterSpacingEditing";
+import TextStrokeEditing from "./TextStrokeEditing";
+
+export class LetterSpacing extends Plugin {
+  static get requires() {
+    return [LetterSpacingEditing];
+  }
+
+  static get pluginName() {
+    return "LetterSpacing";
+  }
+}
+export class TextStroke extends Plugin {
+  static get requires() {
+    return [TextStrokeEditing];
+  }
+
+  static get pluginName() {
+    return "TextStroke";
+  }
+}

+ 1 - 4
src/modules/editor/components/CompUI/basicUI/Text/ckeditor-letter-spacing/utils.ts → src/modules/editor/components/CompUI/basicUI/Text/ckeditor-plugin/utils.ts

@@ -1,9 +1,6 @@
 export const Letter_Spacing = "letterSpacing";
+export const Text_Stroke = "textStroke";
 
-export function isSupported(option: any) {
-  // return supportedOptions.includes( option );
-  return /^\d(.\d+)?$/gm.test(String(option));
-}
 export type optionsKey = Record<string, any>;
 
 export function buildDefinition(options: any) {