diff --git a/packages/demo/public/legao-assets.json b/packages/demo/public/legao-assets.json
index e499f3918..d3feb0cc8 100644
--- a/packages/demo/public/legao-assets.json
+++ b/packages/demo/public/legao-assets.json
@@ -115,8 +115,8 @@
},
{
"prototypeConfigsUrl": [
- "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-deep/2.0.11/proto.3f4f5d1.css",
- "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-deep/2.0.11/proto.057b4c5.js"
+ "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-deep/2.1.12/proto.611ab53.css",
+ "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-deep/2.1.12/proto.5b7b3d3.js"
],
"prototypeViewsUrl": null,
"alias": "",
diff --git a/packages/designer/package.json b/packages/designer/package.json
index 5803b6980..c2922f1b7 100644
--- a/packages/designer/package.json
+++ b/packages/designer/package.json
@@ -19,6 +19,7 @@
"@ali/lowcode-types": "^0.8.3",
"@ali/lowcode-utils": "^0.8.4",
"classnames": "^2.2.6",
+ "event": "^1.0.0",
"react": "^16",
"react-dom": "^16.7.0"
},
diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx
new file mode 100644
index 000000000..b0036c5c4
--- /dev/null
+++ b/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx
@@ -0,0 +1,273 @@
+import { Component, Fragment } from 'react';
+import DragResizeEngine from './drag-resize-engine';
+import { observer, computed } from '@ali/lowcode-editor-core';
+import classNames from 'classnames';
+import { SimulatorContext } from '../context';
+import { BuiltinSimulatorHost } from '../host';
+import { OffsetObserver, Designer } from '../../designer';
+
+@observer
+export default class BoxResizing extends Component<{ host: BuiltinSimulatorHost }> {
+ static contextType = SimulatorContext;
+
+ get host(): BuiltinSimulatorHost {
+ return this.props.host;
+ }
+
+ get dragging(): boolean {
+ return this.host.designer.dragon.dragging;
+ }
+
+ @computed get selecting() {
+ const doc = this.host.document;
+ if (doc.suspensed) {
+ return null;
+ }
+ const selection = doc.selection;
+ return this.dragging ? selection.getTopNodes() : selection.getNodes();
+ }
+
+ shouldComponentUpdate() {
+ return false;
+ }
+
+ componentDidUpdate() {
+ // this.hoveringCapture.setBoundary(this.outline);
+ // this.willBind();
+ }
+
+ render() {
+ const selecting = this.selecting;
+ if (!selecting || selecting.length < 1) {
+ // DIRTY FIX, recore has a bug!
+ return ;
+ }
+
+ // const componentMeta = selecting[0].componentMeta;
+ // const metaData = componentMeta.getMetadata();
+
+ return (
+
+ {selecting.map((node) => (
+
+ ))}
+
+ );
+ }
+}
+
+@observer
+export class BoxResizingForNode extends Component<{ host: BuiltinSimulatorHost; node: Node }> {
+ static contextType = SimulatorContext;
+
+ get host(): BuiltinSimulatorHost {
+ return this.props.host;
+ }
+
+ get dragging(): boolean {
+ return this.host.designer.dragon.dragging;
+ }
+
+ @computed get instances() {
+ return this.host.getComponentInstances(this.props.node);
+ }
+
+ shouldComponentUpdate() {
+ return false;
+ }
+
+ render() {
+ const { instances } = this;
+ const { node } = this.props;
+ const designer = this.host.designer;
+
+ if (!instances || instances.length < 1) {
+ return null;
+ }
+ return (
+
+ {instances.map((instance: any) => {
+ const observed = designer.createOffsetObserver({
+ node,
+ instance,
+ });
+ if (!observed) {
+ return null;
+ }
+ return (
+
+ );
+ })}
+
+ );
+ }
+}
+
+@observer
+export class BoxResizingInstance extends Component<{
+ observed: OffsetObserver;
+ highlight?: boolean;
+ dragging?: boolean;
+ designer?: Designer;
+}> {
+ // private outline: any;
+ private willUnbind: () => any;
+ private outlineRight: any;
+ private outlineLeft: any;
+ private dragEngine: DragResizeEngine;
+
+ constructor(props: any) {
+ super(props);
+ this.dragEngine = new DragResizeEngine(props.designer);
+ }
+
+ componentWillUnmount() {
+ if (this.willUnbind) {
+ this.willUnbind();
+ }
+ this.props.observed.purge();
+ }
+
+ getExperiMentalFns = (metaData: any) => {
+ if (metaData.experimental && metaData.experimental.callbacks) {
+ return metaData.experimantal.callbacks;
+ }
+ };
+
+ componentDidMount() {
+ // this.hoveringCapture.setBoundary(this.outline);
+ this.willBind();
+
+ const resize = (e: MouseEvent, direction: string, node: any, moveX: number, moveY: number) => {
+ const metaData = node.componentMeta.getMetadata();
+ if (
+ metaData &&
+ metaData.experimental &&
+ metaData.experimental.callbacks &&
+ typeof metaData.experimental.callbacks.onResize === 'function'
+ ) {
+ e.trigger = direction;
+ e.deltaX = moveX;
+ e.deltaY = moveY;
+ metaData.experimental.callbacks.onResize(e, node);
+ }
+ };
+
+ const resizeStart = (e: MouseEvent, direction: string, node: any) => {
+ const metaData = node.componentMeta.getMetadata();
+ if (
+ metaData &&
+ metaData.experimental &&
+ metaData.experimental.callbacks &&
+ typeof metaData.experimental.callbacks.onResizeStart === 'function'
+ ) {
+ e.trigger = direction;
+ metaData.experimental.callbacks.onResizeStart(e, node);
+ }
+ };
+
+ const resizeEnd = (e: MouseEvent, direction: string, node: any) => {
+ const metaData = node.componentMeta.getMetadata();
+ if (
+ metaData &&
+ metaData.experimental &&
+ metaData.experimental.callbacks &&
+ typeof metaData.experimental.callbacks.onResizeEnd === 'function'
+ ) {
+ e.trigger = direction;
+ metaData.experimental.callbacks.onResizeStart(e, node);
+ }
+ };
+
+ this.dragEngine.onResize(resize);
+ this.dragEngine.onResizeStart(resizeStart);
+ this.dragEngine.onResizeEnd(resizeEnd);
+ }
+
+ willBind() {
+ if (this.willUnbind) {
+ this.willUnbind();
+ }
+
+ if (!this.outlineRight && !this.outlineLeft) {
+ return;
+ }
+
+ const unBind: any[] = [];
+
+ unBind.push(
+ this.dragEngine.from(this.outlineRight, 'e', () => {
+ // if (!this.hoveringLine.hasOutline()) {
+ // return null;
+ // }
+ // return this.hoveringLine.getCurrentNode();
+ return this.props.observed.node;
+ }),
+ );
+ unBind.push(
+ this.dragEngine.from(this.outlineLeft, 'w', () => {
+ return this.props.observed.node;
+ // if (!this.hoveringLine.hasOutline()) {
+ // return null;
+ // }
+ // return this.hoveringLine.getCurrentNode();
+ }),
+ );
+
+ this.willUnbind = () => {
+ if (unBind && unBind.length > 0) {
+ unBind.forEach((item) => {
+ item();
+ });
+ }
+ this.willUnbind = () => {};
+ };
+ }
+
+ render() {
+ const { observed } = this.props;
+ if (!observed.hasOffset) {
+ return null;
+ }
+
+ const { node, offsetWidth, offsetHeight, offsetTop, offsetLeft } = observed;
+ let triggerVisible: any = [];
+ const metaData = node.componentMeta.getMetadata();
+ if (metaData && metaData.experimental && metaData.experimental.getResizingHandlers) {
+ triggerVisible = metaData.experimental.getResizingHandlers(node);
+ }
+
+ const className = classNames('lc-borders lc-resize-box');
+
+ return (
+
+ {triggerVisible.includes('w') && (
+
{
+ this.outlineLeft = ref;
+ }}
+ className={className}
+ style={{
+ height: offsetHeight,
+ transform: `translate(${offsetLeft - 10}px, ${offsetTop}px)`,
+ width: 20,
+ }}
+ />
+ )}
+ {triggerVisible.includes('e') && (
+
{
+ this.outlineRight = ref;
+ }}
+ style={{
+ height: offsetHeight,
+ transform: `translate(${offsetLeft + offsetWidth - 10}px, ${offsetTop}px)`,
+ width: 20,
+ }}
+ />
+ )}
+
+ );
+ }
+}
diff --git a/packages/designer/src/builtin-simulator/bem-tools/borders.less b/packages/designer/src/builtin-simulator/bem-tools/borders.less
index a2469519c..4b10396ed 100644
--- a/packages/designer/src/builtin-simulator/bem-tools/borders.less
+++ b/packages/designer/src/builtin-simulator/bem-tools/borders.less
@@ -49,6 +49,28 @@
}
}
+ &.lc-resize-box {
+ border-width: 0;
+ z-index: 1;
+ cursor: ew-resize;
+ pointer-events: auto;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+
+ &:after {
+ content: "";
+ display: block;
+ height: calc(100% - 20px);
+ min-height: 50%;
+ width: 4px;
+ background: #738397;
+ border-radius: 2px;
+ // animation: flashing 1.5s infinite linear;
+ }
+ }
+
+ // &&-hovering {
&&-detecting {
z-index: 1;
border-style: dashed;
diff --git a/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts
new file mode 100644
index 000000000..11308316e
--- /dev/null
+++ b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts
@@ -0,0 +1,138 @@
+import * as EventEmitter from 'events';
+import { ISimulatorHost, isSimulatorHost } from '../../../../designer/src/simulator';
+import { Designer } from '../../../../designer/src/designer/designer';
+import { setNativeSelection, cursor } from '@ali/lowcode-utils';
+// import Cursor from './cursor';
+// import Pages from './pages';
+
+function makeEventsHandler(
+ boostEvent: MouseEvent | DragEvent,
+ sensors: ISimulatorHost[],
+): (fn: (sdoc: Document) => void) => void {
+ const topDoc = window.top.document;
+ const sourceDoc = boostEvent.view?.document || topDoc;
+ // TODO: optimize this logic, reduce listener
+ // const boostPrevented = boostEvent.defaultPrevented;
+ const docs = new Set
();
+ // if (boostPrevented || isDragEvent(boostEvent)) {
+ docs.add(topDoc);
+ // }
+ docs.add(sourceDoc);
+ // if (sourceDoc !== topDoc || isDragEvent(boostEvent)) {
+ sensors.forEach((sim) => {
+ const sdoc = sim.contentDocument;
+ if (sdoc) {
+ docs.add(sdoc);
+ }
+ });
+ // }
+
+ return (handle: (sdoc: Document) => void) => {
+ docs.forEach((doc) => handle(doc));
+ };
+}
+
+// 拖动缩放
+export default class DragResizeEngine {
+ private emitter: EventEmitter;
+ private dragResizing = false;
+
+ constructor(readonly designer: Designer) {
+ this.designer = designer;
+ this.emitter = new EventEmitter();
+ }
+
+ private getMasterSensors(): ISimulatorHost[] {
+ return this.designer.project.documents
+ .map((doc) => {
+ // TODO: not use actived,
+ if (doc.actived && doc.simulator?.sensorAvailable) {
+ return doc.simulator;
+ }
+ return null;
+ })
+ .filter(Boolean) as any;
+ }
+
+ isDragResizing() {
+ return this.dragResizing;
+ }
+
+ /**
+ * drag reszie from
+ * @param shell
+ * @param direction n/s/e/w
+ * @param boost (e: MouseEvent) => VE.Node
+ */
+ from(shell: Element, direction: string, boost: (e: MouseEvent) => any) {
+ let node: any;
+ let startEvent: MouseEvent;
+
+ if (!shell) {
+ return () => {};
+ }
+
+ const move = (e: MouseEvent) => {
+ const moveX = e.clientX - startEvent.clientX;
+ const moveY = e.clientY - startEvent.clientY;
+
+ this.emitter.emit('resize', e, direction, node, moveX, moveY);
+ };
+
+ const masterSensors = this.getMasterSensors();
+
+ const over = (e: MouseEvent) => {
+ const handleEvents = makeEventsHandler(e, masterSensors);
+ handleEvents((doc) => {
+ doc.removeEventListener('mousemove', move, true);
+ doc.removeEventListener('mouseup', over, true);
+ });
+
+ this.dragResizing = false;
+ cursor.release();
+
+ this.emitter.emit('resizeEnd', e, direction, node);
+ };
+
+ const mousedown = (e: MouseEvent) => {
+ node = boost(e);
+ startEvent = e;
+ const handleEvents = makeEventsHandler(e, masterSensors);
+ handleEvents((doc) => {
+ doc.addEventListener('mousemove', move, true);
+ doc.addEventListener('mouseup', over, true);
+ });
+
+ this.emitter.emit('resizestart', e, direction, node);
+ this.dragResizing = true;
+ cursor.addState('ew-resize');
+ };
+ shell.addEventListener('mousedown', mousedown);
+ return () => {
+ shell.removeEventListener('mousedown', mousedown);
+ };
+ }
+
+ onResizeStart(func: (e: MouseEvent, direction: string, node: any) => any) {
+ this.emitter.on('resizestart', func);
+ return () => {
+ this.emitter.removeListener('resizestart', func);
+ };
+ }
+
+ onResize(func: (e: MouseEvent, direction: string, node: any, moveX: number, moveY: number) => any) {
+ this.emitter.on('resize', func);
+ return () => {
+ this.emitter.removeListener('resize', func);
+ };
+ }
+
+ onResizeEnd(func: (e: MouseEvent, direction: string, node: any) => any) {
+ this.emitter.on('resizeEnd', func);
+ return () => {
+ this.emitter.removeListener('resizeEnd', func);
+ };
+ }
+}
+
+// new DragResizeEngine();
diff --git a/packages/designer/src/builtin-simulator/bem-tools/index.tsx b/packages/designer/src/builtin-simulator/bem-tools/index.tsx
index 881ff9396..c22951c2f 100644
--- a/packages/designer/src/builtin-simulator/bem-tools/index.tsx
+++ b/packages/designer/src/builtin-simulator/bem-tools/index.tsx
@@ -3,6 +3,7 @@ import { observer } from '@ali/lowcode-editor-core';
import { BorderDetecting } from './border-detecting';
import { BuiltinSimulatorHost } from '../host';
import { BorderSelecting } from './border-selecting';
+import BorderResizing from './border-resizing';
import { InsertionView } from './insertion';
import './bem-tools.less';
import './borders.less';
@@ -21,6 +22,7 @@ export class BemTools extends Component<{ host: BuiltinSimulatorHost }> {
+
);
}
diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts
index 63a75421d..e5c18d33d 100644
--- a/packages/designer/src/document/node/node.ts
+++ b/packages/designer/src/document/node/node.ts
@@ -426,6 +426,7 @@ export class Node
{
return this.parent.children.indexOf(this);
}
+
/**
* 获取下一个兄弟节点
*/
@@ -618,6 +619,9 @@ export class Node {
getId() {
return this.id;
}
+ getIndex() {
+ return this.index;
+ }
getNode() {
return this;
}