@chenyomi/leafer-htmltext-editor 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,145 +1,130 @@
1
- /**
2
- * TextEditTool 插件
3
- * 用于在编辑器中提供带有圆角的矩形的控制点编辑功能
4
- *
5
- * 作者: chenyomi
6
- */
7
-
8
- import { DragEvent, PointerEvent, WatchEvent } from 'leafer-ui';
9
- import { EditTool, Editor, registerEditTool, EditorScaleEvent, EditorMoveEvent } from '@leafer-in/editor';
10
- import { updataHtmlText } from '../utils';
11
- import { TextEditor } from '../TextEditor';
12
-
13
- // 简单的防抖函数实现
14
- function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void {
15
- let timeout: ReturnType<typeof setTimeout> | null = null;
16
- return function(this: any, ...args: Parameters<T>) {
17
- if (timeout) clearTimeout(timeout);
18
- timeout = setTimeout(() => func.apply(this, args), wait);
19
- };
20
- }
21
-
1
+ import {
2
+ EditTool,
3
+ EditorScaleEvent,
4
+ registerEditTool
5
+ } from "@leafer-in/editor";
6
+ import { PointerEvent } from "leafer-ui";
7
+ import { quillManager } from "../";
8
+ import { updataHtmlText } from "../utils";
22
9
  @registerEditTool()
