compObj.ts 4.9 KB

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