canvas.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  4. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  5. var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
  6. var _emit = _interopRequireDefault(require("./event/emit"));
  7. var _controller = _interopRequireDefault(require("./event/controller"));
  8. var _canvasElement = _interopRequireDefault(require("./canvas-element"));
  9. function _createSuper(Derived) { return function () { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
  10. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
  11. var Util = require('../util/common');
  12. var Container = require('./container');
  13. var Group = require('./group');
  14. var _require = require('./util/requestAnimationFrame'),
  15. requestAnimationFrame = _require.requestAnimationFrame;
  16. var Canvas = /*#__PURE__*/function (_EventEmit) {
  17. (0, _inheritsLoose2["default"])(Canvas, _EventEmit);
  18. var _super = _createSuper(Canvas);
  19. var _proto = Canvas.prototype;
  20. _proto.get = function get(name) {
  21. return this._attrs[name];
  22. };
  23. _proto.set = function set(name, value) {
  24. this._attrs[name] = value;
  25. };
  26. function Canvas(cfg) {
  27. var _this;
  28. _this = _EventEmit.call(this) || this;
  29. _this._attrs = Util.mix({
  30. type: 'canvas',
  31. children: []
  32. }, cfg);
  33. _this._initPixelRatio();
  34. _this._initCanvas();
  35. return _this;
  36. }
  37. _proto._initPixelRatio = function _initPixelRatio() {
  38. var pixelRatio = this.get('pixelRatio');
  39. if (!pixelRatio) {
  40. this.set('pixelRatio', Util.getPixelRatio());
  41. }
  42. };
  43. _proto.beforeDraw = function beforeDraw() {
  44. var context = this._attrs.context;
  45. var el = this._attrs.el;
  46. context && context.clearRect && context.clearRect(0, 0, el.width, el.height);
  47. };
  48. _proto._initCanvas = function _initCanvas() {
  49. var self = this;
  50. var el = self.get('el');
  51. var context = self.get('context');
  52. if (!el && !context) {
  53. throw new Error('Please specify the id, el or context of the chart!');
  54. }
  55. var canvas;
  56. if (el) {
  57. // DOMElement or String
  58. canvas = Util.isString(el) ? Util.getDomById(el) : el;
  59. } else {
  60. // 说明没有指定el
  61. canvas = _canvasElement["default"].create(context);
  62. }
  63. if (context && canvas && !canvas.getContext) {
  64. canvas.getContext = function () {
  65. return context;
  66. };
  67. }
  68. var width = self.get('width');
  69. if (!width) {
  70. width = Util.getWidth(canvas);
  71. }
  72. var height = self.get('height');
  73. if (!height) {
  74. height = Util.getHeight(canvas);
  75. }
  76. self.set('canvas', this);
  77. self.set('el', canvas);
  78. self.set('context', context || canvas.getContext('2d'));
  79. self.changeSize(width, height); // 初始化事件控制器
  80. var eventController = new _controller["default"]({
  81. canvas: this,
  82. el: canvas
  83. });
  84. self.set('eventController', eventController);
  85. };
  86. _proto.changeSize = function changeSize(width, height) {
  87. var pixelRatio = this.get('pixelRatio');
  88. var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
  89. // 浏览器环境设置style样式
  90. if (canvasDOM.style) {
  91. canvasDOM.style.width = width + 'px';
  92. canvasDOM.style.height = height + 'px';
  93. }
  94. if (Util.isCanvasElement(canvasDOM)) {
  95. canvasDOM.width = width * pixelRatio;
  96. canvasDOM.height = height * pixelRatio;
  97. if (pixelRatio !== 1) {
  98. var ctx = this.get('context');
  99. ctx.scale(pixelRatio, pixelRatio);
  100. }
  101. }
  102. this.set('width', width);
  103. this.set('height', height);
  104. };
  105. _proto.getWidth = function getWidth() {
  106. var pixelRatio = this.get('pixelRatio');
  107. var width = this.get('width');
  108. return width * pixelRatio;
  109. };
  110. _proto.getHeight = function getHeight() {
  111. var pixelRatio = this.get('pixelRatio');
  112. var height = this.get('height');
  113. return height * pixelRatio;
  114. };
  115. _proto.getPointByClient = function getPointByClient(clientX, clientY) {
  116. var el = this.get('el');
  117. var bbox = el.getBoundingClientRect();
  118. var width = bbox.right - bbox.left;
  119. var height = bbox.bottom - bbox.top;
  120. return {
  121. x: (clientX - bbox.left) * (el.width / width),
  122. y: (clientY - bbox.top) * (el.height / height)
  123. };
  124. };
  125. _proto._beginDraw = function _beginDraw() {
  126. this._attrs.toDraw = true;
  127. };
  128. _proto._endDraw = function _endDraw() {
  129. this._attrs.toDraw = false;
  130. };
  131. _proto.draw = function draw() {
  132. var self = this;
  133. function drawInner() {
  134. self.set('animateHandler', requestAnimationFrame(function () {
  135. self.set('animateHandler', undefined);
  136. if (self.get('toDraw')) {
  137. drawInner();
  138. }
  139. }));
  140. self.beforeDraw();
  141. try {
  142. var context = self._attrs.context;
  143. var children = self._attrs.children;
  144. for (var i = 0, len = children.length; i < len; i++) {
  145. var child = children[i];
  146. child.draw(context);
  147. } // 支付宝,微信小程序,需要调context.draw才能完成绘制, 所以这里直接判断是否有.draw方法
  148. if (context.draw) {
  149. context.draw();
  150. }
  151. } catch (ev) {
  152. console.warn('error in draw canvas, detail as:');
  153. console.warn(ev);
  154. self._endDraw();
  155. }
  156. self._endDraw();
  157. }
  158. if (self.get('destroyed')) {
  159. return;
  160. }
  161. if (self.get('animateHandler')) {
  162. this._beginDraw();
  163. } else {
  164. drawInner();
  165. }
  166. };
  167. _proto.destroy = function destroy() {
  168. if (this.get('destroyed')) {
  169. return;
  170. } // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
  171. // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
  172. // https://github.com/antvis/F2/issues/630
  173. var el = this.get('el');
  174. el.width = 0;
  175. el.height = 0;
  176. this.clear();
  177. this._attrs = {};
  178. this.set('destroyed', true);
  179. };
  180. _proto.isDestroyed = function isDestroyed() {
  181. return this.get('destroyed');
  182. };
  183. return Canvas;
  184. }(_emit["default"]);
  185. Util.mix(Canvas.prototype, Container, {
  186. getGroupClass: function getGroupClass() {
  187. return Group;
  188. }
  189. });
  190. module.exports = Canvas;