SCanvasView.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. extendStatics(d, b);
  11. function __() { this.constructor = d; }
  12. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13. };
  14. })();
  15. Object.defineProperty(exports, "__esModule", { value: true });
  16. exports.SCanvasView = void 0;
  17. var base_1 = require("@persagy-web/base");
  18. var SSvgPaintEngine_1 = require("./engines/SSvgPaintEngine");
  19. var SPoint_1 = require("./types/SPoint");
  20. var SPainter_1 = require("./SPainter");
  21. var SCanvasView = (function (_super) {
  22. __extends(SCanvasView, _super);
  23. function SCanvasView(id) {
  24. var _this = _super.call(this) || this;
  25. _this._needDraw = true;
  26. _this._origin = new SPoint_1.SPoint();
  27. _this.moveable = true;
  28. _this._scale = 1;
  29. _this.scalable = true;
  30. _this.wheelZoom = 1.05;
  31. _this.minScale = 0.000001;
  32. _this.maxScale = 1000000;
  33. _this._lastFrameTime = 0;
  34. _this._midKeyPos = new SPoint_1.SPoint();
  35. _this._touchState = base_1.STouchState.None;
  36. _this._touchPoint = new SPoint_1.SPoint();
  37. _this._beforeLength = 0;
  38. _this._afterLength = 0;
  39. _this.canvasView = document.getElementById(id);
  40. _this.bindEvent(_this.canvasView);
  41. _this.requestAnimationFrame(_this.loop.bind(_this));
  42. return _this;
  43. }
  44. Object.defineProperty(SCanvasView.prototype, "canvas", {
  45. get: function () {
  46. return this.canvasView.getContext("2d");
  47. },
  48. enumerable: false,
  49. configurable: true
  50. });
  51. Object.defineProperty(SCanvasView.prototype, "width", {
  52. get: function () {
  53. return this.canvasView.width;
  54. },
  55. enumerable: false,
  56. configurable: true
  57. });
  58. Object.defineProperty(SCanvasView.prototype, "height", {
  59. get: function () {
  60. return this.canvasView.height;
  61. },
  62. enumerable: false,
  63. configurable: true
  64. });
  65. Object.defineProperty(SCanvasView.prototype, "origin", {
  66. get: function () {
  67. return this._origin;
  68. },
  69. set: function (v) {
  70. if (!this.moveable) {
  71. return;
  72. }
  73. this._origin.x = v.x;
  74. this._origin.y = v.y;
  75. this._needDraw = true;
  76. },
  77. enumerable: false,
  78. configurable: true
  79. });
  80. Object.defineProperty(SCanvasView.prototype, "scale", {
  81. get: function () {
  82. return this._scale;
  83. },
  84. set: function (v) {
  85. if (!this.scalable) {
  86. return;
  87. }
  88. this._scale = v;
  89. this._needDraw = true;
  90. },
  91. enumerable: false,
  92. configurable: true
  93. });
  94. Object.defineProperty(SCanvasView.prototype, "cursor", {
  95. set: function (v) {
  96. this.canvasView.style.cursor = v;
  97. },
  98. enumerable: false,
  99. configurable: true
  100. });
  101. SCanvasView.prototype.update = function () {
  102. this._needDraw = true;
  103. };
  104. SCanvasView.prototype.saveImage = function (name, type) {
  105. var url = this.canvasView.toDataURL("image/" + type);
  106. base_1.SNetUtil.downLoad(name, url);
  107. };
  108. SCanvasView.prototype.imageUrl = function (type) {
  109. return this.canvasView.toDataURL("image/" + type);
  110. };
  111. SCanvasView.prototype.saveSvg = function (name) {
  112. var url = URL.createObjectURL(new Blob([this.svgData()], { type: "text/xml,charset=UTF-8" }));
  113. base_1.SNetUtil.downLoad(name, url);
  114. };
  115. SCanvasView.prototype.svgData = function () {
  116. var engine = new SSvgPaintEngine_1.SSvgPaintEngine(this.width, this.height);
  117. var painter = new SPainter_1.SPainter(engine);
  118. this.onDraw(painter);
  119. return engine.toSvg();
  120. };
  121. SCanvasView.prototype.scaleByPoint = function (zoom, x0, y0) {
  122. if (!this.scalable) {
  123. return;
  124. }
  125. var z = zoom;
  126. if (this.scale * zoom >= this.maxScale) {
  127. z = this.maxScale / this.scale;
  128. this.scale = this.maxScale;
  129. }
  130. else if (this.scale * zoom <= this.minScale) {
  131. z = this.minScale / this.scale;
  132. this.scale = this.minScale;
  133. }
  134. else {
  135. this.scale *= zoom;
  136. }
  137. this.origin.x = x0 - (x0 - this.origin.x) * z;
  138. this.origin.y = y0 - (y0 - this.origin.y) * z;
  139. };
  140. SCanvasView.prototype.loop = function () {
  141. var ctx = this.canvas;
  142. if (null != ctx && this._needDraw) {
  143. this._needDraw = false;
  144. var painter = new SPainter_1.SPainter(this);
  145. this.onDraw(painter);
  146. }
  147. this.requestAnimationFrame(this.loop.bind(this));
  148. };
  149. SCanvasView.prototype.onDraw = function (painter) { };
  150. SCanvasView.prototype.onClick = function (event) { };
  151. SCanvasView.prototype.onDoubleClick = function (event) { };
  152. SCanvasView.prototype.onMouseDown = function (event) {
  153. var se = new base_1.SMouseEvent(event);
  154. if (se.buttons & base_1.SMouseButton.MidButton) {
  155. this._midKeyPos.x = se.x;
  156. this._midKeyPos.y = se.y;
  157. }
  158. };
  159. SCanvasView.prototype.onMouseMove = function (event) {
  160. if (this.moveable) {
  161. var se = new base_1.SMouseEvent(event);
  162. if (se.buttons & base_1.SMouseButton.MidButton) {
  163. this.origin.x += se.x - this._midKeyPos.x;
  164. this.origin.y += se.y - this._midKeyPos.y;
  165. this._midKeyPos.x = se.x;
  166. this._midKeyPos.y = se.y;
  167. this.update();
  168. return;
  169. }
  170. }
  171. };
  172. SCanvasView.prototype.onMouseUp = function (event) { };
  173. SCanvasView.prototype.onContextMenu = function (event) { };
  174. SCanvasView.prototype.onMouseWheel = function (event) {
  175. if (event.deltaY < 0) {
  176. this.scaleByPoint(this.wheelZoom, event.offsetX, event.offsetY);
  177. }
  178. else {
  179. this.scaleByPoint(1 / this.wheelZoom, event.offsetX, event.offsetY);
  180. }
  181. };
  182. SCanvasView.prototype.onKeyDown = function (event) { };
  183. SCanvasView.prototype.onKeyPress = function (event) { };
  184. SCanvasView.prototype.onKeyUp = function (event) { };
  185. SCanvasView.prototype.onTouchStart = function (event) {
  186. var touches = event.touches;
  187. if (touches.length == 1) {
  188. this._touchPoint.x = event.touches[0].clientX;
  189. this._touchPoint.y = event.touches[0].clientY;
  190. }
  191. if (touches.length == 2) {
  192. this._touchState = base_1.STouchState.Zoom;
  193. this._beforeLength = this.getDistance(event);
  194. }
  195. };
  196. SCanvasView.prototype.onTouchMove = function (event) {
  197. var touches = event.touches;
  198. if (touches.length == 1) {
  199. this.origin.x += event.touches[0].clientX - this._touchPoint.x;
  200. this.origin.y += event.touches[0].clientY - this._touchPoint.y;
  201. this._touchPoint.x = event.touches[0].clientX;
  202. this._touchPoint.y = event.touches[0].clientY;
  203. }
  204. if (touches.length == 2) {
  205. this.viewZoom(event);
  206. }
  207. };
  208. SCanvasView.prototype.onTouchEnd = function (event) {
  209. this._touchState = base_1.STouchState.None;
  210. };
  211. SCanvasView.prototype.onResize = function (event) { };
  212. SCanvasView.prototype.bindEvent = function (element) {
  213. element.onclick = this.onClick.bind(this);
  214. element.ondblclick = this.onDoubleClick.bind(this);
  215. element.onmousedown = this.onMouseDown.bind(this);
  216. element.onmousemove = this.onMouseMove.bind(this);
  217. element.onmouseup = this.onMouseUp.bind(this);
  218. element.oncontextmenu = this.onContextMenu.bind(this);
  219. element.onwheel = this.onMouseWheel.bind(this);
  220. element.onkeydown = this.onKeyDown.bind(this);
  221. element.onkeypress = this.onKeyPress.bind(this);
  222. element.onkeyup = this.onKeyUp.bind(this);
  223. element.ontouchstart = this.onTouchStart.bind(this);
  224. element.ontouchmove = this.onTouchMove.bind(this);
  225. element.ontouchend = this.onTouchEnd.bind(this);
  226. element.onresize = this.onResize.bind(this);
  227. };
  228. SCanvasView.prototype.requestAnimationFrame = function (callback) {
  229. var currTime = new Date().getTime();
  230. var timeToCall = Math.max(0, 16 - (currTime - this._lastFrameTime));
  231. var id = setTimeout(function () {
  232. callback(currTime + timeToCall);
  233. }, timeToCall);
  234. this._lastFrameTime = currTime + timeToCall;
  235. return id;
  236. };
  237. SCanvasView.prototype.viewZoom = function (event) {
  238. if (this._touchState == base_1.STouchState.Zoom) {
  239. this._afterLength = this.getDistance(event);
  240. var gapLenght = this._afterLength - this._beforeLength;
  241. if (Math.abs(gapLenght) > 5 && this._beforeLength != 0.0) {
  242. var tempScale = this._afterLength / this._beforeLength;
  243. var p = this.getMiddlePoint(event);
  244. this.scaleByPoint(tempScale, p.x, p.y);
  245. this._beforeLength = this._afterLength;
  246. }
  247. }
  248. return true;
  249. };
  250. SCanvasView.prototype.getDistance = function (event) {
  251. if (event.touches.length < 2) {
  252. return 0;
  253. }
  254. var dx = event.touches[0].clientX - event.touches[1].clientX;
  255. var dy = event.touches[0].clientY - event.touches[1].clientY;
  256. return Math.sqrt(dx * dx + dy * dy);
  257. };
  258. SCanvasView.prototype.getMiddlePoint = function (event) {
  259. return new SPoint_1.SPoint((event.touches[0].clientX + event.touches[1].clientX) / 2, (event.touches[0].clientY + event.touches[1].clientY) / 2);
  260. };
  261. return SCanvasView;
  262. }(base_1.SObject));
  263. exports.SCanvasView = SCanvasView;