Viewport.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import {Vector2} from "./math/Vector2.js";
  2. import {Matrix} from "./math/Matrix.js";
  3. import {UUID} from "./math/UUID.js";
  4. /**
  5. * Viewport defines the user view into the content being rendered, similar to a camera it defines the size of the content, rotation and position of the content.
  6. *
  7. * The viewport can be moved, rotated and scaled to navigate the virtual canvas.
  8. *
  9. * @class
  10. * @param {Element} canvas Canvas DOM element where the viewport is being rendered.
  11. */
  12. function Viewport(canvas)
  13. {
  14. /**
  15. * UUID of the object.
  16. *
  17. * @type {string}
  18. */
  19. this.uuid = UUID.generate();
  20. /**
  21. * Canvas DOM element where the viewport is being rendered.
  22. *
  23. * @type {Element}
  24. */
  25. this.canvas = canvas;
  26. /**
  27. * Position of the viewport.
  28. *
  29. * @type {Vector2}
  30. */
  31. this.position = new Vector2(0, 0);
  32. /**
  33. * Center point of the viewport. Relative to the size of the canvas.
  34. *
  35. * Rotation and zoom is applied relative to this point.
  36. *
  37. * @type {Vector2}
  38. */
  39. this.center = new Vector2(0, 0);
  40. /**
  41. * Scale of the object.
  42. *
  43. * @type {number}
  44. */
  45. this.scale = 1.0
  46. /**
  47. * Rotation of the object relative to its center.
  48. *
  49. * @type {number}
  50. */
  51. this.rotation = 0.0;
  52. /**
  53. * Local transformation matrix applied to the object.
  54. *
  55. * @type {Matrix}
  56. */
  57. this.matrix = new Matrix();
  58. /**
  59. * Inverse of the local transformation matrix.
  60. *
  61. * Used to transform points from local to global coordinates.
  62. *
  63. * @type {Matrix}
  64. */
  65. this.inverseMatrix = new Matrix();
  66. /**
  67. * If true the matrix is updated before rendering the object.
  68. *
  69. * Disable this if you want to update the matrix manually.
  70. *
  71. * @type {boolean}
  72. */
  73. this.matrixNeedsUpdate = true;
  74. /**
  75. * Flag to indicate if the viewport should move when scaling.
  76. *
  77. * For some application its easier to focus the target if the viewport moves to the pointer location while scaling.
  78. */
  79. this.centerOnPointer = false;
  80. /**
  81. * Value of the initial point of rotation if the viewport is being rotated.
  82. *
  83. * Is set to null when the viewport is not being rotated.
  84. */
  85. this.rotationPoint = null;
  86. }
  87. /**
  88. * Calculate and update the viewport transformation matrix.
  89. *
  90. * Also updates the inverse matrix of the viewport.
  91. */
  92. Viewport.prototype.updateMatrix = function()
  93. {
  94. if(this.matrixNeedsUpdate)
  95. {
  96. this.matrix.m = [1, 0, 0, 1, this.position.x , this.position.y];
  97. if(this.center.x !== 0.0 || this.center.y !== 0.0) {
  98. this.matrix.multiply(new Matrix([1, 0, 0, 1, this.center.x, this.center.y]));
  99. }
  100. if(this.rotation !== 0.0)
  101. {
  102. var c = Math.cos(this.rotation);
  103. var s = Math.sin(this.rotation);
  104. this.matrix.multiply(new Matrix([c, s, -s, c, 0, 0]));
  105. }
  106. if(this.scale !== 1.0)
  107. {
  108. this.matrix.multiply(new Matrix([this.scale, 0, 0, this.scale, 0, 0]));
  109. }
  110. if(this.center.x !== 0.0 || this.center.y !== 0.0) {
  111. this.matrix.multiply(new Matrix([1, 0, 0, 1, -this.center.x, -this.center.y]));
  112. }
  113. this.inverseMatrix = this.matrix.getInverse();
  114. this.matrixNeedsUpdate = false;
  115. }
  116. };
  117. /**
  118. * Center the viewport relative to a object.
  119. *
  120. * The position of the object is used a central point, this method does not consider "box" attributes or other strucures in the object.
  121. *
  122. * Uses the object's local transformation matrix and the canvas size to calculate the new position of the viewport.
  123. *
  124. * @param {Object2D} object Object to be centered on the viewport.
  125. * @param {Element} canvas Canvas element where the image is drawn.
  126. */
  127. Viewport.prototype.centerObject = function(object, canvas)
  128. {
  129. var position = object.globalMatrix.transformPoint(new Vector2());
  130. position.multiplyScalar(-this.scale);
  131. position.x += canvas.width / 2;
  132. position.y += canvas.height / 2;
  133. this.position.copy(position);
  134. this.matrixNeedsUpdate = true;
  135. };
  136. export {Viewport};