Painter.js 25 KB

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