import { Bounds } from './objects/bounds'; import { Rectangle } from './objects/rectangle'; import { Container } from './objects/container'; import { CompObject } from './compObj'; import { Matrix } from './matrix'; export class ObjsContainer { aabb = new Bounds(); tempBound = new Bounds(); parent = new Container(); rect = new Rectangle(); pivotIndex = 0; selected:CompObject[] = []; constructor(selected:any[]) { this.selected = selected; this.parent.sortableChildren = false; if (selected.length > 0) { this.init(); } } clone() { const ret = new ObjsContainer([]); const parent = this.parent; ret.parent.pivot = parent.pivot; ret.parent.skew = parent.skew; ret.parent.scale = parent.scale; ret.parent.rotation = parent.rotation; ret.parent.position = parent.position; ret.rect.copyFrom(this.rect); ret.parent.updateTransform(); ret.setPivot(this.pivotIndex); return ret; } getBound() { //加上parent的旋转和平移 this.tempBound.clear(); this.tempBound.addFrame(this.parent.transform, 0, 0, this.rect.width, this.rect.height); return this.tempBound.getRectangle(); } get width() { return this.rect.width } get height() { return this.rect.height; } testClick(sx:number,sy:number) { let w = this.width; let h = this.height; let local = {x:0,y:0} as any; this.parent.worldTransform.applyInverse({x:sx,y:sy} as any, local); if( local.x < 0 || local.x > w ) return false; if( local.y < 0 || local.y > h ) return false; return true; } init() { //获取选择对象的aabb(画布空间) this.aabb.clear(); let n = this.selected.length; const selected = this.selected; const selectedRotation = 0; if (n == 1) { //单对象 let obj = selected[0]; let rect = new Rectangle(0, 0, obj.width , obj.height); this.rect = rect; this.parent.transform.setFromMatrix(obj.worldTransform); this.parent.updateTransform(); this.parent.addChildWorldNoChange(obj); this.parent.updateTransform(); return; } while (n--) { let obj = selected[n]; let box = obj.calculateBounds(); this.aabb.addBounds(box); } //构建当前对象的转换矩阵 let rect = new Rectangle(); this.aabb.getRectangle(rect); let center = rect.center; this.rect = rect; //设置位置 let p = this.parent.position; p.x = center.x; p.y = center.y; //设置旋转中心点 let pivot = this.parent.pivot; pivot.x = rect.width / 2; pivot.y = rect.height / 2; //设置旋转 this.parent.scale = { x: 1, y: 1 } as any; this.parent.width = rect.width; this.parent.height = rect.height; //设置旋转 this.parent.rotation = selectedRotation; // this.parent.scale = {x:1.5, y:1.5}; this.parent.updateTransform(); //选择的对象坐标从画布空间转到选框坐标, n = selected.length; for (let i = 0; i < n; i++) { let obj = selected[i]; this.parent.addChildWorldNoChange(obj); } this.parent.updateTransform(); } rotate(r:number) { this.parent.rotation = r; this.parent._boundsID++; this.parent.updateTransform(); this.updateCompState(); } //index // 0 ---- 1 // | 4 | // 3 -----2 setPivot(index:number) { let rect = this.rect; let pivots = [{ x: 0, y: 0 }, { x: rect.width, y: 0 }, { x: rect.width, y: rect.height }, { x: 0, y: rect.height }, { x: rect.width / 2, y: rect.height / 2 }]; let targetPivot = pivots[index]; let point = { x: targetPivot.x, y: targetPivot.y } as any; this.parent.worldTransform.apply(point, point); this.parent.pivot = targetPivot as any; this.parent.position.x = point.x; this.parent.position.y = point.y; this.parent.updateTransform(); this.pivotIndex = index; return { x: point.x, y: point.y}; } getPivotXY(index:number) { let rect = this.rect; let pivots = [{ x: 0, y: 0 }, { x: rect.width, y: 0 }, { x: rect.width, y: rect.height }, { x: 0, y: rect.height }, { x: rect.width / 2, y: rect.height / 2 }]; let targetPivot = pivots[index]; let point = { x: targetPivot.x, y: targetPivot.y } as any; this.parent.worldTransform.apply(point, point); let yIndex = 0, xIndex = 0; if (index == 3) { yIndex = 0; xIndex = 2; } else if (index == 0) { yIndex = 3; xIndex = 1; } else if (index == 1) { yIndex = 2; xIndex = 0; } else if (index == 2) { yIndex = 1; xIndex = 3; } let pointY = pivots[yIndex]; let pY = { x: pointY.x, y: pointY.y } as any; this.parent.worldTransform.apply(pY, pY); let pointX = pivots[xIndex]; let pX = { x: pointX.x, y: pointX.y } as any; this.parent.worldTransform.apply(pX, pX); let xVec = { x: (pX.x - point.x), y: (pX.y - point.y) }; let yVec = { x: (pY.x - point.x), y: (pY.y - point.y) }; return { x: xVec, y: yVec }; } scale(x:number, y:number) { this.parent.scale.x = x; this.parent.scale.y = y; this.parent.updateTransform(); this.updateCompState(); } scaleX(x:number) { this.parent.scale.x = x; this.parent.updateTransform(); this.updateCompState(); } scaleY(y:number) { this.parent.scale.y = y; this.parent.updateTransform(); this.updateCompState(); } applyChildWidth(option:{Width?:number, Height?:number}) { if (this.selected.length != 1) return; const obj = this.selected[0]; //先移除 this.parent.removeChildWorldNoChange(obj); const m = new Matrix(); m.scale(option.Width ? option.Width/obj.width :1 , option.Height? option.Height / obj.height: 1) m.invert(); m.prepend(obj.worldTransform) obj.transform.setFromMatrix(m) if (option.Width) { obj.width = option.Width } if (option.Height) { obj.height = option.Height } obj.updateTransform(); this.parent.addChildWorldNoChange(obj); } scaleSize(Width:number, Height:number) { this.parent.scale.y = Height / this.rect.height this.parent.scale.x = Width / this.rect.width this.parent.updateTransform(); this.applyChildWidth({Width, Height}) this.updateCompState(); } scaleWidth(Width:number) { //怎么改对应的偏移值 this.parent.scale.x = Width / this.rect.width this.parent.updateTransform(); this.applyChildWidth({Width}) this.updateCompState(); } scaleHeight(Height:number) { this.parent.scale.y = Height / this.rect.height this.parent.updateTransform(); this.applyChildWidth({Height}); this.updateCompState(); } translate(x:number, y:number) { this.parent.x += x; this.parent.y += y; this.parent.updateTransform(); this.updateCompState(); } destroy() {//选中的对象坐标转到画布空间坐标 let selected = this.selected; let n = selected.length; while (n--) { let child = selected[n]; child.updateTransform(); //世界坐标 child.transform.setFromMatrix(child.worldTransform); child.parent = null; child.transform._parentID = -1; child.updateTransform(); child._boundsID = -2; child._lastBoundsID = 0; } } updateCompState() { let n = this.selected.length; while (n--) { let child = this.selected[n]; child.comp.layout.transformMatrix = child.worldTransform.getMatrixStr(); } } }