10
+ // 定义插件类,继承自 EditTool,处理矩形圆角编辑交互
23
11
  export class TextEditTool extends EditTool {
12
+ // 插件标识标签
24
13
  public get tag() {
25
- return 'TextEditTool';
14
+ return "TextEditTool";
26
15
  }
27
-
28
16
  public quill: any = null;
29
- private _dragRAF: number | null = null;
30
17
  private updateBoxDebounced: (text: any) => void;
31
-
18
+ // 构造函数,初始化控制点并加入视图
32
19
  constructor(editor: any) {
33
20
  super(editor);
34
- this.eventIds = [];
35
- this.updateBoxDebounced = debounce((text: any) => {
21
+ this.eventIds = []; // 存储事件绑定ID
22
+ this.updateBoxDebounced = this.debounce((text: any) => {
36
23
  updataHtmlText(text);
37
24
  }, 300);
38
25
  }
39
-
26
+ // 自定义防抖函数替代 lodash/debounce
27
+ private debounce<T extends (...args: any[]) => any>(
28
+ func: T,
29
+ wait: number,
30
+ ): T {
31
+ let timeout: number | null = null;
32
+ return ((...args: any[]) => {
33
+ if (timeout !== null) {
34
+ window.clearTimeout(timeout);
35
+ }
36
+ timeout = window.setTimeout(
37
+ () => func.apply(this, args),
38
+ wait,
39
+ ) as unknown as number;
40
+ }) as T;
41
+ }
42
+ // 绑定事件
40
43
  public addEvent(): void {
41
- if (!this.editor?.element) return;
42
-
43
- const text = this.editor.element.findOne('HTMLText');
44
- if (!text) return;
45
-
44
+ const { editor } = quillManager.getCanvas();
45
+ const text = editor._target.findOne("HTMLText");
46
46
  const { scaleX, scaleY } = text.worldTransform;
47
47
  const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
48
- const div: any = document.querySelector('#textInnerEditor');
49
-
50
- if (!div) return;
51
-
48
+ const div: any = document.querySelector("#textInnerEditor");
52
49
  const { style } = div;
53
-
54
50
  this.eventIds = [
55
- this.editor.on_(EditorScaleEvent.SCALE, (e: any) => {
56
- if (!text.data) text.data = {};
51
+ editor.on_(EditorScaleEvent.SCALE, (e: any) => {
57
52
  if (!text.data.canChangeBox) {
58
53
  text.data.canChangeBox = true;
59
54
  }
60
- if (text.data.canChangeBox && text.parent) {
61
- const parentWidth = text.parent.width;
62
- if (parentWidth !== undefined) {
63
- style.width = parentWidth * zoomScale + 'px';
64
- style.height = 'auto';
65
- }
55
+ if (text.data.canChangeBox) {
56
+ style.width = text.parent.width * zoomScale + "px";
57
+ style.height = "auto";
66
58
  }
67
59
  this.updateBoxDebounced(text);
68
60
  }),
69
- this.editor.on_(PointerEvent.DOUBLE_TAP, () => {
70
- if (!text.parent?.locked) {
71
- this.editor.openInnerEditor(text, true);
61
+ editor.on_(PointerEvent.DOUBLE_TAP, () => {
62
+ if (!text.parent.locked) {
63
+ editor.openInnerEditor(text, true);
72
64
  }
73
- })
65
+ }),
74
66
  ];
75
67
  }
76
68
 
69
+ // 生命周期钩子:插件加载时绑定事件
77
70
  public onLoad(): void {
78
- if (!this.editor?.element) return;
79
-
80
- const text: any = this.editor.element.findOne('HTMLText');
81
- if (!text) return;
82
-
71
+ console.log(22222222)
72
+ const { editor } = quillManager.getCanvas();
73
+ const text: any = editor._target.findOne("HTMLText");
83
74
  const { scaleX, scaleY } = text.worldTransform;
84
75
  const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
85
-
86
76
  this.addEvent();
87
- this.editBox.add(this.view);
88
-
89
- this.quill = TextEditor.quill;
90
- if (this.quill && text.text) {
91
- this.quill.clipboard.dangerouslyPasteHTML(text.text);
92
- }
93
-
94
- const div: any = document.querySelector('#textInnerEditor');
95
- if (!div) return;
96
-
77
+ this.quill = quillManager.getQuill();
78
+ this.quill.clipboard.dangerouslyPasteHTML(text.text);
79
+ const div: any = document.querySelector("#textInnerEditor");
97
80
  const { style } = div;
98
81
 
99
- if (text.data?.canChangeBox && text.parent) {
100
- const parentWidth = text.parent.width;
101
- const parentHeight = text.parent.height;
102
- if (parentWidth !== undefined) {
103
- style.width = parentWidth * zoomScale + 'px';
104
- }
105
- if (parentHeight !== undefined) {
106
- style.height = parentHeight * zoomScale + 'px';
107
- }
82
+ if (text.data.canChangeBox) {
83
+ style.width = text.parent.width * zoomScale + "px";
84
+ style.height = text.parent.height * zoomScale + "px";
108
85
  } else {
109
- style.width = 'auto';
110
- style.height = 'auto';
86
+ style.width = "auto";
87
+ style.height = "auto";
111
88
  }
89
+ // 每次进来就恢复初始的 canChangeBox 和 自动的宽高
90
+ // text.set({
91
+ // width: 0,
92
+ // height: 0
93
+ // })
94
+ // text.data.canChangeBox = false
112
95
  }
113
96
 
114
97
  private isUpdatingPoints = false;
115
98
  private curveAmount = 0;
116
-
117
99
  public updateChangeBoxBound(text: any): void {
118
- if (text && text.__layout?.boxBounds) {
100
+ text &&
119
101
  text.set({
120
102
  width: text.__layout.boxBounds.width,
121
- height: text.__layout.boxBounds.height
103
+ height: text.__layout.boxBounds.height,
122
104
  });
123
- }
124
105
  }
125
-
106
+ // 生命周期钩子:插件更新时,因为这是全局的生命周期所以判断一定要细致仔细
126
107
  public onUpdate(): void {
127
- if (!this.editor?.element) return;
128
-
129
- const text = this.editor.element.findOne('HTMLText');
130
- if (!text) return;
131
-
132
- const el = this.editor.element;
133
- console.log('文本bound更新');
108
+ const { editor } = quillManager.getCanvas();
109
+ const text = editor._target.findOne("HTMLText");
110
+ const el = editor._target;
111
+ console.log("文本bound更新");
134
112
 
135
- // 记录上一次的 curveAmount,只有变化时才触发
136
- if (this.curveAmount === (text as any).curveAmount) return;
113
+ if (this.curveAmount == (text as any).curveAmount) return;
137
114
  if (this.isUpdatingPoints) return;
115
+ // 每次进来就恢复初始的 canChangeBox 和 自动的宽高
116
+ // text.set({
117
+ // width: 0,
118
+ // height: 0
119
+ // })
138
120
  }
139
121
 
122
+ // 生命周期钩子:插件卸载时解绑事件
140
123
  public onUnload(): void {
141
- this.editor.off_(this.eventIds);
124
+ const { editor } = quillManager.getCanvas();
125
+ editor.off_(this.eventIds);
142
126
  }
143
127
 
128
+ // 生命周期钩子:销毁插件时清理资源
144
129
  public onDestroy(): void {}
145
130
  }
@@ -1,5 +1,5 @@
1
- import { Text, Box, Path } from 'leafer-ui'
2
- import { HTMLText } from '@leafer-in/html' // 导入 html 插件
1
+ import { HTMLText } from '@leafer-in/html'; // 导入 html 插件
2
+ import { Box, Path } from 'leafer-ui'
3
3
  export function getArcRadius(fontSize: number, curveAmount: number): number {
4
4
  if (curveAmount === 0) return Infinity
5
5
  const theta = (330 * fontSize * 72) / 96
@@ -82,22 +82,105 @@ export const handleShowCurve = (element: any, op: boolean) => {
82
82
 
83
83
  // base 映射:只需把普通字符 -> 上标/下标(任意已有的上/下标字符)列出来一次
84
84
  const baseSuperscript: Record<string, string> = {
85
- '0': '⁰','1': '¹','2': '²','3': '³','4': '⁴','5': '⁵','6': '⁶','7': '⁷','8': '⁸','9': '⁹',
86
- a: '', b: '', c: 'ᶜ', d: 'ᵈ', e: 'ᵉ', f: 'ᶠ', g: 'ᵍ', h: 'ʰ', i: 'ⁱ', j: 'ʲ', k: 'ᵏ',
87
- l: 'ˡ', m: '', n: 'ⁿ', o: 'ᵒ', p: 'ᵖ', r: 'ʳ', s: 'ˢ', t: 'ᵗ', u: 'ᵘ', v: 'ᵛ', w: 'ʷ',
88
- x: 'ˣ', y: 'ʸ', z: 'ᶻ',
89
- A: '', B: '', D: 'ᴰ', E: 'ᴱ', G: 'ᴳ', H: 'ᴴ', I: 'ᴵ', J: 'ᴶ', K: 'ᴷ', L: 'ᴸ', M: 'ᴹ',
90
- N: '', O: '', P: 'ᴾ', R: 'ᴿ', T: 'ᵀ', U: 'ᵁ', W: 'ᵂ',
91
- '+': '', '-': '⁻', '=': '⁼', '(': '⁽', ')': '⁾'
85
+ '0': '⁰',
86
+ '1': '¹',
87
+ '2': '²',
88
+ '3': '³',
89
+ '4': '',
90
+ '5': '',
91
+ '6': '',
92
+ '7': '⁷',
93
+ '8': '⁸',
94
+ '9': '⁹',
95
+ a: 'ᵃ',
96
+ b: 'ᵇ',
97
+ c: 'ᶜ',
98
+ d: 'ᵈ',
99
+ e: 'ᵉ',
100
+ f: 'ᶠ',
101
+ g: 'ᵍ',
102
+ h: 'ʰ',
103
+ i: 'ⁱ',
104
+ j: 'ʲ',
105
+ k: 'ᵏ',
106
+ l: 'ˡ',
107
+ m: 'ᵐ',
108
+ n: 'ⁿ',
109
+ o: 'ᵒ',
110
+ p: 'ᵖ',
111
+ r: 'ʳ',
112
+ s: 'ˢ',
113
+ t: 'ᵗ',
114
+ u: 'ᵘ',
115
+ v: 'ᵛ',
116
+ w: 'ʷ',
117
+ x: 'ˣ',
118
+ y: 'ʸ',
119
+ z: 'ᶻ',
120
+ A: 'ᴬ',
121
+ B: 'ᴮ',
122
+ D: 'ᴰ',
123
+ E: 'ᴱ',
124
+ G: 'ᴳ',
125
+ H: 'ᴴ',
126
+ I: 'ᴵ',
127
+ J: 'ᴶ',
128
+ K: 'ᴷ',
129
+ L: 'ᴸ',
130
+ M: 'ᴹ',
131
+ N: 'ᴺ',
132
+ O: 'ᴼ',
133
+ P: 'ᴾ',
134
+ R: 'ᴿ',
135
+ T: 'ᵀ',
136
+ U: 'ᵁ',
137
+ W: 'ᵂ',
138
+ '+': '⁺',
139
+ '-': '⁻',
140
+ '=': '⁼',
141
+ '(': '⁽',
142
+ ')': '⁾'
92
143
  }
93
144
 
94
145
  const baseSubscript: Record<string, string> = {
95
- '0': '₀','1': '₁','2': '₂','3': '₃','4': '₄','5': '₅','6': '₆','7': '₇','8': '₈','9': '₉',
96
- a: '', e: '', h: 'ₕ', i: 'ᵢ', j: 'ⱼ', k: 'ₖ', l: 'ₗ', m: 'ₘ', n: 'ₙ', o: 'ₒ', p: 'ₚ',
97
- r: '', s: '', t: 'ₜ', u: 'ᵤ', v: 'ᵥ', x: 'ₓ',
98
- '+': '', '-': '₋', '=': '₌', '(': '₍', ')': '₎',
146
+ '0': '₀',
147
+ '1': '',
148
+ '2': '',
149
+ '3': '',
150
+ '4': '₄',
151
+ '5': '₅',
152
+ '6': '₆',
153
+ '7': '₇',
154
+ '8': '₈',
155
+ '9': '₉',
156
+ a: 'ₐ',
157
+ e: 'ₑ',
158
+ h: 'ₕ',
159
+ i: 'ᵢ',
160
+ j: 'ⱼ',
161
+ k: 'ₖ',
162
+ l: 'ₗ',
163
+ m: 'ₘ',
164
+ n: 'ₙ',
165
+ o: 'ₒ',
166
+ p: 'ₚ',
167
+ r: 'ᵣ',
168
+ s: 'ₛ',
169
+ t: 'ₜ',
170
+ u: 'ᵤ',
171
+ v: 'ᵥ',
172
+ x: 'ₓ',
173
+ '+': '₊',
174
+ '-': '₋',
175
+ '=': '₌',
176
+ '(': '₍',
177
+ ')': '₎',
99
178
  // 常见希腊字母的下标形式(如需要可加入)
100
- 'β': 'ᵦ', 'γ': 'ᵧ', 'ρ': 'ᵨ', 'φ': 'ᵩ', 'χ': 'ᵪ'
179
+ β: 'ᵦ',
180
+ γ: 'ᵧ',
181
+ ρ: 'ᵨ',
182
+ φ: 'ᵩ',
183
+ χ: 'ᵪ'
101
184
  }
102
185
 
103
186
  // helper: 从 base 映射中收集所有已知上标/下标字符(用于反向映射)
@@ -110,13 +193,10 @@ function invertMap(map: Record<string, string>): Record<string, string> {
110
193
  }
111
194
 
112
195
  const knownSupers = invertMap(baseSuperscript) // '¹' -> '¹', 'ᵃ'->'ᵃ' ...
113
- const knownSubs = invertMap(baseSubscript) // '₁' -> '₁', 'ₐ'->'ₐ' ...
196
+ const knownSubs = invertMap(baseSubscript) // '₁' -> '₁', 'ₐ'->'ₐ' ...
114
197
 
115
198
  // 生成最终的“鲁棒”映射:接受普通字符、上标字符、下标字符,统一输出目标形式
116
- function buildSuperscriptMap(
117
- baseSup: Record<string, string>,
118
- baseSub: Record<string, string>
119
- ): Record<string, string> {
199
+ function buildSuperscriptMap(baseSup: Record<string, string>, baseSub: Record<string, string>): Record<string, string> {
120
200
  const out: Record<string, string> = {}
121
201
 
122
202
  // 普通字符 -> 上标
@@ -136,10 +216,7 @@ function buildSuperscriptMap(
136
216
  return out
137
217
  }
138
218
 
139
- function buildSubscriptMap(
140
- baseSup: Record<string, string>,
141
- baseSub: Record<string, string>
142
- ): Record<string, string> {
219
+ function buildSubscriptMap(baseSup: Record<string, string>, baseSub: Record<string, string>): Record<string, string> {
143
220
  const out: Record<string, string> = {}
144
221
 
145
222
  // 普通字符 -> 下标
@@ -177,16 +254,12 @@ export function toSubscript(input: string): string {
177
254
  return out
178
255
  }
179
256
 
180
-
181
257
  export const superscriptMapVal = Object.values(superscriptMap)
182
258
 
183
259
  export const subscriptMapVal = Object.values(subscriptMap)
184
260
 
185
261
  // 构建 normalMap:所有上标、下标字符 → 对应的普通 base 字符
186
- function buildNormalMap(
187
- baseSup: Record<string, string>,
188
- baseSub: Record<string, string>
189
- ): Record<string, string> {
262
+ function buildNormalMap(baseSup: Record<string, string>, baseSub: Record<string, string>): Record<string, string> {
190
263
  const normal: Record<string, string> = {}
191
264
 
192
265
  // 上标的 value → key(普通)
@@ -213,4 +286,3 @@ export function toNormal(input: string): string {
213
286
  }
214
287
  return out
215
288
  }
216
-