ObjsContainer.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. //获取选择对象的aabb(画布空间)
  57. this.aabb.clear();
  58. let n = this.selected.length;
  59. const selected = this.selected;
  60. const selectedRotation = 0;
  61. if (n == 1) { //单对象
  62. let obj = selected[0];
  63. let rect = new Rectangle(0, 0, obj.width , obj.height);
  64. this.rect = rect;
  65. this.parent.transform.setFromMatrix(obj.worldTransform);
  66. this.parent.updateTransform();
  67. this.parent.addChildWorldNoChange(obj);
  68. this.parent.updateTransform();
  69. return;
  70. }
  71. while (n--) {
  72. let obj = selected[n];
  73. let box = obj.calculateBounds();
  74. this.aabb.addBounds(box);
  75. }
  76. //构建当前对象的转换矩阵
  77. let rect = new Rectangle();
  78. this.aabb.getRectangle(rect);
  79. let center = rect.center;
  80. this.rect = rect;
  81. //设置位置
  82. let p = this.parent.position;
  83. p.x = center.x;
  84. p.y = center.y;
  85. //设置旋转中心点
  86. let pivot = this.parent.pivot;
  87. pivot.x = rect.width / 2;
  88. pivot.y = rect.height / 2;
  89. //设置旋转
  90. this.parent.scale = { x: 1, y: 1 } as any;
  91. this.parent.width = rect.width;
  92. this.parent.height = rect.height;
  93. //设置旋转
  94. this.parent.rotation = selectedRotation;
  95. // this.parent.scale = {x:1.5, y:1.5};
  96. this.parent.updateTransform();
  97. //选择的对象坐标从画布空间转到选框坐标,
  98. n = selected.length;
  99. for (let i = 0; i < n; i++) {
  100. let obj = selected[i];
  101. this.parent.addChildWorldNoChange(obj);
  102. }
  103. this.parent.updateTransform();
  104. }
  105. rotate(r:number) {
  106. this.parent.rotation = r;
  107. this.parent._boundsID++;
  108. this.parent.updateTransform();
  109. this.updateCompState();
  110. }
  111. //index
  112. // 0 ---- 1
  113. // | 4 |
  114. // 3 -----2
  115. setPivot(index:number) {
  116. let rect = this.rect;
  117. 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 }];
  118. let targetPivot = pivots[index];
  119. let point = { x: targetPivot.x, y: targetPivot.y } as any;
  120. this.parent.worldTransform.apply(point, point);
  121. this.parent.pivot = targetPivot as any;
  122. this.parent.position.x = point.x;
  123. this.parent.position.y = point.y;
  124. this.parent.updateTransform();
  125. this.pivotIndex = index;
  126. return { x: point.x, y: point.y};
  127. }
  128. getPivotXY(index:number) {
  129. let rect = this.rect;
  130. 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 }];
  131. let targetPivot = pivots[index];
  132. let point = { x: targetPivot.x, y: targetPivot.y } as any;
  133. this.parent.worldTransform.apply(point, point);
  134. let yIndex = 0, xIndex = 0;
  135. if (index == 3) {
  136. yIndex = 0;
  137. xIndex = 2;
  138. } else if (index == 0) {
  139. yIndex = 3;
  140. xIndex = 1;
  141. } else if (index == 1) {
  142. yIndex = 2;
  143. xIndex = 0;
  144. } else if (index == 2) {
  145. yIndex = 1;
  146. xIndex = 3;
  147. }
  148. let pointY = pivots[yIndex];
  149. let pY = { x: pointY.x, y: pointY.y } as any;
  150. this.parent.worldTransform.apply(pY, pY);
  151. let pointX = pivots[xIndex];
  152. let pX = { x: pointX.x, y: pointX.y } as any;
  153. this.parent.worldTransform.apply(pX, pX);
  154. let xVec = { x: (pX.x - point.x), y: (pX.y - point.y) };
  155. let yVec = { x: (pY.x - point.x), y: (pY.y - point.y) };
  156. return { x: xVec, y: yVec };
  157. }
  158. scale(x:number, y:number) {
  159. this.parent.scale.x = x;
  160. this.parent.scale.y = y;
  161. this.parent.updateTransform();
  162. this.updateCompState();
  163. }
  164. scaleX(x:number) {
  165. this.parent.scale.x = x;
  166. this.parent.updateTransform();
  167. this.updateCompState();
  168. }
  169. scaleY(y:number) {
  170. this.parent.scale.y = y;
  171. this.parent.updateTransform();
  172. this.updateCompState();
  173. }
  174. applyChildWidth(option:{Width?:number, Height?:number}) {
  175. if (this.selected.length != 1) return;
  176. const obj = this.selected[0];
  177. //先移除
  178. this.parent.removeChildWorldNoChange(obj);
  179. const m = new Matrix();
  180. m.scale(option.Width ? option.Width/obj.width :1 , option.Height? option.Height / obj.height: 1)
  181. m.invert();
  182. m.prepend(obj.worldTransform)
  183. obj.transform.setFromMatrix(m)
  184. if (option.Width) {
  185. obj.width = option.Width
  186. }
  187. if (option.Height) {
  188. obj.height = option.Height
  189. }
  190. obj.updateTransform();
  191. this.parent.addChildWorldNoChange(obj);
  192. }
  193. scaleSize(Width:number, Height:number) {
  194. this.parent.scale.y = Height / this.rect.height
  195. this.parent.scale.x = Width / this.rect.width
  196. this.parent.updateTransform();
  197. this.applyChildWidth({Width, Height})
  198. this.updateCompState();
  199. }
  200. scaleWidth(Width:number) {
  201. //怎么改对应的偏移值
  202. this.parent.scale.x = Width / this.rect.width
  203. this.parent.updateTransform();
  204. this.applyChildWidth({Width})
  205. this.updateCompState();
  206. }
  207. scaleHeight(Height:number) {
  208. this.parent.scale.y = Height / this.rect.height
  209. this.parent.updateTransform();
  210. this.applyChildWidth({Height});
  211. this.updateCompState();
  212. }
  213. translate(x:number, y:number) {
  214. this.parent.x += x;
  215. this.parent.y += y;
  216. this.parent.updateTransform();
  217. this.updateCompState();
  218. }
  219. destroy() {//选中的对象坐标转到画布空间坐标
  220. let selected = this.selected;
  221. let n = selected.length;
  222. while (n--) {
  223. let child = selected[n];
  224. child.updateTransform();
  225. //世界坐标
  226. child.transform.setFromMatrix(child.worldTransform);
  227. child.parent = null;
  228. child.transform._parentID = -1;
  229. child.updateTransform();
  230. child._boundsID = -2;
  231. child._lastBoundsID = 0;
  232. }
  233. }
  234. updateCompState() {
  235. let n = this.selected.length;
  236. while (n--) {
  237. let child = this.selected[n];
  238. child.comp.layout.transformMatrix = child.worldTransform.getMatrixStr();
  239. }
  240. }
  241. }