@visactor/vrender-core 0.20.11-alpha.1 → 0.20.11
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.
- package/cjs/common/bezier-utils.d.ts +0 -3
- package/cjs/common/bezier-utils.js +2 -17
- package/cjs/common/bezier-utils.js.map +1 -1
- package/cjs/common/custom-path2d.d.ts +0 -3
- package/cjs/common/custom-path2d.js +11 -35
- package/cjs/common/custom-path2d.js.map +1 -1
- package/cjs/common/segment/curve/arc.d.ts +1 -2
- package/cjs/common/segment/curve/arc.js +1 -4
- package/cjs/common/segment/curve/arc.js.map +1 -1
- package/cjs/common/segment/curve/base.d.ts +1 -2
- package/cjs/common/segment/curve/base.js.map +1 -1
- package/cjs/common/segment/curve/cubic-bezier.d.ts +1 -3
- package/cjs/common/segment/curve/cubic-bezier.js +3 -14
- package/cjs/common/segment/curve/cubic-bezier.js.map +1 -1
- package/cjs/common/segment/curve/curve-context.js +4 -5
- package/cjs/common/segment/curve/curve-context.js.map +1 -1
- package/cjs/common/segment/curve/ellipse.d.ts +1 -2
- package/cjs/common/segment/curve/ellipse.js +0 -3
- package/cjs/common/segment/curve/ellipse.js.map +1 -1
- package/cjs/common/segment/curve/line.d.ts +1 -2
- package/cjs/common/segment/curve/line.js +0 -6
- package/cjs/common/segment/curve/line.js.map +1 -1
- package/cjs/common/segment/curve/move.d.ts +1 -2
- package/cjs/common/segment/curve/move.js +0 -3
- package/cjs/common/segment/curve/move.js.map +1 -1
- package/cjs/common/segment/curve/path.d.ts +1 -2
- package/cjs/common/segment/curve/path.js +2 -5
- package/cjs/common/segment/curve/path.js.map +1 -1
- package/cjs/common/segment/curve/quadratic-bezier.d.ts +2 -4
- package/cjs/common/segment/curve/quadratic-bezier.js +5 -17
- package/cjs/common/segment/curve/quadratic-bezier.js.map +1 -1
- package/cjs/common/simplify.js +2 -3
- package/cjs/common/simplify.js.map +1 -1
- package/cjs/graphic/builtin-symbol/utils.d.ts +1 -2
- package/cjs/graphic/builtin-symbol/utils.js +0 -5
- package/cjs/graphic/builtin-symbol/utils.js.map +1 -1
- package/cjs/graphic/config.js +1 -5
- package/cjs/graphic/config.js.map +1 -1
- package/cjs/graphic/graphic-service/graphic-service.d.ts +0 -2
- package/cjs/graphic/graphic-service/graphic-service.js +5 -10
- package/cjs/graphic/graphic-service/graphic-service.js.map +1 -1
- package/cjs/graphic/richtext/wrapper.d.ts +0 -1
- package/cjs/graphic/richtext/wrapper.js +1 -1
- package/cjs/graphic/richtext/wrapper.js.map +1 -1
- package/cjs/graphic/richtext.js +1 -2
- package/cjs/graphic/richtext.js.map +1 -1
- package/cjs/interface/graphic/path.d.ts +0 -1
- package/cjs/interface/graphic/path.js.map +1 -1
- package/cjs/interface/graphic/symbol.d.ts +0 -2
- package/cjs/interface/graphic/symbol.js.map +1 -1
- package/cjs/interface/graphic-service.d.ts +0 -2
- package/cjs/interface/graphic-service.js.map +1 -1
- package/cjs/interface/graphic.d.ts +1 -3
- package/cjs/interface/graphic.js.map +1 -1
- package/cjs/interface/path.d.ts +0 -2
- package/cjs/interface/path.js.map +1 -1
- package/cjs/plugins/builtin-plugin/dirty-bounds-plugin.js +0 -3
- package/cjs/plugins/builtin-plugin/dirty-bounds-plugin.js.map +1 -1
- package/cjs/plugins/builtin-plugin/edit-module.d.ts +5 -6
- package/cjs/plugins/builtin-plugin/edit-module.js +28 -84
- package/cjs/plugins/builtin-plugin/edit-module.js.map +1 -1
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin.d.ts +30 -49
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin.js +217 -280
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin.js.map +1 -1
- package/cjs/render/contributions/render/arc3d-render.js.map +1 -1
- package/cjs/render/contributions/render/base-render.d.ts +0 -1
- package/cjs/render/contributions/render/base-render.js +2 -20
- package/cjs/render/contributions/render/base-render.js.map +1 -1
- package/cjs/render/contributions/render/contributions/base-contribution-render.js.map +1 -1
- package/cjs/render/contributions/render/contributions/base-texture-contribution-render.js +2 -29
- package/cjs/render/contributions/render/contributions/base-texture-contribution-render.js.map +1 -1
- package/cjs/render/contributions/render/contributions/symbol-contribution-render.d.ts +1 -8
- package/cjs/render/contributions/render/contributions/symbol-contribution-render.js +2 -30
- package/cjs/render/contributions/render/contributions/symbol-contribution-render.js.map +1 -1
- package/cjs/render/contributions/render/group-render.js +3 -3
- package/cjs/render/contributions/render/group-render.js.map +1 -1
- package/cjs/render/contributions/render/path-render.js.map +1 -1
- package/cjs/render/contributions/render/polygon-render.js.map +1 -1
- package/cjs/render/contributions/render/symbol-render.js +12 -15
- package/cjs/render/contributions/render/symbol-render.js.map +1 -1
- package/cjs/render/contributions/render/utils.d.ts +2 -1
- package/cjs/render/contributions/render/utils.js +20 -4
- package/cjs/render/contributions/render/utils.js.map +1 -1
- package/dist/index.es.js +8138 -8650
- package/es/common/bezier-utils.d.ts +0 -3
- package/es/common/bezier-utils.js +0 -14
- package/es/common/bezier-utils.js.map +1 -1
- package/es/common/custom-path2d.d.ts +0 -3
- package/es/common/custom-path2d.js +12 -36
- package/es/common/custom-path2d.js.map +1 -1
- package/es/common/segment/curve/arc.d.ts +1 -2
- package/es/common/segment/curve/arc.js +1 -4
- package/es/common/segment/curve/arc.js.map +1 -1
- package/es/common/segment/curve/base.d.ts +1 -2
- package/es/common/segment/curve/base.js.map +1 -1
- package/es/common/segment/curve/cubic-bezier.d.ts +1 -3
- package/es/common/segment/curve/cubic-bezier.js +1 -14
- package/es/common/segment/curve/cubic-bezier.js.map +1 -1
- package/es/common/segment/curve/curve-context.js +3 -6
- package/es/common/segment/curve/curve-context.js.map +1 -1
- package/es/common/segment/curve/ellipse.d.ts +1 -2
- package/es/common/segment/curve/ellipse.js +0 -3
- package/es/common/segment/curve/ellipse.js.map +1 -1
- package/es/common/segment/curve/line.d.ts +1 -2
- package/es/common/segment/curve/line.js +0 -6
- package/es/common/segment/curve/line.js.map +1 -1
- package/es/common/segment/curve/move.d.ts +1 -2
- package/es/common/segment/curve/move.js +0 -3
- package/es/common/segment/curve/move.js.map +1 -1
- package/es/common/segment/curve/path.d.ts +1 -2
- package/es/common/segment/curve/path.js +2 -5
- package/es/common/segment/curve/path.js.map +1 -1
- package/es/common/segment/curve/quadratic-bezier.d.ts +2 -4
- package/es/common/segment/curve/quadratic-bezier.js +5 -22
- package/es/common/segment/curve/quadratic-bezier.js.map +1 -1
- package/es/common/simplify.js +2 -3
- package/es/common/simplify.js.map +1 -1
- package/es/graphic/builtin-symbol/utils.d.ts +1 -2
- package/es/graphic/builtin-symbol/utils.js +0 -5
- package/es/graphic/builtin-symbol/utils.js.map +1 -1
- package/es/graphic/config.js +1 -5
- package/es/graphic/config.js.map +1 -1
- package/es/graphic/graphic-service/graphic-service.d.ts +0 -2
- package/es/graphic/graphic-service/graphic-service.js +4 -11
- package/es/graphic/graphic-service/graphic-service.js.map +1 -1
- package/es/graphic/richtext/wrapper.d.ts +0 -1
- package/es/graphic/richtext/wrapper.js +1 -1
- package/es/graphic/richtext/wrapper.js.map +1 -1
- package/es/graphic/richtext.js +1 -2
- package/es/graphic/richtext.js.map +1 -1
- package/es/interface/graphic/path.d.ts +0 -1
- package/es/interface/graphic/path.js.map +1 -1
- package/es/interface/graphic/symbol.d.ts +0 -2
- package/es/interface/graphic/symbol.js.map +1 -1
- package/es/interface/graphic-service.d.ts +0 -2
- package/es/interface/graphic-service.js.map +1 -1
- package/es/interface/graphic.d.ts +1 -3
- package/es/interface/graphic.js.map +1 -1
- package/es/interface/path.d.ts +0 -2
- package/es/interface/path.js.map +1 -1
- package/es/plugins/builtin-plugin/dirty-bounds-plugin.js +0 -3
- package/es/plugins/builtin-plugin/dirty-bounds-plugin.js.map +1 -1
- package/es/plugins/builtin-plugin/edit-module.d.ts +5 -6
- package/es/plugins/builtin-plugin/edit-module.js +25 -79
- package/es/plugins/builtin-plugin/edit-module.js.map +1 -1
- package/es/plugins/builtin-plugin/richtext-edit-plugin.d.ts +30 -49
- package/es/plugins/builtin-plugin/richtext-edit-plugin.js +214 -283
- package/es/plugins/builtin-plugin/richtext-edit-plugin.js.map +1 -1
- package/es/render/contributions/render/arc3d-render.js.map +1 -1
- package/es/render/contributions/render/base-render.d.ts +0 -1
- package/es/render/contributions/render/base-render.js +2 -21
- package/es/render/contributions/render/base-render.js.map +1 -1
- package/es/render/contributions/render/contributions/base-contribution-render.js.map +1 -1
- package/es/render/contributions/render/contributions/base-texture-contribution-render.js +2 -29
- package/es/render/contributions/render/contributions/base-texture-contribution-render.js.map +1 -1
- package/es/render/contributions/render/contributions/symbol-contribution-render.d.ts +1 -8
- package/es/render/contributions/render/contributions/symbol-contribution-render.js +0 -26
- package/es/render/contributions/render/contributions/symbol-contribution-render.js.map +1 -1
- package/es/render/contributions/render/group-render.js +3 -3
- package/es/render/contributions/render/group-render.js.map +1 -1
- package/es/render/contributions/render/path-render.js.map +1 -1
- package/es/render/contributions/render/polygon-render.js.map +1 -1
- package/es/render/contributions/render/symbol-render.js +13 -16
- package/es/render/contributions/render/symbol-render.js.map +1 -1
- package/es/render/contributions/render/utils.d.ts +2 -1
- package/es/render/contributions/render/utils.js +18 -0
- package/es/render/contributions/render/utils.js.map +1 -1
- package/package.json +1 -1
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin-old.d.ts +0 -1
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin-old.js +0 -3
- package/cjs/plugins/builtin-plugin/richtext-edit-plugin-old.js.map +0 -1
- package/es/plugins/builtin-plugin/richtext-edit-plugin-old.d.ts +0 -1
- package/es/plugins/builtin-plugin/richtext-edit-plugin-old.js +0 -3
- package/es/plugins/builtin-plugin/richtext-edit-plugin-old.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IMatrix, IPointLike, IPoint, BoundsAnchorType, IOBBBounds } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget } from './animate';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\n\ntype IStrokeSeg = {\n start: number; // 百分比\n // end和length二选一\n end: number; // 百分比\n length: number; // 像素长度\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph'\n | string;\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n x: number;\n y: number;\n z: number;\n dx: number;\n dy: number;\n dz: number;\n scrollX: number;\n scrollY: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n angle: number;\n alpha: number;\n beta: number;\n scaleCenter: [number | string, number | string];\n anchor: [number | string, number | string]; // 基于AABB的锚点位置,用于简单的定位某些path\n anchor3d: [number | string, number | string, number] | [number | string, number | string]; // 3d的锚点位置\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n fillOpacity: number;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n fill: IFillType;\n};\n\nexport type ILayout = {\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n distance: number | string;\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n outerBorder: Partial<IBorderStyle>;\n innerBorder: Partial<IBorderStyle>;\n strokeOpacity: number;\n lineDash: number[];\n lineDashOffset: number;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n // 描边的boundsBuffer,用于控制bounds的buffer\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n // 连接,取零或者断开\n connectedType: 'connect' | 'zero' | 'none';\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\ntype IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport interface SimpleDomStyleOptions {\n width: number; // 容器的宽度\n height: number; // 容器的高度\n style?:\n | string\n | Record<string, any>\n | ((\n pos: { top: number; left: number; width: number; height: number },\n graphic: IGraphic,\n wrapContainer: HTMLElement\n ) => Record<string, any>); // 容器的样式\n}\n\nexport interface CommonDomOptions {\n id?: string;\n container: string | HTMLElement | null; // id或者dom\n visible?: boolean;\n pointerEvents?: boolean | string;\n anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType;\n}\n\nexport type IGraphicStyle = ILayout &\n IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n forceBoundsWidth: number | (() => number) | undefined;\n forceBoundsHeight: number | (() => number) | undefined;\n opacity: number;\n shadowGraphic?: IGraphic | undefined;\n backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关)\n backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n backgroundCornerRadius: number | number[];\n backgroundOpacity: number;\n // 如果做动画的话,这里代表ratio\n textureRatio: number;\n textureOptions: any;\n background:\n | IBackgroundType\n | {\n background: IBackgroundType;\n dx?: number;\n dy?: number;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n texture: TextureType | string; // 纹理\n textureColor: string; // 纹理颜色\n textureSize: number; // 纹理大小\n texturePadding: number; // 纹理间隙\n blur: number;\n cursor: Cursor | null; // 鼠标样式\n renderStyle?: 'default' | 'rough' | any;\n // HTML的dom或者string\n html:\n | ({\n dom: string | HTMLElement; // dom字符串或者dom\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n react:\n | ({\n element: any; // react场景节点\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n };\n\nexport type IPickStyle = {\n // 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n // 包围盒的padding\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n zIndex: number;\n layout: any;\n /**\n * 是否隐藏元素(只是绘制的时候不绘制)\n */\n renderable: boolean;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n shadowPickMode?: 'full' | 'graphic';\n globalZIndex: number;\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n // 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n // 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制\n fillStrokeOrder: number;\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n slience?: boolean;\n id?: number | string;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n attachedThemeGraphic?: IGraphic<any>;\n\n bindDom?: Map<\n string | HTMLElement,\n { container: HTMLElement | string; dom: HTMLElement | any; wrapGroup: HTMLDivElement | any; root?: any }\n >;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: Record<string, Partial<T>>;\n normalAttrs?: Partial<T>;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string, hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (attrs: Partial<T>, stateNames: string[], hasAnimation?: boolean, isClear?: boolean) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n getGraphicTheme: () => T;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IMatrix, IPointLike, IPoint, BoundsAnchorType, IOBBBounds } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget } from './animate';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\n\ntype IStrokeSeg = {\n start: number; // 百分比\n // end和length二选一\n end: number; // 百分比\n length: number; // 像素长度\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph';\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n x: number;\n y: number;\n z: number;\n dx: number;\n dy: number;\n dz: number;\n scrollX: number;\n scrollY: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n angle: number;\n alpha: number;\n beta: number;\n scaleCenter: [number | string, number | string];\n anchor: [number | string, number | string]; // 基于AABB的锚点位置,用于简单的定位某些path\n anchor3d: [number | string, number | string, number] | [number | string, number | string]; // 3d的锚点位置\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n fillOpacity: number;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n fill: IFillType;\n};\n\nexport type ILayout = {\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n distance: number | string;\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n outerBorder: Partial<IBorderStyle>;\n innerBorder: Partial<IBorderStyle>;\n strokeOpacity: number;\n lineDash: number[];\n lineDashOffset: number;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n // 描边的boundsBuffer,用于控制bounds的buffer\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n // 连接,取零或者断开\n connectedType: 'connect' | 'zero' | 'none';\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\ntype IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport interface SimpleDomStyleOptions {\n width: number; // 容器的宽度\n height: number; // 容器的高度\n style?:\n | string\n | Record<string, any>\n | ((\n pos: { top: number; left: number; width: number; height: number },\n graphic: IGraphic,\n wrapContainer: HTMLElement\n ) => Record<string, any>); // 容器的样式\n}\n\nexport interface CommonDomOptions {\n id?: string;\n container: string | HTMLElement | null; // id或者dom\n visible?: boolean;\n pointerEvents?: boolean | string;\n anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType;\n}\n\nexport type IGraphicStyle = ILayout &\n IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n forceBoundsWidth: number | (() => number) | undefined;\n forceBoundsHeight: number | (() => number) | undefined;\n opacity: number;\n shadowGraphic?: IGraphic | undefined;\n backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关)\n backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n backgroundCornerRadius: number | number[];\n backgroundOpacity: number;\n background:\n | IBackgroundType\n | {\n background: IBackgroundType;\n dx?: number;\n dy?: number;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n texture: TextureType | string; // 纹理\n textureColor: string; // 纹理颜色\n textureSize: number; // 纹理大小\n texturePadding: number; // 纹理间隙\n blur: number;\n cursor: Cursor | null; // 鼠标样式\n renderStyle?: 'default' | 'rough' | any;\n // HTML的dom或者string\n html:\n | ({\n dom: string | HTMLElement; // dom字符串或者dom\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n react:\n | ({\n element: any; // react场景节点\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n };\n\nexport type IPickStyle = {\n // 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n // 包围盒的padding\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n zIndex: number;\n layout: any;\n /**\n * 是否隐藏元素(只是绘制的时候不绘制)\n */\n renderable: boolean;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n shadowPickMode?: 'full' | 'graphic';\n globalZIndex: number;\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n // 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n // 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制\n fillStrokeOrder: number;\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n slience?: boolean;\n id?: number | string;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n attachedThemeGraphic?: IGraphic<any>;\n\n bindDom?: Map<\n string | HTMLElement,\n { container: HTMLElement | string; dom: HTMLElement | any; wrapGroup: HTMLDivElement | any; root?: any }\n >;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: Record<string, Partial<T>>;\n normalAttrs?: Partial<T>;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string, hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (attrs: Partial<T>, stateNames: string[], hasAnimation?: boolean, isClear?: boolean) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n getGraphicTheme: () => T;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
package/cjs/interface/path.d.ts
CHANGED
|
@@ -36,7 +36,6 @@ export interface ICurve<T> {
|
|
|
36
36
|
getPointAt: (t: number) => IPointLike;
|
|
37
37
|
getAngleAt: (t: number) => number;
|
|
38
38
|
getLength: (direction?: IDirection) => number;
|
|
39
|
-
draw: (path: IPath2D, x: number, y: number, sx: number, sy: number, percent: number) => void;
|
|
40
39
|
}
|
|
41
40
|
export interface ICubicBezierCurve extends ICurve<IPoint> {
|
|
42
41
|
type: CurveTypeEnum.CubicBezierCurve;
|
|
@@ -98,5 +97,4 @@ export interface ICustomPath2D extends ICurvePath<IPoint>, IPath2D, Releaseable
|
|
|
98
97
|
fromCustomPath2D: (path: ICustomPath2D, x?: number, y?: number, sX?: number, sY?: number) => ICustomPath2D;
|
|
99
98
|
addCurve: (curve: ICurve<IPoint>) => void;
|
|
100
99
|
clear: () => void;
|
|
101
|
-
drawWithClipRange: (ctx: IPath2D, size: number, x: number, y: number, clipRange: number) => void;
|
|
102
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/path.ts"],"names":[],"mappings":";;;AAIa,QAAA,aAAa,GAAG;IAC3B,KAAK;IACL,OAAO;IACP,eAAe;IACf,WAAW;IACX,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,kBAAkB;IAClB,MAAM;CACP,CAAC","file":"path.js","sourcesContent":["import type { IAABBBounds, IPoint, IPointLike } from '@visactor/vutils';\nimport type { Releaseable, IDirection } from './common';\nimport type { CurveTypeEnum } from '../common/enums';\n\nexport const strCommandMap = [\n 'arc',\n 'arcTo',\n 'bezierCurveTo',\n 'closePath',\n 'ellipse',\n 'lineTo',\n 'moveTo',\n 'quadraticCurveTo',\n 'rect'\n];\n\nexport type CommandType = [\n number,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?\n];\n\nexport type CommandStrType = [\n string,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?\n];\n\nexport interface ICurve<T> {\n type: number;\n defined: boolean;\n originP1?: IPointLike;\n originP2?: IPointLike;\n readonly p0: T;\n readonly p1?: T;\n readonly p2?: T;\n readonly p3?: T;\n getPointAt: (t: number) => IPointLike;\n getAngleAt: (t: number) => number;\n getLength: (direction?: IDirection) => number;\n
|
|
1
|
+
{"version":3,"sources":["../src/interface/path.ts"],"names":[],"mappings":";;;AAIa,QAAA,aAAa,GAAG;IAC3B,KAAK;IACL,OAAO;IACP,eAAe;IACf,WAAW;IACX,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,kBAAkB;IAClB,MAAM;CACP,CAAC","file":"path.js","sourcesContent":["import type { IAABBBounds, IPoint, IPointLike } from '@visactor/vutils';\nimport type { Releaseable, IDirection } from './common';\nimport type { CurveTypeEnum } from '../common/enums';\n\nexport const strCommandMap = [\n 'arc',\n 'arcTo',\n 'bezierCurveTo',\n 'closePath',\n 'ellipse',\n 'lineTo',\n 'moveTo',\n 'quadraticCurveTo',\n 'rect'\n];\n\nexport type CommandType = [\n number,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?\n];\n\nexport type CommandStrType = [\n string,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?,\n (number | boolean)?\n];\n\nexport interface ICurve<T> {\n type: number;\n defined: boolean;\n originP1?: IPointLike;\n originP2?: IPointLike;\n readonly p0: T;\n readonly p1?: T;\n readonly p2?: T;\n readonly p3?: T;\n getPointAt: (t: number) => IPointLike;\n getAngleAt: (t: number) => number;\n getLength: (direction?: IDirection) => number;\n}\n\nexport interface ICubicBezierCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.CubicBezierCurve;\n // p0: IPoint;\n readonly p1: IPoint;\n readonly p2: IPoint;\n readonly p3: IPoint;\n}\n\nexport interface IQuadraticBezierCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.QuadraticBezierCurve;\n // p0: IPoint;\n readonly p1: IPoint;\n readonly p2: IPoint;\n}\n\nexport interface IArcCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.ArcCurve;\n // p0: IPoint;\n readonly p1: IPoint;\n radius: number;\n}\n\nexport interface ILineCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.LineCurve;\n // p0: IPoint;\n readonly p1: IPoint;\n}\n\nexport interface IEllipseCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.EllipseCurve;\n // p0: IPoint;\n radiusX: number;\n radiusY: number;\n rotation: number;\n startAngle: number;\n endAngle: number;\n anticlockwise?: boolean;\n}\n\nexport interface IMoveCurve extends ICurve<IPoint> {\n type: CurveTypeEnum.MoveCurve;\n // p0: IPoint;\n readonly p1: IPoint;\n}\n\nexport interface ICurvePath<T> {\n curves: ICurve<T>[];\n bounds?: IAABBBounds;\n getPointAt: (t: number) => IPointLike;\n getCurveLengths: () => number[];\n getLength: (direction?: IDirection) => number;\n getBounds?: () => IAABBBounds;\n}\n\nexport interface IPath2D {\n moveTo: (x: number, y: number, z?: number) => void;\n lineTo: (x: number, y: number, z?: number) => void;\n quadraticCurveTo: (aCPx: number, aCPy: number, aX: number, aY: number, z?: number) => void;\n bezierCurveTo: (\n aCP1x: number,\n aCP1y: number,\n aCP2x: number,\n aCP2y: number,\n aX: number,\n aY: number,\n z?: number\n ) => void;\n arcTo: (aX1: number, aY1: number, aX2: number, aY2: number, aRadius: number, z?: number) => void;\n ellipse: (\n aX: number,\n aY: number,\n xRadius: number,\n yRadius: number,\n aRotation: number,\n aStartAngle: number,\n aEndAngle: number,\n aClockwise: boolean\n ) => void;\n rect: (x: number, y: number, w: number, h: number, z?: number) => void;\n arc: (\n x: number,\n y: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n counterclockwise?: boolean,\n z?: number\n ) => void;\n closePath: () => void;\n}\n\n// 用户可以直接操作path2D\nexport interface ICustomPath2D extends ICurvePath<IPoint>, IPath2D, Releaseable {\n commandList: CommandType[];\n\n toString: () => string;\n transform: (x: number, y: number, sx: number, sy: number) => void;\n fromString: (pathStr: string, x?: number, y?: number, sX?: number, sY?: number) => ICustomPath2D;\n fromCustomPath2D: (path: ICustomPath2D, x?: number, y?: number, sX?: number, sY?: number) => ICustomPath2D;\n addCurve: (curve: ICurve<IPoint>) => void;\n clear: () => void;\n}\n"]}
|
|
@@ -19,8 +19,6 @@ class DirtyBoundsPlugin {
|
|
|
19
19
|
stage.dirty(globalBounds, graphic.parent && graphic.parent.globalTransMatrix)));
|
|
20
20
|
})), application_1.application.graphicService.hooks.afterUpdateAABBBounds.tap(this.key, ((graphic, stage, bounds, params, selfChange) => {
|
|
21
21
|
stage && stage === this.pluginService.stage && stage.renderCount && (graphic.isContainer && !selfChange || stage.dirty(params.globalAABBBounds));
|
|
22
|
-
})), application_1.application.graphicService.hooks.clearAABBBounds.tap(this.key, ((graphic, stage, bounds) => {
|
|
23
|
-
stage && stage === this.pluginService.stage && stage.renderCount && stage && stage.dirty(bounds);
|
|
24
22
|
})), application_1.application.graphicService.hooks.onRemove.tap(this.key, (graphic => {
|
|
25
23
|
const stage = graphic.stage;
|
|
26
24
|
stage && stage === this.pluginService.stage && stage.renderCount && stage && stage.dirty(graphic.globalAABBBounds);
|
|
@@ -29,7 +27,6 @@ class DirtyBoundsPlugin {
|
|
|
29
27
|
deactivate(context) {
|
|
30
28
|
application_1.application.graphicService.hooks.beforeUpdateAABBBounds.taps = application_1.application.graphicService.hooks.beforeUpdateAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
31
29
|
application_1.application.graphicService.hooks.afterUpdateAABBBounds.taps = application_1.application.graphicService.hooks.afterUpdateAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
32
|
-
application_1.application.graphicService.hooks.clearAABBBounds.taps = application_1.application.graphicService.hooks.clearAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
33
30
|
context.stage.hooks.afterRender.taps = context.stage.hooks.afterRender.taps.filter((item => item.name !== this.key)),
|
|
34
31
|
application_1.application.graphicService.hooks.onRemove.taps = application_1.application.graphicService.hooks.onRemove.taps.filter((item => item.name !== this.key));
|
|
35
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugins/builtin-plugin/dirty-bounds-plugin.ts"],"names":[],"mappings":";;;AACA,6CAA8C;AAC9C,sDAAmD;AAEnD,mDAAgD;AAEhD,MAAM,YAAY,GAAG,IAAI,mBAAU,EAAE,CAAC;AAEtC,MAAa,iBAAiB;IAA9B;QACE,SAAI,GAAwB,mBAAmB,CAAC;QAChD,gBAAW,GAAiB,YAAY,CAAC;QAEzC,SAAI,GAAW,qBAAS,CAAC,kBAAkB,EAAE,CAAC;QAC9C,QAAG,GAAW,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"sources":["../src/plugins/builtin-plugin/dirty-bounds-plugin.ts"],"names":[],"mappings":"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","file":"dirty-bounds-plugin.js","sourcesContent":["import type { IAABBBounds } from '@visactor/vutils';\nimport { AABBBounds } from '@visactor/vutils';\nimport { Generator } from '../../common/generator';\nimport type { IGraphic, IStage, IPlugin, IPluginService } from '../../interface';\nimport { application } from '../../application';\n\nconst globalBounds = new AABBBounds();\n\nexport class DirtyBoundsPlugin implements IPlugin {\n name: 'DirtyBoundsPlugin' = 'DirtyBoundsPlugin';\n activeEvent: 'onRegister' = 'onRegister';\n pluginService: IPluginService;\n _uid: number = Generator.GenAutoIncrementId();\n key: string = this.name + this._uid;\n\n activate(context: IPluginService): void {\n this.pluginService = context;\n context.stage.hooks.afterRender.tap(this.key, stage => {\n if (!(stage && stage === this.pluginService.stage)) {\n return;\n }\n stage.dirtyBounds.clear();\n });\n application.graphicService.hooks.beforeUpdateAABBBounds.tap(\n this.key,\n (graphic: IGraphic, stage: IStage, willUpdate: boolean, bounds: IAABBBounds) => {\n if (graphic.glyphHost) {\n graphic = graphic.glyphHost;\n }\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !graphic.shouldSelfChangeUpdateAABBBounds()) {\n return;\n }\n if (willUpdate) {\n globalBounds.setValue(bounds.x1, bounds.y1, bounds.x2, bounds.y2);\n stage.dirty(globalBounds, graphic.parent && graphic.parent.globalTransMatrix);\n }\n }\n );\n application.graphicService.hooks.afterUpdateAABBBounds.tap(\n this.key,\n (\n graphic: IGraphic,\n stage: IStage,\n bounds: IAABBBounds,\n params: { globalAABBBounds: IAABBBounds },\n selfChange: boolean\n ) => {\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !selfChange) {\n return;\n }\n stage.dirty(params.globalAABBBounds);\n }\n );\n application.graphicService.hooks.onRemove.tap(this.key, (graphic: IGraphic) => {\n const stage = graphic.stage;\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n if (stage) {\n stage.dirty(graphic.globalAABBBounds);\n }\n });\n }\n deactivate(context: IPluginService): void {\n application.graphicService.hooks.beforeUpdateAABBBounds.taps =\n application.graphicService.hooks.beforeUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n application.graphicService.hooks.afterUpdateAABBBounds.taps =\n application.graphicService.hooks.afterUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n context.stage.hooks.afterRender.taps = context.stage.hooks.afterRender.taps.filter(item => {\n return item.name !== this.key;\n });\n application.graphicService.hooks.onRemove.taps = application.graphicService.hooks.onRemove.taps.filter(item => {\n return item.name !== this.key;\n });\n }\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { IRichText, IRichTextCharacter } from '../../interface';
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function textConfigIgnoreLinebreakIdxToCursorIdx(textConfig: IRichTextCharacter[], cursorIndex: number): number;
|
|
2
|
+
export declare function findCursorIndexIgnoreLinebreak(textConfig: IRichTextCharacter[], cursorIndex: number): number;
|
|
4
3
|
export declare class EditModule {
|
|
5
4
|
container: HTMLElement;
|
|
6
5
|
textAreaDom: HTMLTextAreaElement;
|
|
@@ -8,11 +7,11 @@ export declare class EditModule {
|
|
|
8
7
|
isComposing: boolean;
|
|
9
8
|
cursorIndex: number;
|
|
10
9
|
selectionStartCursorIdx: number;
|
|
11
|
-
onInputCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void>;
|
|
12
|
-
onChangeCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void>;
|
|
10
|
+
onInputCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void>;
|
|
11
|
+
onChangeCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void>;
|
|
13
12
|
constructor(container?: HTMLElement);
|
|
14
|
-
onInput(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void): void;
|
|
15
|
-
onChange(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void): void;
|
|
13
|
+
onInput(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void): void;
|
|
14
|
+
onChange(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void): void;
|
|
16
15
|
applyStyle(textAreaDom: HTMLTextAreaElement): void;
|
|
17
16
|
handleKeyDown: (e: KeyboardEvent) => void;
|
|
18
17
|
handleCompositionStart: () => void;
|
|
@@ -1,51 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var t = {};
|
|
5
|
-
for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
|
|
6
|
-
if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
|
|
7
|
-
var i = 0;
|
|
8
|
-
for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
Object.defineProperty(exports, "__esModule", {
|
|
14
|
-
value: !0
|
|
15
|
-
}), exports.EditModule = exports.textConfigIgnoreLinebreakIdxToCursorIdx = exports.findConfigIndex = void 0;
|
|
16
|
-
|
|
17
|
-
const application_1 = require("../../application");
|
|
18
|
-
|
|
19
|
-
function getMaxConfigIndexIgnoreLinebreak(textConfig) {
|
|
20
|
-
let idx = 0;
|
|
21
|
-
for (let i = 0; i < textConfig.length; i++) {
|
|
22
|
-
"\n" !== textConfig[i].text && idx++;
|
|
23
|
-
}
|
|
24
|
-
return Math.max(idx - 1, 0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function findConfigIndex(textConfig, cursorIndex) {
|
|
3
|
+
function findCursorIndexIgnoreLinebreak(textConfig, cursorIndex) {
|
|
28
4
|
let index = 0;
|
|
29
|
-
if (cursorIndex < 0) return -1;
|
|
30
|
-
let idx = Math.round(cursorIndex);
|
|
31
5
|
for (index = 0; index < textConfig.length; index++) {
|
|
32
|
-
|
|
6
|
+
const c = textConfig[index];
|
|
7
|
+
if (c.text && "\n" === c.text || cursorIndex--, cursorIndex < 0) break;
|
|
33
8
|
}
|
|
34
|
-
return
|
|
35
|
-
Math.min(index, textConfig.length - 1);
|
|
9
|
+
return index;
|
|
36
10
|
}
|
|
37
11
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for (let i = 0; i < cursorIndex; i++) {
|
|
42
|
-
"\n" !== textConfig[i].text && index++;
|
|
43
|
-
}
|
|
44
|
-
return "\n" === (null === (_a = textConfig[cursorIndex]) || void 0 === _a ? void 0 : _a.text) ? index -= .1 : index += .1,
|
|
45
|
-
index;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
exports.findConfigIndex = findConfigIndex, exports.textConfigIgnoreLinebreakIdxToCursorIdx = textConfigIgnoreLinebreakIdxToCursorIdx;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", {
|
|
13
|
+
value: !0
|
|
14
|
+
}), exports.EditModule = exports.findCursorIndexIgnoreLinebreak = void 0, exports.findCursorIndexIgnoreLinebreak = findCursorIndexIgnoreLinebreak;
|
|
49
15
|
|
|
50
16
|
class EditModule {
|
|
51
17
|
constructor(container) {
|
|
@@ -55,67 +21,45 @@ class EditModule {
|
|
|
55
21
|
type: "Backspace"
|
|
56
22
|
});
|
|
57
23
|
}, this.handleCompositionStart = () => {
|
|
58
|
-
const {textConfig: textConfig = []} = this.currRt.attribute;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
fill: "black"
|
|
63
|
-
}, config), {
|
|
64
|
-
text: ""
|
|
65
|
-
}));
|
|
66
|
-
} else {
|
|
67
|
-
const cursorIndex = findConfigIndex(textConfig, this.cursorIndex), lastConfig = textConfig[cursorIndex];
|
|
68
|
-
textConfig.splice(cursorIndex + 1, 0, Object.assign(Object.assign({}, lastConfig), {
|
|
69
|
-
text: ""
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
this.isComposing = !0;
|
|
24
|
+
const {textConfig: textConfig = []} = this.currRt.attribute, cursorIndex = findCursorIndexIgnoreLinebreak(textConfig, this.cursorIndex), lastConfig = textConfig[cursorIndex];
|
|
25
|
+
textConfig.splice(cursorIndex + 1, 0, Object.assign(Object.assign({}, lastConfig), {
|
|
26
|
+
text: ""
|
|
27
|
+
})), this.isComposing = !0;
|
|
73
28
|
}, this.handleCompositionEnd = () => {
|
|
74
29
|
this.isComposing = !1;
|
|
75
|
-
const {textConfig: textConfig = []} = this.currRt.attribute,
|
|
76
|
-
textConfig.splice(
|
|
77
|
-
const text = lastConfig.text, textList =
|
|
78
|
-
for (let i = 0; i < textList.length; i++) textConfig.splice(i +
|
|
30
|
+
const {textConfig: textConfig = []} = this.currRt.attribute, curIdx = findCursorIndexIgnoreLinebreak(textConfig, this.cursorIndex + 1), lastConfig = textConfig[curIdx];
|
|
31
|
+
textConfig.splice(curIdx, 1);
|
|
32
|
+
const text = lastConfig.text, textList = Array.from(text.toString());
|
|
33
|
+
for (let i = 0; i < textList.length; i++) textConfig.splice(i + curIdx, 0, Object.assign(Object.assign({}, lastConfig), {
|
|
79
34
|
text: textList[i]
|
|
80
35
|
}));
|
|
81
36
|
this.currRt.setAttributes({
|
|
82
37
|
textConfig: textConfig
|
|
83
38
|
}), this.onChangeCbList.forEach((cb => {
|
|
84
|
-
cb(text, this.isComposing,
|
|
39
|
+
cb(text, this.isComposing, this.cursorIndex + textList.length, this.currRt, "right");
|
|
85
40
|
}));
|
|
86
41
|
}, this.handleInput = ev => {
|
|
87
|
-
var _a, _b, _c, _d;
|
|
88
42
|
if (!this.currRt) return;
|
|
89
|
-
const _e = this.currRt.attribute, {textConfig: textConfig = []} = _e, rest = __rest(_e, [ "textConfig" ]);
|
|
90
|
-
if ("Backspace" === ev.type && !textConfig.length) return;
|
|
91
43
|
let str = ev.data;
|
|
92
|
-
|
|
44
|
+
"Backspace" === ev.type || str || (str = "\n");
|
|
45
|
+
const {textConfig: textConfig = []} = this.currRt.attribute;
|
|
93
46
|
let startIdx = this.selectionStartCursorIdx, endIdx = this.cursorIndex;
|
|
94
47
|
startIdx > endIdx && ([startIdx, endIdx] = [ endIdx, startIdx ]), this.selectionStartCursorIdx = startIdx,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
let lastConfig = textConfig[lastConfigIdx];
|
|
100
|
-
lastConfig || (lastConfig = 0 === textConfig.length ? {
|
|
101
|
-
fill: null !== (_a = rest.fill) && void 0 !== _a ? _a : "black",
|
|
102
|
-
stroke: null !== (_b = rest.stroke) && void 0 !== _b && _b,
|
|
103
|
-
fontSize: null !== (_c = rest.fontSize) && void 0 !== _c ? _c : 12,
|
|
104
|
-
fontWeight: null !== (_d = rest.fontWeight) && void 0 !== _d ? _d : "normal"
|
|
105
|
-
} : textConfig[lastConfigIdx - 1] || textConfig[lastConfigIdx + 1]);
|
|
48
|
+
this.cursorIndex = startIdx, startIdx = findCursorIndexIgnoreLinebreak(textConfig, startIdx);
|
|
49
|
+
const delta = this.selectionStartCursorIdx - startIdx;
|
|
50
|
+
endIdx = findCursorIndexIgnoreLinebreak(textConfig, endIdx);
|
|
51
|
+
const lastConfig = textConfig[startIdx + (this.isComposing ? 1 : 0)];
|
|
106
52
|
let currConfig = lastConfig;
|
|
107
53
|
"Backspace" !== ev.type || this.isComposing ? (startIdx !== endIdx && textConfig.splice(startIdx + 1, endIdx - startIdx),
|
|
108
54
|
this.isComposing || (currConfig = Object.assign(Object.assign({}, lastConfig), {
|
|
109
55
|
text: ""
|
|
110
|
-
}), startIdx += 1, textConfig.splice(startIdx, 0, currConfig)), currConfig.text = str,
|
|
111
|
-
textConfig.length || textConfig.push(currConfig)) : startIdx !== endIdx ? textConfig.splice(startIdx + 1, endIdx - startIdx) : (textConfig.splice(startIdx, 1),
|
|
56
|
+
}), startIdx += 1, textConfig.splice(startIdx, 0, currConfig)), currConfig.text = str) : startIdx !== endIdx ? textConfig.splice(startIdx + 1, endIdx - startIdx) : (textConfig.splice(startIdx, 1),
|
|
112
57
|
startIdx -= 1), this.currRt.setAttributes({
|
|
113
58
|
textConfig: textConfig
|
|
114
|
-
}), this.
|
|
115
|
-
|
|
116
|
-
cb(str, this.isComposing, this.cursorIndex, this.currRt);
|
|
59
|
+
}), this.isComposing ? this.onInputCbList.forEach((cb => {
|
|
60
|
+
cb(str, this.isComposing, startIdx + delta, this.currRt, "\n" === str ? "left" : "right");
|
|
117
61
|
})) : this.onChangeCbList.forEach((cb => {
|
|
118
|
-
cb(str, this.isComposing,
|
|
62
|
+
cb(str, this.isComposing, startIdx + delta, this.currRt, "\n" === str ? "left" : "right");
|
|
119
63
|
}));
|
|
120
64
|
}, this.container = null != container ? container : document.body;
|
|
121
65
|
const textAreaDom = document.createElement("textarea");
|
|
@@ -132,7 +76,7 @@ class EditModule {
|
|
|
132
76
|
applyStyle(textAreaDom) {
|
|
133
77
|
textAreaDom.setAttribute("style", "width: 100px; height: 30px; left: 0; top: 0; position: absolute; z-index: -1; outline: none; resize: none; border: none; overflow: hidden; color: transparent; user-select: none; caret-color: transparent;background-color: transparent;"),
|
|
134
78
|
textAreaDom.addEventListener("input", this.handleInput), textAreaDom.addEventListener("compositionstart", this.handleCompositionStart),
|
|
135
|
-
textAreaDom.addEventListener("compositionend", this.handleCompositionEnd),
|
|
79
|
+
textAreaDom.addEventListener("compositionend", this.handleCompositionEnd), window.addEventListener("keydown", this.handleKeyDown);
|
|
136
80
|
}
|
|
137
81
|
moveTo(x, y, rt, cursorIndex, selectionStartCursorIdx) {
|
|
138
82
|
this.textAreaDom.style.left = `${x}px`, this.textAreaDom.style.top = `${y}px`, setTimeout((() => {
|
|
@@ -142,7 +86,7 @@ class EditModule {
|
|
|
142
86
|
release() {
|
|
143
87
|
this.textAreaDom.removeEventListener("input", this.handleInput), this.textAreaDom.removeEventListener("compositionstart", this.handleCompositionStart),
|
|
144
88
|
this.textAreaDom.removeEventListener("compositionend", this.handleCompositionEnd),
|
|
145
|
-
|
|
89
|
+
window.removeEventListener("keydown", this.handleKeyDown);
|
|
146
90
|
}
|
|
147
91
|
}
|
|
148
92
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugins/builtin-plugin/edit-module.ts"],"names":[],"mappings":"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","file":"edit-module.js","sourcesContent":["import { application } from '../../application';\nimport type { IRichText, IRichTextCharacter, IRichTextParagraphCharacter } from '../../interface';\nimport { IRichTextIcon, IRichTextParagraph } from '../../interface';\n\nfunction getMaxConfigIndexIgnoreLinebreak(textConfig: IRichTextCharacter[]) {\n let idx = 0;\n for (let i = 0; i < textConfig.length; i++) {\n const c = textConfig[i] as IRichTextParagraphCharacter;\n if (c.text !== '\\n') {\n idx++;\n }\n }\n return Math.max(idx - 1, 0);\n}\n\n/**\n * 找到cursorIndex所在的textConfig的位置,忽略换行符\n * @param textConfig\n * @param cursorIndex\n * @returns\n */\nexport function findConfigIndex(textConfig: IRichTextCharacter[], cursorIndex: number): number {\n let index = 0;\n // 小于0是在最前面了\n if (cursorIndex < 0) {\n return -1;\n }\n let idx = Math.round(cursorIndex);\n for (index = 0; index < textConfig.length; index++) {\n const c = textConfig[index] as IRichTextParagraphCharacter;\n if (c.text !== '\\n') {\n idx--;\n }\n if (idx < 0) {\n break;\n }\n }\n if (cursorIndex - Math.round(cursorIndex) < 0) {\n index--;\n }\n index = Math.max(index, 0);\n // 避免超过限度,最后一个字符可能是换行符,算一个字符\n return Math.min(index, textConfig.length - 1);\n}\n\nexport function textConfigIgnoreLinebreakIdxToCursorIdx(textConfig: IRichTextCharacter[], cursorIndex: number): number {\n let index = 0;\n for (let i = 0; i < cursorIndex; i++) {\n const c = textConfig[i] as IRichTextParagraphCharacter;\n if (c.text !== '\\n') {\n index++;\n }\n }\n // 正常Cursor是放在右边的,但如果回退到换行符了,那就放在左侧\n if ((textConfig[cursorIndex] as any)?.text === '\\n') {\n index -= 0.1;\n } else {\n index += 0.1;\n }\n return index;\n}\n\nexport class EditModule {\n container: HTMLElement;\n textAreaDom: HTMLTextAreaElement;\n currRt: IRichText;\n isComposing: boolean;\n cursorIndex: number;\n selectionStartCursorIdx: number;\n // 输入的回调(composing的时候每次也会触发)\n onInputCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void>;\n // change的回调(composing确认才会触发)\n onChangeCbList: Array<(text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void>;\n\n constructor(container?: HTMLElement) {\n this.container = container ?? document.body;\n\n const textAreaDom = document.createElement('textarea');\n textAreaDom.autocomplete = 'off';\n textAreaDom.innerText = '';\n this.applyStyle(textAreaDom);\n this.container.append(textAreaDom);\n this.textAreaDom = textAreaDom;\n this.isComposing = false;\n this.onInputCbList = [];\n this.onChangeCbList = [];\n }\n\n onInput(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void) {\n this.onInputCbList.push(cb);\n }\n\n onChange(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void) {\n this.onChangeCbList.push(cb);\n }\n\n applyStyle(textAreaDom: HTMLTextAreaElement) {\n textAreaDom.setAttribute(\n 'style',\n `width: 100px; height: 30px; left: 0; top: 0; position: absolute; z-index: -1; outline: none; resize: none; border: none; overflow: hidden; color: transparent; user-select: none; caret-color: transparent;background-color: transparent;`\n );\n\n textAreaDom.addEventListener('input', this.handleInput);\n textAreaDom.addEventListener('compositionstart', this.handleCompositionStart);\n textAreaDom.addEventListener('compositionend', this.handleCompositionEnd);\n application.global.addEventListener('keydown', this.handleKeyDown);\n }\n\n handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n this.handleInput({ data: null, type: 'Backspace' });\n }\n };\n\n handleCompositionStart = () => {\n const { textConfig = [] } = this.currRt.attribute;\n if (this.cursorIndex < 0) {\n const config = textConfig[0];\n textConfig.unshift({ fill: 'black', ...config, text: '' });\n } else {\n const cursorIndex = findConfigIndex(textConfig, this.cursorIndex);\n const lastConfig = textConfig[cursorIndex];\n textConfig.splice(cursorIndex + 1, 0, { ...lastConfig, text: '' });\n }\n\n this.isComposing = true;\n };\n handleCompositionEnd = () => {\n this.isComposing = false;\n // 拆分上一次的内容\n const { textConfig = [] } = this.currRt.attribute;\n const configIdx = findConfigIndex(textConfig, this.cursorIndex + 1);\n\n const lastConfig = textConfig[configIdx];\n textConfig.splice(configIdx, 1);\n const text = (lastConfig as any).text;\n const textList: string[] = text ? Array.from(text.toString()) : [];\n for (let i = 0; i < textList.length; i++) {\n textConfig.splice(i + configIdx, 0, { ...lastConfig, text: textList[i] });\n }\n this.currRt.setAttributes({ textConfig });\n this.onChangeCbList.forEach(cb => {\n cb(\n text,\n this.isComposing,\n // TODO 当换行后刚开始输入会有问题,后续看这里具体Cursor变换逻辑\n Math.min(this.cursorIndex + textList.length, getMaxConfigIndexIgnoreLinebreak(textConfig) + 0.1),\n this.currRt\n );\n });\n };\n\n handleInput = (ev: any) => {\n if (!this.currRt) {\n return;\n }\n\n // 如果是回车,那就不往后+1\n const { textConfig = [], ...rest } = this.currRt.attribute;\n // 删完了,直接返回\n if (ev.type === 'Backspace' && !textConfig.length) {\n return;\n }\n\n let str = (ev as any).data;\n if (!this.isComposing && ev.type !== 'Backspace' && !str) {\n str = '\\n';\n }\n\n // 如果有选中多个文字,那就先删除\n let startIdx = this.selectionStartCursorIdx;\n let endIdx = this.cursorIndex;\n if (startIdx > endIdx) {\n [startIdx, endIdx] = [endIdx, startIdx];\n }\n // 无论是否composition都立刻恢复到没有选中的idx状态\n this.selectionStartCursorIdx = startIdx;\n\n // 转换成基于textConfig的\n // let delta = 0;\n startIdx = findConfigIndex(textConfig, startIdx);\n // delta = this.selectionStartCursorIdx - startIdx;\n endIdx = findConfigIndex(textConfig, endIdx);\n // console.log(startIdx, delta, endIdx);\n\n let idxDelta = 0;\n // 如果是换行,得往回一格\n if (str === '\\n') {\n idxDelta = -0.2;\n }\n\n const lastConfigIdx = startIdx + (this.isComposing ? 1 : 0);\n let lastConfig: any = textConfig[lastConfigIdx];\n if (!lastConfig) {\n if (textConfig.length === 0) {\n lastConfig = {\n fill: rest.fill ?? 'black',\n stroke: rest.stroke ?? false,\n fontSize: rest.fontSize ?? 12,\n fontWeight: rest.fontWeight ?? 'normal'\n };\n } else {\n lastConfig = textConfig[lastConfigIdx - 1] || textConfig[lastConfigIdx + 1];\n }\n }\n let currConfig = lastConfig;\n if (ev.type === 'Backspace' && !this.isComposing) {\n if (startIdx !== endIdx) {\n textConfig.splice(startIdx + 1, endIdx - startIdx);\n } else {\n textConfig.splice(startIdx, 1);\n startIdx -= 1;\n }\n } else {\n if (startIdx !== endIdx) {\n textConfig.splice(startIdx + 1, endIdx - startIdx);\n }\n\n if (!this.isComposing) {\n currConfig = { ...lastConfig, text: '' };\n startIdx += 1;\n textConfig.splice(startIdx, 0, currConfig);\n }\n (currConfig as any).text = str;\n if (!textConfig.length) {\n textConfig.push(currConfig);\n }\n }\n\n this.currRt.setAttributes({ textConfig });\n this.cursorIndex = textConfigIgnoreLinebreakIdxToCursorIdx(textConfig, startIdx);\n\n this.cursorIndex += idxDelta;\n if (!this.isComposing) {\n this.onChangeCbList.forEach(cb => {\n cb(str, this.isComposing, this.cursorIndex, this.currRt);\n });\n } else {\n this.onInputCbList.forEach(cb => {\n cb(str, this.isComposing, this.cursorIndex, this.currRt);\n });\n }\n };\n\n moveTo(x: number, y: number, rt: IRichText, cursorIndex: number, selectionStartCursorIdx: number) {\n this.textAreaDom.style.left = `${x}px`;\n this.textAreaDom.style.top = `${y}px`;\n setTimeout(() => {\n this.textAreaDom.focus();\n this.textAreaDom.setSelectionRange(0, 0);\n });\n this.currRt = rt;\n\n this.cursorIndex = cursorIndex;\n this.selectionStartCursorIdx = selectionStartCursorIdx;\n }\n\n release() {\n this.textAreaDom.removeEventListener('input', this.handleInput);\n this.textAreaDom.removeEventListener('compositionstart', this.handleCompositionStart);\n this.textAreaDom.removeEventListener('compositionend', this.handleCompositionEnd);\n application.global.removeEventListener('keydown', this.handleKeyDown);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugins/builtin-plugin/edit-module.ts"],"names":[],"mappings":";;;AAGA,SAAgB,8BAA8B,CAAC,UAAgC,EAAE,WAAmB;IAClG,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAClD,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAgC,CAAC;QAC3D,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE;YAChC,WAAW,EAAE,CAAC;SACf;QACD,IAAI,WAAW,GAAG,CAAC,EAAE;YACnB,MAAM;SACP;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAZD,wEAYC;AAED,MAAa,UAAU;IAgBrB,YAAY,SAAuB;QAkCnC,kBAAa,GAAG,CAAC,CAAgB,EAAE,EAAE;YACnC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,EAAE;gBAC/C,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;aACrD;QACH,CAAC,CAAC;QAEF,2BAAsB,GAAG,GAAG,EAAE;YAC5B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YAClD,MAAM,WAAW,GAAG,8BAA8B,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACjF,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;YAC3C,UAAU,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC,kCAAO,UAAU,KAAE,IAAI,EAAE,EAAE,IAAG,CAAC;YACnE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC,CAAC;QACF,yBAAoB,GAAG,GAAG,EAAE;YAC1B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAEzB,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YAClD,MAAM,MAAM,GAAG,8BAA8B,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YAEhF,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YACtC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAI,UAAkB,CAAC,IAAI,CAAC;YACtC,MAAM,QAAQ,GAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACxC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,kCAAO,UAAU,KAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAG,CAAC;aACxE;YACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBAC/B,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvF,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,gBAAW,GAAG,CAAC,EAAO,EAAE,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAChB,OAAO;aACR;YACD,IAAI,GAAG,GAAI,EAAU,CAAC,IAAI,CAAC;YAC3B,IAAI,EAAE,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,GAAG,EAAE;gBACnC,GAAG,GAAG,IAAI,CAAC;aACZ;YAED,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YAGlD,IAAI,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC;YAC5C,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;YAC9B,IAAI,QAAQ,GAAG,MAAM,EAAE;gBACrB,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;aACzC;YAED,IAAI,CAAC,uBAAuB,GAAG,QAAQ,CAAC;YACxC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAG5B,QAAQ,GAAG,8BAA8B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,GAAG,QAAQ,CAAC;YACtD,MAAM,GAAG,8BAA8B,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAE5D,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,IAAI,UAAU,GAAG,UAAU,CAAC;YAC5B,IAAI,EAAE,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAChD,IAAI,QAAQ,KAAK,MAAM,EAAE;oBACvB,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;iBACpD;qBAAM;oBACL,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBAC/B,QAAQ,IAAI,CAAC,CAAC;iBACf;aACF;iBAAM;gBACL,IAAI,QAAQ,KAAK,MAAM,EAAE;oBACvB,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;iBACpD;gBAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBACrB,UAAU,mCAAQ,UAAU,KAAE,IAAI,EAAE,EAAE,GAAE,CAAC;oBACzC,QAAQ,IAAI,CAAC,CAAC;oBACd,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;iBAC5C;gBACA,UAAkB,CAAC,IAAI,GAAG,GAAG,CAAC;aAChC;YAED,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;oBAC/B,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC5F,CAAC,CAAC,CAAC;aACJ;iBAAM;gBACL,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;oBAC9B,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC5F,CAAC,CAAC,CAAC;aACJ;QACH,CAAC,CAAC;QA3HA,IAAI,CAAC,SAAS,GAAG,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,QAAQ,CAAC,IAAI,CAAC;QAE5C,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACvD,WAAW,CAAC,YAAY,GAAG,KAAK,CAAC;QACjC,WAAW,CAAC,SAAS,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,EAAyG;QAC/G,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,QAAQ,CAAC,EAAyG;QAChH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,UAAU,CAAC,WAAgC;QACzC,WAAW,CAAC,YAAY,CACtB,OAAO,EACP,2OAA2O,CAC5O,CAAC;QAEF,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACxD,WAAW,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC9E,WAAW,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC1E,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IA8FD,MAAM,CAAC,CAAS,EAAE,CAAS,EAAE,EAAa,EAAE,WAAmB,EAAE,uBAA+B;QAC9F,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;QACtC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,uBAAuB,GAAG,uBAAuB,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACtF,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClF,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5D,CAAC;CACF;AAjKD,gCAiKC","file":"edit-module.js","sourcesContent":["import type { IRichText, IRichTextCharacter, IRichTextParagraphCharacter } from '../../interface';\nimport { IRichTextIcon, IRichTextParagraph } from '../../interface';\n\nexport function findCursorIndexIgnoreLinebreak(textConfig: IRichTextCharacter[], cursorIndex: number): number {\n let index = 0;\n for (index = 0; index < textConfig.length; index++) {\n const c = textConfig[index] as IRichTextParagraphCharacter;\n if (!(c.text && c.text === '\\n')) {\n cursorIndex--;\n }\n if (cursorIndex < 0) {\n break;\n }\n }\n return index;\n}\n\nexport class EditModule {\n container: HTMLElement;\n textAreaDom: HTMLTextAreaElement;\n currRt: IRichText;\n isComposing: boolean;\n cursorIndex: number;\n selectionStartCursorIdx: number;\n // 输入的回调(composing的时候每次也会触发)\n onInputCbList: Array<\n (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void\n >;\n // change的回调(composing确认才会触发)\n onChangeCbList: Array<\n (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void\n >;\n\n constructor(container?: HTMLElement) {\n this.container = container ?? document.body;\n\n const textAreaDom = document.createElement('textarea');\n textAreaDom.autocomplete = 'off';\n textAreaDom.innerText = '';\n this.applyStyle(textAreaDom);\n this.container.append(textAreaDom);\n this.textAreaDom = textAreaDom;\n this.isComposing = false;\n this.onInputCbList = [];\n this.onChangeCbList = [];\n }\n\n onInput(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void) {\n this.onInputCbList.push(cb);\n }\n\n onChange(cb: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, pos: 'left' | 'right') => void) {\n this.onChangeCbList.push(cb);\n }\n\n applyStyle(textAreaDom: HTMLTextAreaElement) {\n textAreaDom.setAttribute(\n 'style',\n `width: 100px; height: 30px; left: 0; top: 0; position: absolute; z-index: -1; outline: none; resize: none; border: none; overflow: hidden; color: transparent; user-select: none; caret-color: transparent;background-color: transparent;`\n );\n\n textAreaDom.addEventListener('input', this.handleInput);\n textAreaDom.addEventListener('compositionstart', this.handleCompositionStart);\n textAreaDom.addEventListener('compositionend', this.handleCompositionEnd);\n window.addEventListener('keydown', this.handleKeyDown);\n }\n\n handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n this.handleInput({ data: null, type: 'Backspace' });\n }\n };\n\n handleCompositionStart = () => {\n const { textConfig = [] } = this.currRt.attribute;\n const cursorIndex = findCursorIndexIgnoreLinebreak(textConfig, this.cursorIndex);\n const lastConfig = textConfig[cursorIndex];\n textConfig.splice(cursorIndex + 1, 0, { ...lastConfig, text: '' });\n this.isComposing = true;\n };\n handleCompositionEnd = () => {\n this.isComposing = false;\n // 拆分上一次的内容\n const { textConfig = [] } = this.currRt.attribute;\n const curIdx = findCursorIndexIgnoreLinebreak(textConfig, this.cursorIndex + 1);\n\n const lastConfig = textConfig[curIdx];\n textConfig.splice(curIdx, 1);\n const text = (lastConfig as any).text;\n const textList: string[] = Array.from(text.toString());\n for (let i = 0; i < textList.length; i++) {\n textConfig.splice(i + curIdx, 0, { ...lastConfig, text: textList[i] });\n }\n this.currRt.setAttributes({ textConfig });\n this.onChangeCbList.forEach(cb => {\n cb(text, this.isComposing, this.cursorIndex + textList.length, this.currRt, 'right');\n });\n };\n\n handleInput = (ev: any) => {\n if (!this.currRt) {\n return;\n }\n let str = (ev as any).data;\n if (ev.type !== 'Backspace' && !str) {\n str = '\\n';\n }\n // 如果是回车,那就不往后+1\n const { textConfig = [] } = this.currRt.attribute;\n\n // 如果有选中多个文字,那就先删除\n let startIdx = this.selectionStartCursorIdx;\n let endIdx = this.cursorIndex;\n if (startIdx > endIdx) {\n [startIdx, endIdx] = [endIdx, startIdx];\n }\n // 无论是否composition都立刻恢复到没有选中的idx状态\n this.selectionStartCursorIdx = startIdx;\n this.cursorIndex = startIdx;\n\n // 转换成基于textConfig的\n startIdx = findCursorIndexIgnoreLinebreak(textConfig, startIdx);\n const delta = this.selectionStartCursorIdx - startIdx;\n endIdx = findCursorIndexIgnoreLinebreak(textConfig, endIdx);\n\n const lastConfig = textConfig[startIdx + (this.isComposing ? 1 : 0)];\n let currConfig = lastConfig;\n if (ev.type === 'Backspace' && !this.isComposing) {\n if (startIdx !== endIdx) {\n textConfig.splice(startIdx + 1, endIdx - startIdx);\n } else {\n textConfig.splice(startIdx, 1);\n startIdx -= 1;\n }\n } else {\n if (startIdx !== endIdx) {\n textConfig.splice(startIdx + 1, endIdx - startIdx);\n }\n\n if (!this.isComposing) {\n currConfig = { ...lastConfig, text: '' };\n startIdx += 1;\n textConfig.splice(startIdx, 0, currConfig);\n }\n (currConfig as any).text = str;\n }\n\n this.currRt.setAttributes({ textConfig });\n if (!this.isComposing) {\n this.onChangeCbList.forEach(cb => {\n cb(str, this.isComposing, startIdx + delta, this.currRt, str === '\\n' ? 'left' : 'right');\n });\n } else {\n this.onInputCbList.forEach(cb => {\n cb(str, this.isComposing, startIdx + delta, this.currRt, str === '\\n' ? 'left' : 'right');\n });\n }\n };\n\n moveTo(x: number, y: number, rt: IRichText, cursorIndex: number, selectionStartCursorIdx: number) {\n this.textAreaDom.style.left = `${x}px`;\n this.textAreaDom.style.top = `${y}px`;\n setTimeout(() => {\n this.textAreaDom.focus();\n this.textAreaDom.setSelectionRange(0, 0);\n });\n this.currRt = rt;\n\n this.cursorIndex = cursorIndex;\n this.selectionStartCursorIdx = selectionStartCursorIdx;\n }\n\n release() {\n this.textAreaDom.removeEventListener('input', this.handleInput);\n this.textAreaDom.removeEventListener('compositionstart', this.handleCompositionStart);\n this.textAreaDom.removeEventListener('compositionend', this.handleCompositionEnd);\n window.removeEventListener('keydown', this.handleKeyDown);\n }\n}\n"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { IPointLike } from '@visactor/vutils';
|
|
2
|
-
import type { IGroup, ILine, IPlugin, IPluginService, IRichText, IRichTextFrame, IRichTextIcon, IRichTextLine, IRichTextParagraph
|
|
2
|
+
import type { IGroup, ILine, IPlugin, IPluginService, IRichText, IRichTextFrame, IRichTextIcon, IRichTextLine, IRichTextParagraph } from '../../interface';
|
|
3
3
|
import { EditModule } from './edit-module';
|
|
4
4
|
type UpdateType = 'input' | 'change' | 'onfocus' | 'defocus' | 'selection' | 'dispatch';
|
|
5
5
|
declare class Selection {
|
|
6
|
+
cacheSelectionStartCursorIdx: number;
|
|
7
|
+
cacheCurCursorIdx: number;
|
|
6
8
|
selectionStartCursorIdx: number;
|
|
7
9
|
curCursorIdx: number;
|
|
8
10
|
rt: IRichText;
|
|
9
|
-
constructor(selectionStartCursorIdx: number, curCursorIdx: number, rt: IRichText);
|
|
10
|
-
isEmpty(): boolean;
|
|
11
|
+
constructor(cacheSelectionStartCursorIdx: number, cacheCurCursorIdx: number, selectionStartCursorIdx: number, curCursorIdx: number, rt: IRichText);
|
|
11
12
|
hasFormat(key: string): boolean;
|
|
12
|
-
_getFormat(key: string, cursorIdx: number): any;
|
|
13
13
|
getFormat(key: string): any;
|
|
14
14
|
getAllFormat(key: string): any;
|
|
15
15
|
}
|
|
@@ -22,74 +22,55 @@ export declare class RichTextEditPlugin implements IPlugin {
|
|
|
22
22
|
_uid: number;
|
|
23
23
|
key: string;
|
|
24
24
|
editing: boolean;
|
|
25
|
-
pointerDown: boolean;
|
|
26
25
|
editLine: ILine;
|
|
27
26
|
editBg: IGroup;
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
pointerDown: boolean;
|
|
28
|
+
lastPoint?: IPointLike;
|
|
29
|
+
editModule: EditModule;
|
|
30
30
|
currRt: IRichText;
|
|
31
31
|
curCursorIdx: number;
|
|
32
32
|
selectionStartCursorIdx: number;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
protected commandCbs: Map<string, Array<(payload: any, p: RichTextEditPlugin) => void>>;
|
|
36
|
-
protected updateCbs: Array<(type: UpdateType, p: RichTextEditPlugin) => void>;
|
|
37
|
-
protected deltaX: number;
|
|
38
|
-
protected deltaY: number;
|
|
39
|
-
static splitText(text: string): string[];
|
|
40
|
-
static tryUpdateRichtext(richtext: IRichText): void;
|
|
41
|
-
static CreateSelection(rt: IRichText): Selection;
|
|
33
|
+
commandCbs: Map<string, Array<(payload: any, p: RichTextEditPlugin) => void>>;
|
|
34
|
+
updateCbs: Array<(type: UpdateType, p: RichTextEditPlugin) => void>;
|
|
42
35
|
constructor();
|
|
36
|
+
getSelection(): Selection;
|
|
43
37
|
formatTextCommandCb(payload: string, p: RichTextEditPlugin): void;
|
|
44
38
|
dispatchCommand(command: string, payload: any): void;
|
|
45
39
|
registerCommand(command: string, cb: (payload: any, p: RichTextEditPlugin) => void): void;
|
|
46
40
|
registerUpdateListener(cb: (type: UpdateType, p: RichTextEditPlugin) => void): void;
|
|
47
41
|
activate(context: IPluginService): void;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
handleChange: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText) => void;
|
|
51
|
-
deactivate(context: IPluginService): void;
|
|
42
|
+
handleInput: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, orient: 'left' | 'right') => void;
|
|
43
|
+
handleChange: (text: string, isComposing: boolean, cursorIdx: number, rt: IRichText, orient: 'left' | 'right') => void;
|
|
52
44
|
handleMove: (e: PointerEvent) => void;
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
showSelection(e: PointerEvent): void;
|
|
46
|
+
hideSelection(): void;
|
|
55
47
|
handlePointerDown: (e: PointerEvent) => void;
|
|
56
48
|
handlePointerUp: (e: PointerEvent) => void;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
tryShowSelection(e: PointerEvent): void;
|
|
61
|
-
hideSelection(): void;
|
|
62
|
-
protected getLineByPoint(cache: IRichTextFrame, p1: IPointLike): IRichTextLine;
|
|
63
|
-
protected getColumnAndIndexByLinePoint(lineInfo: IRichTextLine, p1: IPointLike): {
|
|
64
|
-
columnInfo: IRichTextParagraph | IRichTextIcon;
|
|
65
|
-
delta: number;
|
|
66
|
-
};
|
|
67
|
-
protected getColumnIndex(cache: IRichTextFrame, cInfo: IRichTextParagraph | IRichTextIcon): number;
|
|
68
|
-
protected isRichtext(e: PointerEvent): boolean;
|
|
69
|
-
protected triggerRender(): void;
|
|
70
|
-
protected computeGlobalDelta(cache: IRichTextFrame): void;
|
|
49
|
+
handleEnter: (e: PointerEvent) => void;
|
|
50
|
+
handleLeave: (e: PointerEvent) => void;
|
|
51
|
+
isRichtext(e: PointerEvent): boolean;
|
|
71
52
|
protected getEventPosition(e: PointerEvent): IPointLike;
|
|
72
|
-
protected
|
|
73
|
-
protected
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
y2: number;
|
|
77
|
-
cursorIndex: number;
|
|
78
|
-
};
|
|
79
|
-
protected computedCursorPosByCursorIdx(cursorIdx: number, rt: IRichText): {
|
|
80
|
-
x: number;
|
|
81
|
-
y1: number;
|
|
82
|
-
y2: any;
|
|
83
|
-
} | {
|
|
53
|
+
protected getLineByPoint(cache: IRichTextFrame, p1: IPointLike): IRichTextLine;
|
|
54
|
+
protected getColumnByLinePoint(lineInfo: IRichTextLine, p1: IPointLike): IRichTextParagraph | IRichTextIcon;
|
|
55
|
+
onFocus(e: PointerEvent): void;
|
|
56
|
+
protected getPointByColumnIdx(idx: number, rt: IRichText, orient: 'left' | 'right'): {
|
|
84
57
|
x: any;
|
|
85
58
|
y1: number;
|
|
86
59
|
y2: number;
|
|
87
60
|
};
|
|
61
|
+
protected getColumnIndex(cache: IRichTextFrame, cInfo: IRichTextParagraph | IRichTextIcon): number;
|
|
88
62
|
protected getColumnByIndex(cache: IRichTextFrame, index: number): {
|
|
89
63
|
lineInfo: IRichTextLine;
|
|
90
64
|
columnInfo: IRichTextParagraph | IRichTextIcon;
|
|
91
65
|
} | null;
|
|
66
|
+
protected setCursorAndTextArea(x: number, y1: number, y2: number, rt: IRichText): void;
|
|
67
|
+
protected setCursor(x: number, y1: number, y2: number): void;
|
|
68
|
+
applyUpdate(): void;
|
|
69
|
+
deFocus(e: PointerEvent): void;
|
|
70
|
+
splitText(text: string): string[];
|
|
71
|
+
tryUpdateRichtext(richtext: IRichText): void;
|
|
72
|
+
onSelect(): void;
|
|
73
|
+
deactivate(context: IPluginService): void;
|
|
92
74
|
release(): void;
|
|
93
|
-
getSelection(defaultAll?: boolean): Selection;
|
|
94
75
|
}
|
|
95
76
|
export {};
|