diff --git a/graphic-pixi b/graphic-pixi index bf2d816..218cae4 160000 --- a/graphic-pixi +++ b/graphic-pixi @@ -1 +1 @@ -Subproject commit bf2d81625f3fa89eaca241ea3a04f2198dcfbba2 +Subproject commit 218cae4c5cf47aa9aad70b19393fbd0e3fc54825 diff --git a/src/jl-graphic/core/JlGraphic.ts b/src/jl-graphic/core/JlGraphic.ts index c4c0d91..7ed967a 100644 --- a/src/jl-graphic/core/JlGraphic.ts +++ b/src/jl-graphic/core/JlGraphic.ts @@ -148,6 +148,23 @@ DisplayObject.prototype.getAllParentScaled = }); return scaled; }; +DisplayObject.prototype.getPositionOnCanvas = + function getPositionOnCanvas(): Point { + if (this.parent.isCanvas()) { + return this.position; + } else { + return this.parent.localToCanvasPoint(this.position); + } + }; +DisplayObject.prototype.updatePositionByCanvasPosition = + function updatePositionByCanvasPosition(p: IPointData): void { + if (this.parent.isCanvas()) { + this.position.copyFrom(p); + } else { + const localPosition = this.parent.canvasToLocalPoint(p); + this.position.copyFrom(localPosition); + } + }; DisplayObject.prototype.saveTransform = function saveTransform() { return GraphicTransform.fromObject(this); }; diff --git a/src/jl-graphic/global.d.ts b/src/jl-graphic/global.d.ts index df5fa49..a70a5f9 100644 --- a/src/jl-graphic/global.d.ts +++ b/src/jl-graphic/global.d.ts @@ -60,9 +60,28 @@ declare namespace GlobalMixins { _rotatable: boolean; // 是否可旋转 rotatable: boolean; worldAngle: number; // 世界角度,(-180, 180] + /** + * 获取所有父级元素叠加缩放 + */ getAllParentScaled(): PointType; - saveTransform(): GraphicTransform; // 保存变换 - loadTransform(transform: GraphicTransform): void; // 加载变换 + /** + * 获取位置在画布的坐标 + */ + getPositionOnCanvas(): PointType; + /** + * 通过画布坐标更新位置 + * @param p 画布坐标 + */ + updatePositionByCanvasPosition(p: IPointData): void; + /** + * 保存变换数据 + */ + saveTransform(): GraphicTransform; + /** + * 加载变换 + * @param transform 变换数据 + */ + loadTransform(transform: GraphicTransform): void; isChild(obj: DisplayObject): boolean; // 是否子元素 isParent(obj: DisplayObject): boolean; // 是否父元素 isAssistantAppend(): boolean; // 是否辅助附加图形 @@ -83,14 +102,45 @@ declare namespace GlobalMixins { isCanvas(): boolean; // 是否画布对象 getViewport(): Viewport; // 获取视口 getGraphicApp(): GraphicApp; // 获取图形app - localToCanvasPoint(p: IPointData): PointType; // 图形本地坐标转为画布坐标 - localToCanvasPoints(...points: IPointData[]): PointType[]; // 批量转换 - canvasToLocalPoint(p: IPointData): PointType; // 画布坐标转为图形本地坐标 - canvasToLocalPoints(...points: IPointData[]): PointType[]; // 批量转换 - - localToScreenPoint(p: IPointData): PointType; // 本地坐标转为屏幕坐标 - localToScreenPoints(...points: IPointData[]): PointType[]; // 批量 - screenToLocalPoint(p: IPointData): PointType; // 屏幕坐标转为本地坐标 + /** + * 图形本地坐标转为画布坐标 + * @param p 图形本地坐标 + */ + localToCanvasPoint(p: IPointData): PointType; + /** + * 批量转换图形本地坐标为画布坐标 + * @param points 图形本地坐标 + */ + localToCanvasPoints(...points: IPointData[]): PointType[]; + /** + * 画布坐标转为图形本地坐标 + * @param p 画布坐标 + */ + canvasToLocalPoint(p: IPointData): PointType; + /** + * 批量转换画布坐标为图形本地坐标 + * @param points 画布坐标 + */ + canvasToLocalPoints(...points: IPointData[]): PointType[]; + /** + * 本地坐标转为屏幕坐标 + * @param p 本地坐标 + */ + localToScreenPoint(p: IPointData): PointType; + /** + * 批量转换本地坐标为屏幕坐标 + * @param points 本地坐标 + */ + localToScreenPoints(...points: IPointData[]): PointType[]; + /** + * 屏幕坐标转为本地坐标 + * @param p 屏幕坐标 + */ + screenToLocalPoint(p: IPointData): PointType; + /** + * 批量转换屏幕坐标为本地坐标 + * @param points 屏幕坐标 + */ screenToLocalPoints(...points: IPointData[]): PointType[]; // 批量 localBoundsToCanvasPoints(): PointType[]; // 本地包围框转为多边形点坐标 diff --git a/src/jl-graphic/graphic/AbsorbablePosition.ts b/src/jl-graphic/graphic/AbsorbablePosition.ts index 0d5405f..b3a7acf 100644 --- a/src/jl-graphic/graphic/AbsorbablePosition.ts +++ b/src/jl-graphic/graphic/AbsorbablePosition.ts @@ -72,6 +72,11 @@ export default class AbsorbablePoint absorbRange: number; scaledListenerOn = false; + /** + * + * @param point 画布坐标 + * @param absorbRange + */ constructor(point: IPointData, absorbRange = 10) { super(AbsorbablePointGraphic.geometry); this._point = new Point(point.x, point.y); @@ -98,11 +103,16 @@ export default class AbsorbablePoint tryAbsorb(...objs: DisplayObject[]): void { for (let i = 0; i < objs.length; i++) { const obj = objs[i]; + const canvasPosition = obj.getPositionOnCanvas(); if ( - distance(this._point.x, this._point.y, obj.position.x, obj.position.y) < - this.absorbRange + distance( + this._point.x, + this._point.y, + canvasPosition.x, + canvasPosition.y + ) < this.absorbRange ) { - obj.position.copyFrom(this._point); + obj.updatePositionByCanvasPosition(this._point); } } } @@ -122,6 +132,12 @@ export class AbsorbableLine extends Graphics implements AbsorbablePosition { absorbRange: number; _color = '#E77E0E'; + /** + * + * @param p1 画布坐标 + * @param p2 画布坐标 + * @param absorbRange + */ constructor(p1: IPointData, p2: IPointData, absorbRange = 20) { super(); this.p1 = new Point(p1.x, p1.y); @@ -155,10 +171,14 @@ export class AbsorbableLine extends Graphics implements AbsorbablePosition { tryAbsorb(...objs: DisplayObject[]): void { for (let i = 0; i < objs.length; i++) { const obj = objs[i]; - const p = obj.position.clone(); - if (linePoint(this.p1, this.p2, p, this.absorbRange, true)) { - const fp = calculateFootPointFromPointToLine(this.p1, this.p2, p); - obj.position.copyFrom(fp); + const canvasPosition = obj.getPositionOnCanvas(); + if (linePoint(this.p1, this.p2, canvasPosition, this.absorbRange, true)) { + const fp = calculateFootPointFromPointToLine( + this.p1, + this.p2, + canvasPosition + ); + obj.updatePositionByCanvasPosition(fp); } } } @@ -173,6 +193,12 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition { radius: number; _color = '#E77E0E'; + /** + * + * @param p 画布坐标 + * @param radius + * @param absorbRange + */ constructor(p: IPointData, radius: number, absorbRange = 10) { super(); this.p0 = new Point(p.x, p.y); @@ -202,11 +228,12 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition { tryAbsorb(...objs: DisplayObject[]): void { for (let i = 0; i < objs.length; i++) { const obj = objs[i]; + const canvasPosition = obj.getPositionOnCanvas(); const len = distance( this.p0.x, this.p0.y, - obj.position.x, - obj.position.y + canvasPosition.x, + canvasPosition.y ); if ( len > this.radius - this.absorbRange && @@ -216,9 +243,9 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition { const p = calculateIntersectionPointOfCircleAndPoint( this.p0, this.radius, - obj.position + canvasPosition ); - obj.position.copyFrom(p); + obj.updatePositionByCanvasPosition(p); } } } diff --git a/src/jl-graphic/utils/GraphicUtils.ts b/src/jl-graphic/utils/GraphicUtils.ts index a710fde..1fbc572 100644 --- a/src/jl-graphic/utils/GraphicUtils.ts +++ b/src/jl-graphic/utils/GraphicUtils.ts @@ -67,15 +67,16 @@ export function recursiveFindChild( container: Container, finder: (child: DisplayObject) => boolean ): DisplayObject | null { + let result = null; for (let i = 0; i < container.children.length; i++) { const child = container.children[i]; if (finder(child)) { return child; } else if (child.children) { - return recursiveFindChild(child as Container, finder); + result = recursiveFindChild(child as Container, finder); } } - return null; + return result; } export interface BezierParam {