Painter.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. import { devicePixelRatio } from '../config.js';
  2. import * as util from '../core/util.js';
  3. import Layer from './Layer.js';
  4. import requestAnimationFrame from '../animation/requestAnimationFrame.js';
  5. import env from '../core/env.js';
  6. import { brush, brushSingle } from './graphic.js';
  7. import { REDRAW_BIT } from '../graphic/constants.js';
  8. import { getSize } from './helper.js';
  9. var HOVER_LAYER_ZLEVEL = 1e5;
  10. var CANVAS_ZLEVEL = 314159;
  11. var EL_AFTER_INCREMENTAL_INC = 0.01;
  12. var INCREMENTAL_INC = 0.001;
  13. function isLayerValid(layer) {
  14. if (!layer) {
  15. return false;
  16. }
  17. if (layer.__builtin__) {
  18. return true;
  19. }
  20. if (typeof (layer.resize) !== 'function'
  21. || typeof (layer.refresh) !== 'function') {
  22. return false;
  23. }
  24. return true;
  25. }
  26. function createRoot(width, height) {
  27. var domRoot = document.createElement('div');
  28. domRoot.style.cssText = [
  29. 'position:relative',
  30. 'width:' + width + 'px',
  31. 'height:' + height + 'px',
  32. 'padding:0',
  33. 'margin:0',
  34. 'border-width:0'
  35. ].join(';') + ';';
  36. return domRoot;
  37. }
  38. var CanvasPainter = (function () {
  39. function CanvasPainter(root, storage, opts, id) {
  40. this.type = 'canvas';
  41. this._zlevelList = [];
  42. this._prevDisplayList = [];
  43. this._layers = {};
  44. this._layerConfig = {};
  45. this._needsManuallyCompositing = false;
  46. this.type = 'canvas';
  47. var singleCanvas = !root.nodeName
  48. || root.nodeName.toUpperCase() === 'CANVAS';
  49. this._opts = opts = util.extend({}, opts || {});
  50. this.dpr = opts.devicePixelRatio || devicePixelRatio;
  51. this._singleCanvas = singleCanvas;
  52. this.root = root;
  53. var rootStyle = root.style;
  54. if (rootStyle) {
  55. util.disableUserSelect(root);
  56. root.innerHTML = '';
  57. }
  58. this.storage = storage;
  59. var zlevelList = this._zlevelList;
  60. this._prevDisplayList = [];
  61. var layers = this._layers;
  62. if (!singleCanvas) {
  63. this._width = getSize(root, 0, opts);
  64. this._height = getSize(root, 1, opts);
  65. var domRoot = this._domRoot = createRoot(this._width, this._height);
  66. root.appendChild(domRoot);
  67. }
  68. else {
  69. var rootCanvas = root;
  70. var width = rootCanvas.width;
  71. var height = rootCanvas.height;
  72. if (opts.width != null) {
  73. width = opts.width;
  74. }
  75. if (opts.height != null) {
  76. height = opts.height;
  77. }
  78. this.dpr = opts.devicePixelRatio || 1;
  79. rootCanvas.width = width * this.dpr;
  80. rootCanvas.height = height * this.dpr;
  81. this._width = width;
  82. this._height = height;
  83. var mainLayer = new Layer(rootCanvas, this, this.dpr);
  84. mainLayer.__builtin__ = true;
  85. mainLayer.initContext();
  86. layers[CANVAS_ZLEVEL] = mainLayer;
  87. mainLayer.zlevel = CANVAS_ZLEVEL;
  88. zlevelList.push(CANVAS_ZLEVEL);
  89. this._domRoot = root;
  90. }
  91. }
  92. CanvasPainter.prototype.getType = function () {
  93. return 'canvas';
  94. };
  95. CanvasPainter.prototype.isSingleCanvas = function () {
  96. return this._singleCanvas;
  97. };
  98. CanvasPainter.prototype.getViewportRoot = function () {
  99. return this._domRoot;
  100. };
  101. CanvasPainter.prototype.getViewportRootOffset = function () {
  102. var viewportRoot = this.getViewportRoot();
  103. if (viewportRoot) {
  104. return {
  105. offsetLeft: viewportRoot.offsetLeft || 0,
  106. offsetTop: viewportRoot.offsetTop || 0
  107. };
  108. }
  109. };
  110. CanvasPainter.prototype.refresh = function (paintAll) {
  111. var list = this.storage.getDisplayList(true);
  112. var prevList = this._prevDisplayList;
  113. var zlevelList = this._zlevelList;
  114. this._redrawId = Math.random();
  115. this._paintList(list, prevList, paintAll, this._redrawId);
  116. for (var i = 0; i < zlevelList.length; i++) {
  117. var z = zlevelList[i];
  118. var layer = this._layers[z];
  119. if (!layer.__builtin__ && layer.refresh) {
  120. var clearColor = i === 0 ? this._backgroundColor : null;
  121. layer.refresh(clearColor);
  122. }
  123. }
  124. if (this._opts.useDirtyRect) {
  125. this._prevDisplayList = list.slice();
  126. }
  127. return this;
  128. };
  129. CanvasPainter.prototype.refreshHover = function () {
  130. this._paintHoverList(this.storage.getDisplayList(false));
  131. };
  132. CanvasPainter.prototype._paintHoverList = function (list) {
  133. var len = list.length;
  134. var hoverLayer = this._hoverlayer;
  135. hoverLayer && hoverLayer.clear();
  136. if (!len) {
  137. return;
  138. }
  139. var scope = {
  140. inHover: true,
  141. viewWidth: this._width,
  142. viewHeight: this._height
  143. };
  144. var ctx;
  145. for (var i = 0; i < len; i++) {
  146. var el = list[i];
  147. if (el.__inHover) {
  148. if (!hoverLayer) {
  149. hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
  150. }
  151. if (!ctx) {
  152. ctx = hoverLayer.ctx;
  153. ctx.save();
  154. }
  155. brush(ctx, el, scope, i === len - 1);
  156. }
  157. }
  158. if (ctx) {
  159. ctx.restore();
  160. }
  161. };
  162. CanvasPainter.prototype.getHoverLayer = function () {
  163. return this.getLayer(HOVER_LAYER_ZLEVEL);
  164. };
  165. CanvasPainter.prototype.paintOne = function (ctx, el) {
  166. brushSingle(ctx, el);
  167. };
  168. CanvasPainter.prototype._paintList = function (list, prevList, paintAll, redrawId) {
  169. if (this._redrawId !== redrawId) {
  170. return;
  171. }
  172. paintAll = paintAll || false;
  173. this._updateLayerStatus(list);
  174. var _a = this._doPaintList(list, prevList, paintAll), finished = _a.finished, needsRefreshHover = _a.needsRefreshHover;
  175. if (this._needsManuallyCompositing) {
  176. this._compositeManually();
  177. }
  178. if (needsRefreshHover) {
  179. this._paintHoverList(list);
  180. }
  181. if (!finished) {
  182. var self_1 = this;
  183. requestAnimationFrame(function () {
  184. self_1._paintList(list, prevList, paintAll, redrawId);
  185. });
  186. }
  187. else {
  188. this.eachLayer(function (layer) {
  189. layer.afterBrush && layer.afterBrush();
  190. });
  191. }
  192. };
  193. CanvasPainter.prototype._compositeManually = function () {
  194. var ctx = this.getLayer(CANVAS_ZLEVEL).ctx;
  195. var width = this._domRoot.width;
  196. var height = this._domRoot.height;
  197. ctx.clearRect(0, 0, width, height);
  198. this.eachBuiltinLayer(function (layer) {
  199. if (layer.virtual) {
  200. ctx.drawImage(layer.dom, 0, 0, width, height);
  201. }
  202. });
  203. };
  204. CanvasPainter.prototype._doPaintList = function (list, prevList, paintAll) {
  205. var _this = this;
  206. var layerList = [];
  207. var useDirtyRect = this._opts.useDirtyRect;
  208. for (var zi = 0; zi < this._zlevelList.length; zi++) {
  209. var zlevel = this._zlevelList[zi];
  210. var layer = this._layers[zlevel];
  211. if (layer.__builtin__
  212. && layer !== this._hoverlayer
  213. && (layer.__dirty || paintAll)) {
  214. layerList.push(layer);
  215. }
  216. }
  217. var finished = true;
  218. var needsRefreshHover = false;
  219. var _loop_1 = function (k) {
  220. var layer = layerList[k];
  221. var ctx = layer.ctx;
  222. var repaintRects = useDirtyRect
  223. && layer.createRepaintRects(list, prevList, this_1._width, this_1._height);
  224. var start = paintAll ? layer.__startIndex : layer.__drawIndex;
  225. var useTimer = !paintAll && layer.incremental && Date.now;
  226. var startTime = useTimer && Date.now();
  227. var clearColor = layer.zlevel === this_1._zlevelList[0]
  228. ? this_1._backgroundColor : null;
  229. if (layer.__startIndex === layer.__endIndex) {
  230. layer.clear(false, clearColor, repaintRects);
  231. }
  232. else if (start === layer.__startIndex) {
  233. var firstEl = list[start];
  234. if (!firstEl.incremental || !firstEl.notClear || paintAll) {
  235. layer.clear(false, clearColor, repaintRects);
  236. }
  237. }
  238. if (start === -1) {
  239. console.error('For some unknown reason. drawIndex is -1');
  240. start = layer.__startIndex;
  241. }
  242. var i;
  243. var repaint = function (repaintRect) {
  244. var scope = {
  245. inHover: false,
  246. allClipped: false,
  247. prevEl: null,
  248. viewWidth: _this._width,
  249. viewHeight: _this._height
  250. };
  251. for (i = start; i < layer.__endIndex; i++) {
  252. var el = list[i];
  253. if (el.__inHover) {
  254. needsRefreshHover = true;
  255. }
  256. _this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1);
  257. if (useTimer) {
  258. var dTime = Date.now() - startTime;
  259. if (dTime > 15) {
  260. break;
  261. }
  262. }
  263. }
  264. if (scope.prevElClipPaths) {
  265. ctx.restore();
  266. }
  267. };
  268. if (repaintRects) {
  269. if (repaintRects.length === 0) {
  270. i = layer.__endIndex;
  271. }
  272. else {
  273. var dpr = this_1.dpr;
  274. for (var r = 0; r < repaintRects.length; ++r) {
  275. var rect = repaintRects[r];
  276. ctx.save();
  277. ctx.beginPath();
  278. ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
  279. ctx.clip();
  280. repaint(rect);
  281. ctx.restore();
  282. }
  283. }
  284. }
  285. else {
  286. ctx.save();
  287. repaint();
  288. ctx.restore();
  289. }
  290. layer.__drawIndex = i;
  291. if (layer.__drawIndex < layer.__endIndex) {
  292. finished = false;
  293. }
  294. };
  295. var this_1 = this;
  296. for (var k = 0; k < layerList.length; k++) {
  297. _loop_1(k);
  298. }
  299. if (env.wxa) {
  300. util.each(this._layers, function (layer) {
  301. if (layer && layer.ctx && layer.ctx.draw) {
  302. layer.ctx.draw();
  303. }
  304. });
  305. }
  306. return {
  307. finished: finished,
  308. needsRefreshHover: needsRefreshHover
  309. };
  310. };
  311. CanvasPainter.prototype._doPaintEl = function (el, currentLayer, useDirtyRect, repaintRect, scope, isLast) {
  312. var ctx = currentLayer.ctx;
  313. if (useDirtyRect) {
  314. var paintRect = el.getPaintRect();
  315. if (!repaintRect || paintRect && paintRect.intersect(repaintRect)) {
  316. brush(ctx, el, scope, isLast);
  317. el.setPrevPaintRect(paintRect);
  318. }
  319. }
  320. else {
  321. brush(ctx, el, scope, isLast);
  322. }
  323. };
  324. CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
  325. if (this._singleCanvas && !this._needsManuallyCompositing) {
  326. zlevel = CANVAS_ZLEVEL;
  327. }
  328. var layer = this._layers[zlevel];
  329. if (!layer) {
  330. layer = new Layer('zr_' + zlevel, this, this.dpr);
  331. layer.zlevel = zlevel;
  332. layer.__builtin__ = true;
  333. if (this._layerConfig[zlevel]) {
  334. util.merge(layer, this._layerConfig[zlevel], true);
  335. }
  336. else if (this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC]) {
  337. util.merge(layer, this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC], true);
  338. }
  339. if (virtual) {
  340. layer.virtual = virtual;
  341. }
  342. this.insertLayer(zlevel, layer);
  343. layer.initContext();
  344. }
  345. return layer;
  346. };
  347. CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
  348. var layersMap = this._layers;
  349. var zlevelList = this._zlevelList;
  350. var len = zlevelList.length;
  351. var domRoot = this._domRoot;
  352. var prevLayer = null;
  353. var i = -1;
  354. if (layersMap[zlevel]) {
  355. if (process.env.NODE_ENV !== 'production') {
  356. util.logError('ZLevel ' + zlevel + ' has been used already');
  357. }
  358. return;
  359. }
  360. if (!isLayerValid(layer)) {
  361. if (process.env.NODE_ENV !== 'production') {
  362. util.logError('Layer of zlevel ' + zlevel + ' is not valid');
  363. }
  364. return;
  365. }
  366. if (len > 0 && zlevel > zlevelList[0]) {
  367. for (i = 0; i < len - 1; i++) {
  368. if (zlevelList[i] < zlevel
  369. && zlevelList[i + 1] > zlevel) {
  370. break;
  371. }
  372. }
  373. prevLayer = layersMap[zlevelList[i]];
  374. }
  375. zlevelList.splice(i + 1, 0, zlevel);
  376. layersMap[zlevel] = layer;
  377. if (!layer.virtual) {
  378. if (prevLayer) {
  379. var prevDom = prevLayer.dom;
  380. if (prevDom.nextSibling) {
  381. domRoot.insertBefore(layer.dom, prevDom.nextSibling);
  382. }
  383. else {
  384. domRoot.appendChild(layer.dom);
  385. }
  386. }
  387. else {
  388. if (domRoot.firstChild) {
  389. domRoot.insertBefore(layer.dom, domRoot.firstChild);
  390. }
  391. else {
  392. domRoot.appendChild(layer.dom);
  393. }
  394. }
  395. }
  396. layer.__painter = this;
  397. };
  398. CanvasPainter.prototype.eachLayer = function (cb, context) {
  399. var zlevelList = this._zlevelList;
  400. for (var i = 0; i < zlevelList.length; i++) {
  401. var z = zlevelList[i];
  402. cb.call(context, this._layers[z], z);
  403. }
  404. };
  405. CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
  406. var zlevelList = this._zlevelList;
  407. for (var i = 0; i < zlevelList.length; i++) {
  408. var z = zlevelList[i];
  409. var layer = this._layers[z];
  410. if (layer.__builtin__) {
  411. cb.call(context, layer, z);
  412. }
  413. }
  414. };
  415. CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
  416. var zlevelList = this._zlevelList;
  417. for (var i = 0; i < zlevelList.length; i++) {
  418. var z = zlevelList[i];
  419. var layer = this._layers[z];
  420. if (!layer.__builtin__) {
  421. cb.call(context, layer, z);
  422. }
  423. }
  424. };
  425. CanvasPainter.prototype.getLayers = function () {
  426. return this._layers;
  427. };
  428. CanvasPainter.prototype._updateLayerStatus = function (list) {
  429. this.eachBuiltinLayer(function (layer, z) {
  430. layer.__dirty = layer.__used = false;
  431. });
  432. function updatePrevLayer(idx) {
  433. if (prevLayer) {
  434. if (prevLayer.__endIndex !== idx) {
  435. prevLayer.__dirty = true;
  436. }
  437. prevLayer.__endIndex = idx;
  438. }
  439. }
  440. if (this._singleCanvas) {
  441. for (var i_1 = 1; i_1 < list.length; i_1++) {
  442. var el = list[i_1];
  443. if (el.zlevel !== list[i_1 - 1].zlevel || el.incremental) {
  444. this._needsManuallyCompositing = true;
  445. break;
  446. }
  447. }
  448. }
  449. var prevLayer = null;
  450. var incrementalLayerCount = 0;
  451. var prevZlevel;
  452. var i;
  453. for (i = 0; i < list.length; i++) {
  454. var el = list[i];
  455. var zlevel = el.zlevel;
  456. var layer = void 0;
  457. if (prevZlevel !== zlevel) {
  458. prevZlevel = zlevel;
  459. incrementalLayerCount = 0;
  460. }
  461. if (el.incremental) {
  462. layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing);
  463. layer.incremental = true;
  464. incrementalLayerCount = 1;
  465. }
  466. else {
  467. layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing);
  468. }
  469. if (!layer.__builtin__) {
  470. util.logError('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id);
  471. }
  472. if (layer !== prevLayer) {
  473. layer.__used = true;
  474. if (layer.__startIndex !== i) {
  475. layer.__dirty = true;
  476. }
  477. layer.__startIndex = i;
  478. if (!layer.incremental) {
  479. layer.__drawIndex = i;
  480. }
  481. else {
  482. layer.__drawIndex = -1;
  483. }
  484. updatePrevLayer(i);
  485. prevLayer = layer;
  486. }
  487. if ((el.__dirty & REDRAW_BIT) && !el.__inHover) {
  488. layer.__dirty = true;
  489. if (layer.incremental && layer.__drawIndex < 0) {
  490. layer.__drawIndex = i;
  491. }
  492. }
  493. }
  494. updatePrevLayer(i);
  495. this.eachBuiltinLayer(function (layer, z) {
  496. if (!layer.__used && layer.getElementCount() > 0) {
  497. layer.__dirty = true;
  498. layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
  499. }
  500. if (layer.__dirty && layer.__drawIndex < 0) {
  501. layer.__drawIndex = layer.__startIndex;
  502. }
  503. });
  504. };
  505. CanvasPainter.prototype.clear = function () {
  506. this.eachBuiltinLayer(this._clearLayer);
  507. return this;
  508. };
  509. CanvasPainter.prototype._clearLayer = function (layer) {
  510. layer.clear();
  511. };
  512. CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
  513. this._backgroundColor = backgroundColor;
  514. util.each(this._layers, function (layer) {
  515. layer.setUnpainted();
  516. });
  517. };
  518. CanvasPainter.prototype.configLayer = function (zlevel, config) {
  519. if (config) {
  520. var layerConfig = this._layerConfig;
  521. if (!layerConfig[zlevel]) {
  522. layerConfig[zlevel] = config;
  523. }
  524. else {
  525. util.merge(layerConfig[zlevel], config, true);
  526. }
  527. for (var i = 0; i < this._zlevelList.length; i++) {
  528. var _zlevel = this._zlevelList[i];
  529. if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
  530. var layer = this._layers[_zlevel];
  531. util.merge(layer, layerConfig[zlevel], true);
  532. }
  533. }
  534. }
  535. };
  536. CanvasPainter.prototype.delLayer = function (zlevel) {
  537. var layers = this._layers;
  538. var zlevelList = this._zlevelList;
  539. var layer = layers[zlevel];
  540. if (!layer) {
  541. return;
  542. }
  543. layer.dom.parentNode.removeChild(layer.dom);
  544. delete layers[zlevel];
  545. zlevelList.splice(util.indexOf(zlevelList, zlevel), 1);
  546. };
  547. CanvasPainter.prototype.resize = function (width, height) {
  548. if (!this._domRoot.style) {
  549. if (width == null || height == null) {
  550. return;
  551. }
  552. this._width = width;
  553. this._height = height;
  554. this.getLayer(CANVAS_ZLEVEL).resize(width, height);
  555. }
  556. else {
  557. var domRoot = this._domRoot;
  558. domRoot.style.display = 'none';
  559. var opts = this._opts;
  560. var root = this.root;
  561. width != null && (opts.width = width);
  562. height != null && (opts.height = height);
  563. width = getSize(root, 0, opts);
  564. height = getSize(root, 1, opts);
  565. domRoot.style.display = '';
  566. if (this._width !== width || height !== this._height) {
  567. domRoot.style.width = width + 'px';
  568. domRoot.style.height = height + 'px';
  569. for (var id in this._layers) {
  570. if (this._layers.hasOwnProperty(id)) {
  571. this._layers[id].resize(width, height);
  572. }
  573. }
  574. this.refresh(true);
  575. }
  576. this._width = width;
  577. this._height = height;
  578. }
  579. return this;
  580. };
  581. CanvasPainter.prototype.clearLayer = function (zlevel) {
  582. var layer = this._layers[zlevel];
  583. if (layer) {
  584. layer.clear();
  585. }
  586. };
  587. CanvasPainter.prototype.dispose = function () {
  588. this.root.innerHTML = '';
  589. this.root =
  590. this.storage =
  591. this._domRoot =
  592. this._layers = null;
  593. };
  594. CanvasPainter.prototype.getRenderedCanvas = function (opts) {
  595. opts = opts || {};
  596. if (this._singleCanvas && !this._compositeManually) {
  597. return this._layers[CANVAS_ZLEVEL].dom;
  598. }
  599. var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
  600. imageLayer.initContext();
  601. imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
  602. var ctx = imageLayer.ctx;
  603. if (opts.pixelRatio <= this.dpr) {
  604. this.refresh();
  605. var width_1 = imageLayer.dom.width;
  606. var height_1 = imageLayer.dom.height;
  607. this.eachLayer(function (layer) {
  608. if (layer.__builtin__) {
  609. ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
  610. }
  611. else if (layer.renderToCanvas) {
  612. ctx.save();
  613. layer.renderToCanvas(ctx);
  614. ctx.restore();
  615. }
  616. });
  617. }
  618. else {
  619. var scope = {
  620. inHover: false,
  621. viewWidth: this._width,
  622. viewHeight: this._height
  623. };
  624. var displayList = this.storage.getDisplayList(true);
  625. for (var i = 0, len = displayList.length; i < len; i++) {
  626. var el = displayList[i];
  627. brush(ctx, el, scope, i === len - 1);
  628. }
  629. }
  630. return imageLayer.dom;
  631. };
  632. CanvasPainter.prototype.getWidth = function () {
  633. return this._width;
  634. };
  635. CanvasPainter.prototype.getHeight = function () {
  636. return this._height;
  637. };
  638. return CanvasPainter;
  639. }());
  640. export default CanvasPainter;
  641. ;