line.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GUI {
  3. /** Class used to render 2D lines */
  4. export class Line extends Control {
  5. private _lineWidth = 1;
  6. private _x1 = new ValueAndUnit(0);
  7. private _y1 = new ValueAndUnit(0);
  8. private _x2 = new ValueAndUnit(0);
  9. private _y2 = new ValueAndUnit(0);
  10. private _dash = new Array<number>();
  11. private _connectedControl: Control;
  12. private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
  13. /** Gets or sets the dash pattern */
  14. public get dash(): Array<number> {
  15. return this._dash;
  16. }
  17. public set dash(value: Array<number>) {
  18. if (this._dash === value) {
  19. return;
  20. }
  21. this._dash = value;
  22. this._markAsDirty();
  23. }
  24. /** Gets or sets the control connected with the line end */
  25. public get connectedControl(): Control {
  26. return this._connectedControl;
  27. }
  28. public set connectedControl(value: Control) {
  29. if (this._connectedControl === value) {
  30. return;
  31. }
  32. if (this._connectedControlDirtyObserver && this._connectedControl) {
  33. this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
  34. this._connectedControlDirtyObserver = null;
  35. }
  36. if (value) {
  37. this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
  38. }
  39. this._connectedControl = value;
  40. this._markAsDirty();
  41. }
  42. /** Gets or sets start coordinates on X axis */
  43. public get x1(): string | number {
  44. return this._x1.toString(this._host);
  45. }
  46. public set x1(value: string | number ) {
  47. if (this._x1.toString(this._host) === value) {
  48. return;
  49. }
  50. if (this._x1.fromString(value)) {
  51. this._markAsDirty();
  52. }
  53. }
  54. /** Gets or sets start coordinates on Y axis */
  55. public get y1(): string | number {
  56. return this._y1.toString(this._host);
  57. }
  58. public set y1(value: string | number ) {
  59. if (this._y1.toString(this._host) === value) {
  60. return;
  61. }
  62. if (this._y1.fromString(value)) {
  63. this._markAsDirty();
  64. }
  65. }
  66. /** Gets or sets end coordinates on X axis */
  67. public get x2(): string | number {
  68. return this._x2.toString(this._host);
  69. }
  70. public set x2(value: string | number ) {
  71. if (this._x2.toString(this._host) === value) {
  72. return;
  73. }
  74. if (this._x2.fromString(value)) {
  75. this._markAsDirty();
  76. }
  77. }
  78. /** Gets or sets end coordinates on Y axis */
  79. public get y2(): string | number {
  80. return this._y2.toString(this._host);
  81. }
  82. public set y2(value: string | number ) {
  83. if (this._y2.toString(this._host) === value) {
  84. return;
  85. }
  86. if (this._y2.fromString(value)) {
  87. this._markAsDirty();
  88. }
  89. }
  90. /** Gets or sets line width */
  91. public get lineWidth(): number {
  92. return this._lineWidth;
  93. }
  94. public set lineWidth(value: number) {
  95. if (this._lineWidth === value) {
  96. return;
  97. }
  98. this._lineWidth = value;
  99. this._markAsDirty();
  100. }
  101. /** Gets or sets horizontal alignment */
  102. public set horizontalAlignment(value: number) {
  103. return;
  104. }
  105. /** Gets or sets vertical alignment */
  106. public set verticalAlignment(value: number) {
  107. return;
  108. }
  109. private get _effectiveX2(): number {
  110. return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
  111. }
  112. private get _effectiveY2(): number {
  113. return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
  114. }
  115. /**
  116. * Creates a new Line
  117. * @param name defines the control name
  118. */
  119. constructor(public name?: string) {
  120. super(name);
  121. this.isHitTestVisible = false;
  122. this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  123. this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
  124. }
  125. protected _getTypeName(): string {
  126. return "Line";
  127. }
  128. public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  129. context.save();
  130. if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
  131. context.shadowColor = this.shadowColor;
  132. context.shadowBlur = this.shadowBlur;
  133. context.shadowOffsetX = this.shadowOffsetX;
  134. context.shadowOffsetY = this.shadowOffsetY;
  135. }
  136. this._applyStates(context);
  137. if (this._processMeasures(parentMeasure, context)) {
  138. context.strokeStyle = this.color;
  139. context.lineWidth = this._lineWidth;
  140. context.setLineDash(this._dash);
  141. context.beginPath();
  142. context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
  143. context.lineTo(this._effectiveX2, this._effectiveY2);
  144. context.stroke();
  145. }
  146. context.restore();
  147. }
  148. public _measure(): void {
  149. // Width / Height
  150. this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
  151. this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
  152. }
  153. protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  154. this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
  155. this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;
  156. }
  157. /**
  158. * Move one end of the line given 3D cartesian coordinates.
  159. * @param position Targeted world position
  160. * @param scene Scene
  161. * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
  162. */
  163. public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
  164. if (!this._host || this._root !== this._host._rootContainer) {
  165. Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
  166. return;
  167. }
  168. var globalViewport = this._host._getGlobalViewport(scene);
  169. var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
  170. this._moveToProjectedPosition(projectedPosition, end)
  171. if (projectedPosition.z < 0 || projectedPosition.z > 1) {
  172. this.notRenderable = true;
  173. return;
  174. }
  175. this.notRenderable = false;
  176. }
  177. /**
  178. * Move one end of the line to a position in screen absolute space.
  179. * @param projectedPosition Position in screen absolute space (X, Y)
  180. * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
  181. */
  182. public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
  183. let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
  184. let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
  185. if (end) {
  186. this.x2 = x;
  187. this.y2 = y;
  188. this._x2.ignoreAdaptiveScaling = true;
  189. this._y2.ignoreAdaptiveScaling = true;
  190. } else {
  191. this.x1 = x;
  192. this.y1 = y;
  193. this._x1.ignoreAdaptiveScaling = true;
  194. this._y1.ignoreAdaptiveScaling = true;
  195. }
  196. }
  197. }
  198. }