compObj.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { DesignComp } from "../../objects/DesignTemp/DesignComp";
  2. import { history } from "../../objects/DesignTemp/factory";
  3. import { RxValue } from "../ReactCtrl/rxValue";
  4. import { Matrix } from "./matrix";
  5. import { DisplayObject } from "./objects/displayObject";
  6. import { isRectInter } from "./objects/mathUtils";
  7. import { Rectangle } from "./objects/rectangle";
  8. import { Transform } from "./objects/transform";
  9. function designSizeToPx(value: number) {
  10. return value / 2.0;
  11. }
  12. function pxToDesignSize(value: number) {
  13. return value * 2.0;
  14. }
  15. export class CompObject extends DisplayObject {
  16. // @ts-ignore
  17. comp:DesignComp;
  18. rect = new Rectangle();
  19. state = RxValue.create({
  20. transform: {
  21. x: 0,
  22. y: 0,
  23. w: 0,
  24. h: 0,
  25. sx: 0,
  26. sy: 0,
  27. r: 0,
  28. }
  29. })
  30. constructor(c:DesignComp, usHistory = false) {
  31. super();
  32. if(!c) return
  33. this.comp = c;
  34. const wmtx = Matrix.createFromMatrixStr(c.layout.transformMatrix || "matrix(1,0,0,1,0,0)")
  35. const s = wmtx.getScale();
  36. let t = {
  37. x: wmtx.tx,
  38. y: wmtx.ty,
  39. sx: s.x,
  40. sy: s.y,
  41. w: designSizeToPx(c.layout.size[0]),
  42. h: designSizeToPx(c.layout.size[1]),
  43. r: wmtx.getRotate()
  44. }
  45. this.state.setTransform(t);
  46. let inited = true;
  47. this.state.onTransformChanged((tsf)=>{
  48. this.setTransform(tsf.x, tsf.y, tsf.sx, tsf.sy, tsf.r, 0, 0, 0, 0);
  49. this.updateTransform();
  50. if (!inited) {
  51. const s:any = [pxToDesignSize(tsf.w), pxToDesignSize(tsf.h)];
  52. if(!this.comp.layout.setSize) return
  53. this.comp.layout.setSize(s);
  54. this.comp.layout.setTransformMatrix(this.worldTransform.getMatrixStr())
  55. }
  56. inited = false;
  57. })
  58. if (usHistory) {
  59. this.state.setHistory(history);
  60. }
  61. }
  62. get width() {
  63. return this.state.transform.w;
  64. }
  65. set width( value ) {
  66. const t = {...this.state.transform};
  67. t.w = value;
  68. this.state.setTransform(t);
  69. }
  70. setSize(w:number, h: number) {
  71. const t = {...this.state.transform};
  72. t.w = w;
  73. t.h = h;
  74. this.state.setTransform(t);
  75. }
  76. set height( value ) {
  77. const t = {...this.state.transform};
  78. t.h = value;
  79. console.log("hhh=>", t.h, t.sy);
  80. this.state.setTransform(t);
  81. }
  82. get height() {
  83. return this.state.transform.h
  84. }
  85. translate(x:number, y:number) {
  86. const t = {...this.state.transform};
  87. t.x +=x;
  88. t.y +=y;
  89. this.state.setTransform(t);
  90. }
  91. setMatrix(m:Matrix) {
  92. const t = {...this.state.transform};
  93. const s = m.getScale();
  94. t.x = m.tx;
  95. t.y = m.ty;
  96. t.sx = s.x;
  97. t.sy = s.y;
  98. t.r = m.getRotate();
  99. this.state.setTransform(t);
  100. }
  101. getRect(){
  102. let p1 = {x:0,y:0} as any;
  103. this.worldTransform.apply(p1, p1);
  104. let p2 = {x: this.width , y:0} as any;
  105. this.worldTransform.apply(p2, p2);
  106. let p3 = {x:this.width,y:this.height} as any;
  107. this.worldTransform.apply(p3, p3);
  108. let p4 = {x:0,y:this.height} as any;
  109. this.worldTransform.apply(p4, p4);
  110. return {p1,p2,p3,p4};
  111. }
  112. //判定兩個矩形有没有相交
  113. //依据四个定点是否有相交
  114. testRect(posSize:any, more = true) {
  115. let {x,y,w,h} = posSize;
  116. let rect1 = {p1:{x,y},p2:{x:x+w,y},p3:{x:x+w,y:y+h},p4:{x:x,y:y+h}};
  117. let rect2 = this.getRect();
  118. if( more ) return isRectInter(rect1, rect2);
  119. //框选模式,包含才匹配
  120. let minX = x, maxX = x + w;
  121. let minY = y, maxY = y + h;
  122. let ponts = [rect2.p1, rect2.p2, rect2.p3, rect2.p4];
  123. let n = ponts.length;
  124. while( n-- ) {
  125. let p = ponts[n];
  126. if( p.x < minX || p.x > maxX || p.y < minY || p.y > maxY ) return false;
  127. }
  128. return true;
  129. }
  130. calculateBounds()
  131. {
  132. this._bounds.clear();
  133. this._bounds.addFrame(this.transform, 0,0, this.width, this.height);
  134. return this._bounds;
  135. }
  136. testClick(sx:number,sy:number)
  137. {
  138. let w = this.width;
  139. let h = this.height;
  140. let local = {x:0,y:0} as any;
  141. this.worldTransform.applyInverse({x:sx,y:sy} as any, local);
  142. if( local.x < 0 || local.x > w ) return false;
  143. if( local.y < 0 || local.y > h ) return false;
  144. return true;
  145. }
  146. getBox()
  147. {
  148. let rect = this.getBounds(false, this.rect);
  149. return {x:rect.x, y:rect.y, w:rect.width, h:rect.height};
  150. }
  151. getAabb() {
  152. let aabb = this.getBounds(false, this.rect)
  153. return {xmin:aabb.left,ymin:aabb.top, xmax:aabb.right, ymax:aabb.bottom};
  154. }
  155. center() {
  156. let p = {x:this.width/2,y:this.height /2} as any;
  157. this.worldTransform.apply(p,p);
  158. return p;
  159. }
  160. }