ObjsContainer.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import { Bounds } from './objects/bounds';
  2. import { Rectangle } from './objects/rectangle';
  3. import { Container } from './objects/container';
  4. import { CompObject } from './compObj';
  5. import { Matrix } from './matrix';
  6. export class ObjsContainer {
  7. aabb = new Bounds();
  8. tempBound = new Bounds();
  9. parent = new Container();
  10. rect = new Rectangle();
  11. pivotIndex = 0;
  12. selected:CompObject[] = [];
  13. constructor(selected:any[]) {
  14. this.selected = selected;
  15. this.parent.sortableChildren = false;
  16. if (selected.length > 0) {
  17. this.init();
  18. }
  19. }
  20. clone() {
  21. const ret = new ObjsContainer([]);
  22. const parent = this.parent;
  23. ret.parent.pivot = parent.pivot;
  24. ret.parent.skew = parent.skew;
  25. ret.parent.scale = parent.scale;
  26. ret.parent.rotation = parent.rotation;
  27. ret.parent.position = parent.position;
  28. ret.rect.copyFrom(this.rect);
  29. ret.parent.updateTransform();
  30. ret.setPivot(this.pivotIndex);
  31. return ret;
  32. }
  33. getBound() {
  34. //加上parent的旋转和平移
  35. this.tempBound.clear();
  36. this.tempBound.addFrame(this.parent.transform, 0, 0, this.rect.width, this.rect.height);
  37. return this.tempBound.getRectangle();
  38. }
  39. get width() {
  40. return this.rect.width
  41. }
  42. get height() {
  43. return this.rect.height;
  44. }
  45. testClick(sx:number,sy:number)
  46. {
  47. let w = this.width;
  48. let h = this.height;
  49. let local = {x:0,y:0} as any;
  50. this.parent.worldTransform.applyInverse({x:sx,y:sy} as any, local);
  51. if( local.x < 0 || local.x > w ) return false;
  52. if( local.y < 0 || local.y > h ) return false;
  53. return true;
  54. }
  55. init() {
  56. this.parent.removeChildren(0, this.parent.children.length);
  57. //获取选择对象的aabb(画布空间)
  58. this.aabb.clear();
  59. let n = this.selected.length;
  60. const selected = this.selected;
  61. const selectedRotation = 0;
  62. if (n == 1) { //单对象
  63. let obj = selected[0];
  64. let rect = new Rectangle(0, 0, obj.width , obj.height);
  65. this.rect = rect;
  66. this.parent.transform.setFromMatrix(obj.worldTransform);
  67. this.parent.updateTransform();
  68. this.parent.addChildWorldNoChange(obj);
  69. this.parent.updateTransform();
  70. return;
  71. }
  72. while (n--) {
  73. let obj = selected[n];
  74. let box = obj.calculateBounds();
  75. this.aabb.addBounds(box);
  76. }
  77. //构建当前对象的转换矩阵
  78. let rect = new Rectangle();
  79. this.aabb.getRectangle(rect);
  80. let center = rect.center;
  81. this.rect = rect;
  82. console.log("xxxx=>", rect);
  83. //设置位置
  84. let p = this.parent.position;
  85. p.x = center.x;
  86. p.y = center.y;
  87. //设置旋转中心点
  88. let pivot = this.parent.pivot;
  89. pivot.x = rect.width / 2;
  90. pivot.y = rect.height / 2;
  91. //设置旋转
  92. this.parent.scale = { x: 1, y: 1 } as any;
  93. this.parent.width = rect.width;
  94. this.parent.height = rect.height;
  95. //设置旋转
  96. this.parent.rotation = selectedRotation;
  97. // this.parent.scale = {x:1.5, y:1.5};
  98. this.parent.updateTransform();
  99. //选择的对象坐标从画布空间转到选框坐标,
  100. n = selected.length;
  101. for (let i = 0; i < n; i++) {
  102. let obj = selected[i];
  103. this.parent.addChildWorldNoChange(obj);
  104. }
  105. this.parent.updateTransform();
  106. }
  107. rotate(r:number) {
  108. this.parent.rotation = r;
  109. this.parent._boundsID++;
  110. this.parent.updateTransform();
  111. this.updateCompState();
  112. }
  113. //index
  114. // 0 ---- 1
  115. // | 4 |
  116. // 3 -----2
  117. setPivot(index:number) {
  118. let rect = this.rect;
  119. 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 }];
  120. let targetPivot = pivots[index];
  121. let point = { x: targetPivot.x, y: targetPivot.y } as any;
  122. this.parent.worldTransform.apply(point, point);
  123. this.parent.pivot = targetPivot as any;
  124. this.parent.position.x = point.x;
  125. this.parent.position.y = point.y;
  126. this.parent.updateTransform();
  127. this.pivotIndex = index;
  128. return { x: point.x, y: point.y};
  129. }
  130. getPivotXY(index:number) {
  131. let rect = this.rect;
  132. 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 }];
  133. let targetPivot = pivots[index];
  134. let point = { x: targetPivot.x, y: targetPivot.y } as any;
  135. this.parent.worldTransform.apply(point, point);
  136. let yIndex = 0, xIndex = 0;
  137. if (index == 3) {
  138. yIndex = 0;
  139. xIndex = 2;
  140. } else if (index == 0) {
  141. yIndex = 3;
  142. xIndex = 1;
  143. } else if (index == 1) {
  144. yIndex = 2;
  145. xIndex = 0;
  146. } else if (index == 2) {
  147. yIndex = 1;
  148. xIndex = 3;
  149. }
  150. let pointY = pivots[yIndex];
  151. let pY = { x: pointY.x, y: pointY.y } as any;
  152. this.parent.worldTransform.apply(pY, pY);
  153. let pointX = pivots[xIndex];
  154. let pX = { x: pointX.x, y: pointX.y } as any;
  155. this.parent.worldTransform.apply(pX, pX);
  156. let xVec = { x: (pX.x - point.x), y: (pX.y - point.y) };
  157. let yVec = { x: (pY.x - point.x), y: (pY.y - point.y) };
  158. return { x: xVec, y: yVec };
  159. }
  160. scale(x:number, y:number) {
  161. this.parent.scale.x = x;
  162. this.parent.scale.y = y;
  163. this.parent.updateTransform();
  164. this.updateCompState();
  165. }
  166. scaleX(x:number) {
  167. this.parent.scale.x = x;
  168. this.parent.updateTransform();
  169. this.updateCompState();
  170. }
  171. scaleY(y:number) {
  172. this.parent.scale.y = y;
  173. this.parent.updateTransform();
  174. this.updateCompState();
  175. }
  176. applyChildWidth(option:{scaleX?:number, scaleY?:number}) {
  177. if (this.selected.length < 1) return;
  178. const obj = this.selected[0];
  179. //先移除
  180. this.parent.removeChildWorldNoChange(obj);
  181. const m = new Matrix();
  182. m.scale(option.scaleX ? option.scaleX : 1, option.scaleY? option.scaleY : 1)
  183. m.invert();
  184. m.prepend(obj.worldTransform)
  185. obj.transform.setFromMatrix(m)
  186. if (option.scaleX) {
  187. obj.width = option.scaleX * obj.width;
  188. }
  189. if (option.scaleY) {
  190. obj.height = option.scaleY * obj.height;
  191. }
  192. obj.updateTransform();
  193. this.parent.addChildWorldNoChange(obj);
  194. }
  195. scaleSize(x:number, y:number) {
  196. let preW = this.parent.scale.x * this.rect.width;
  197. let preH = this.parent.scale.y * this.rect.height;
  198. this.parent.scale.y = y
  199. this.parent.scale.x = x
  200. const Width = this.parent.scale.x * this.rect.width;
  201. const Height = this.parent.scale.y * this.rect.height;
  202. this.parent.updateTransform();
  203. this.applyChildWidth({scaleX: Width / preW, scaleY: Height/preH})
  204. this.updateCompState();
  205. }
  206. scaleWidth(x:number) {
  207. const prew = this.parent.scale.x * this.rect.width;
  208. //怎么改对应的偏移值
  209. this.parent.scale.x = x
  210. const w = this.parent.scale.x * this.rect.width;
  211. this.parent.updateTransform();
  212. this.applyChildWidth({scaleX: w / prew })
  213. this.updateCompState();
  214. }
  215. scaleHeight(y:number) {
  216. const preH = this.parent.scale.y * this.rect.height;
  217. this.parent.scale.y = y
  218. const h = this.parent.scale.y * this.rect.height;
  219. this.parent.updateTransform();
  220. this.applyChildWidth({scaleY: h / preH});
  221. this.updateCompState();
  222. }
  223. translate(x:number, y:number) {
  224. this.parent.x += x;
  225. this.parent.y += y;
  226. this.parent.updateTransform();
  227. this.updateCompState();
  228. }
  229. destroy() {//选中的对象坐标转到画布空间坐标
  230. let selected = this.selected;
  231. let n = selected.length;
  232. while (n--) {
  233. let child = selected[n];
  234. this.parent.removeChildWorldNoChange(child)
  235. }
  236. this.selected = [];
  237. }
  238. updateCompState() {
  239. let n = this.selected.length;
  240. while (n--) {
  241. let child = this.selected[n];
  242. if (child.comp) child.comp.layout.transformMatrix = child.worldTransform.getMatrixStr();
  243. }
  244. }
  245. updateSize() {
  246. this.selected.forEach(s=>s.updateSize());
  247. this.init();
  248. }
  249. }