Painter.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. import { devicePixelRatio } from '../config.js';
  2. import * as util from '../core/util.js';
  3. import Layer, { isIncrementalLayer } from './Layer.js';
  4. import requestAnimationFrame from '../animation/requestAnimationFrame.js';
  5. import env from '../core/env.js';
  6. import { ZLEVEL2_INCREMENTAL, ZLEVEL2_NORMAL_ABOVE, ZLEVEL2_NORMAL_BELOW } from '../core/types.js';
  7. import { brush, brushLoopFinalize, brushSingle } from './graphic.js';
  8. import { REDRAW_BIT } from '../graphic/constants.js';
  9. import { getSize } from './helper.js';
  10. import { platformApi } from '../core/platform.js';
  11. var HOVER_LAYER_ZLEVEL = 1e5;
  12. var CANVAS_ZLEVEL = 314159;
  13. var HOVER_LAYER_DIRTY_NO = undefined;
  14. var HOVER_LAYER_DIRTY_REPAINT_IF_EXISTING = 1;
  15. var HOVER_LAYER_DIRTY_REPAINT = 2;
  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. function createBuiltinLayer(id, painter, zlevel, zlevel2) {
  42. var layer = new Layer(id, painter, painter.dpr);
  43. layer.zlevel = zlevel;
  44. layer.zlevel2 = zlevel2;
  45. layer.__builtin__ = true;
  46. resetLayerDrawCursors(layer);
  47. return layer;
  48. }
  49. function resetLayerDrawCursors(layer) {
  50. layer.__cursorStack = [];
  51. layer.__cursors = util.createHashMap();
  52. }
  53. function resetLayerDrawCursor(cursor) {
  54. cursor.startIdx = cursor.drawIdx = cursor.endIdx = cursor.endIdxNew = 0;
  55. cursor.used = false;
  56. cursor.first = cursor.last = NaN;
  57. cursor.notClearIdx = -1;
  58. return cursor;
  59. }
  60. function ensureLayerDrawCursor(layer, incrementalCompat) {
  61. var cursors = layer.__cursors;
  62. var incremental = +incrementalCompat;
  63. return cursors.get(incremental)
  64. || (layer.__cursorStack.push(incremental),
  65. cursors.set(incremental, resetLayerDrawCursor({ key: incremental })));
  66. }
  67. function eachCursorInLayer(layer, cb) {
  68. var cursorStack = layer.__cursorStack;
  69. for (var i = 0; i < cursorStack.length; i++) {
  70. cb(layer.__cursors.get(cursorStack[i]));
  71. }
  72. }
  73. function ensureLayerListInZLevel(internal, zlevel) {
  74. var layers = internal.layers;
  75. return layers[zlevel] || (layers[zlevel] = new Array(3));
  76. }
  77. function eachLayer(internal, cb, filter) {
  78. var layerStack = internal.layerStack;
  79. for (var i = 0; i < layerStack.length; i++) {
  80. var zlevel = layerStack[i].zl;
  81. var zlevel2 = layerStack[i].zl2;
  82. var layer = internal.layers[zlevel][zlevel2];
  83. if (!filter || ((!(filter & EACH_LAYER_BUILTIN) || layer.__builtin__)
  84. && (!(filter & EACH_LAYER_NOT_BUILTIN) || !layer.__builtin__)
  85. && (!(filter & EACH_LAYER_NOT_HOVER) || layer !== internal.hoverlayer))) {
  86. cb(layer, zlevel, zlevel2, i);
  87. }
  88. }
  89. }
  90. var EACH_LAYER_BUILTIN = 1;
  91. var EACH_LAYER_NOT_BUILTIN = 2;
  92. var EACH_LAYER_NOT_HOVER = 4;
  93. var EACH_LAYER_BUILTIN_NOT_HOVER = EACH_LAYER_BUILTIN | EACH_LAYER_NOT_HOVER;
  94. var CanvasPainter = (function () {
  95. function CanvasPainter(root, storage, opts, id) {
  96. this.type = 'canvas';
  97. this._prevDisplayList = [];
  98. this._layerConfig = {};
  99. this._needsManuallyCompositing = false;
  100. this.type = 'canvas';
  101. this._i = {
  102. layerStack: [],
  103. layers: []
  104. };
  105. var singleCanvas = !root.nodeName
  106. || root.nodeName.toUpperCase() === 'CANVAS';
  107. this._opts = opts = util.extend({}, opts || {});
  108. this.dpr = opts.devicePixelRatio || devicePixelRatio;
  109. this._singleCanvas = singleCanvas;
  110. this.root = root;
  111. var rootStyle = root.style;
  112. if (rootStyle) {
  113. util.disableUserSelect(root);
  114. root.innerHTML = '';
  115. }
  116. this.storage = storage;
  117. this._prevDisplayList = [];
  118. if (!singleCanvas) {
  119. this._width = getSize(root, 0, opts);
  120. this._height = getSize(root, 1, opts);
  121. var domRoot = this._domRoot = createRoot(this._width, this._height);
  122. root.appendChild(domRoot);
  123. }
  124. else {
  125. var rootCanvas = root;
  126. var width = rootCanvas.width;
  127. var height = rootCanvas.height;
  128. if (opts.width != null) {
  129. width = opts.width;
  130. }
  131. if (opts.height != null) {
  132. height = opts.height;
  133. }
  134. this.dpr = opts.devicePixelRatio || 1;
  135. rootCanvas.width = width * this.dpr;
  136. rootCanvas.height = height * this.dpr;
  137. this._width = width;
  138. this._height = height;
  139. var singleLayer = createBuiltinLayer(rootCanvas, this, CANVAS_ZLEVEL, ZLEVEL2_NORMAL_BELOW);
  140. singleLayer.initContext();
  141. this._insertLayer(singleLayer, CANVAS_ZLEVEL, ZLEVEL2_NORMAL_BELOW, true);
  142. this._domRoot = root;
  143. }
  144. }
  145. CanvasPainter.prototype.getType = function () {
  146. return 'canvas';
  147. };
  148. CanvasPainter.prototype.isSingleCanvas = function () {
  149. return this._singleCanvas;
  150. };
  151. CanvasPainter.prototype.getViewportRoot = function () {
  152. return this._domRoot;
  153. };
  154. CanvasPainter.prototype.getViewportRootOffset = function () {
  155. var viewportRoot = this.getViewportRoot();
  156. if (viewportRoot) {
  157. return {
  158. offsetLeft: viewportRoot.offsetLeft || 0,
  159. offsetTop: viewportRoot.offsetTop || 0
  160. };
  161. }
  162. };
  163. CanvasPainter.prototype.refresh = function (optOrPaintAll) {
  164. var opt;
  165. if (optOrPaintAll && !util.isObject(optOrPaintAll)) {
  166. opt = { paintAll: !!optOrPaintAll };
  167. }
  168. else {
  169. opt = optOrPaintAll || {};
  170. }
  171. var refresh = util.retrieve2(opt.refresh, true);
  172. var refreshHover = util.retrieve2(opt.refreshHover, false);
  173. if (refreshHover) {
  174. this._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT;
  175. }
  176. if (!refresh) {
  177. if (refreshHover) {
  178. this._paintHoverList(this.storage.getDisplayList(false));
  179. }
  180. return this;
  181. }
  182. var list = this.storage.getDisplayList(true);
  183. this._updateLayerStatus(list, opt.paintAll);
  184. this._redrawId = Math.random();
  185. var prevList = this._prevDisplayList;
  186. this._paintList(list, prevList, this._redrawId);
  187. var bgColor = this._backgroundColor;
  188. eachLayer(this._i, function (layer, zlevel, zlevel2, idx) {
  189. if (layer.refresh) {
  190. layer.refresh(idx === 0 ? bgColor : null);
  191. }
  192. }, EACH_LAYER_NOT_BUILTIN);
  193. if (this._opts.useDirtyRect) {
  194. this._prevDisplayList = list.slice();
  195. }
  196. return this;
  197. };
  198. CanvasPainter.prototype._paintHoverList = function (list) {
  199. var hoverLayer = this._i.hoverlayer;
  200. var hoverLayerDirty = this._hoverLayerDirty;
  201. this._hoverLayerDirty = HOVER_LAYER_DIRTY_NO;
  202. if (hoverLayerDirty === HOVER_LAYER_DIRTY_NO) {
  203. return;
  204. }
  205. if (!hoverLayer && hoverLayerDirty === HOVER_LAYER_DIRTY_REPAINT) {
  206. hoverLayer = this._i.hoverlayer = this._ensureLayer(HOVER_LAYER_ZLEVEL);
  207. }
  208. if (!hoverLayer) {
  209. return;
  210. }
  211. hoverLayer.clear();
  212. var scope = {
  213. inHover: true,
  214. viewWidth: this._width,
  215. viewHeight: this._height,
  216. beforeBrushParam: {}
  217. };
  218. var ctx;
  219. for (var i = 0, len = list.length; i < len; i++) {
  220. var el = list[i];
  221. if (!el.__inHover) {
  222. continue;
  223. }
  224. if (!ctx) {
  225. ctx = hoverLayer.ctx;
  226. ctx.save();
  227. }
  228. var hoverStyle = el.__hoverStyle;
  229. var originalStyle = void 0;
  230. if (hoverStyle) {
  231. originalStyle = el.style;
  232. el.style = hoverStyle;
  233. }
  234. brush(ctx, el, scope);
  235. if (hoverStyle) {
  236. el.style = originalStyle;
  237. }
  238. }
  239. if (ctx) {
  240. brushLoopFinalize(ctx, scope);
  241. ctx.restore();
  242. }
  243. };
  244. CanvasPainter.prototype.getHoverLayer = function () {
  245. return this._ensureLayer(HOVER_LAYER_ZLEVEL);
  246. };
  247. CanvasPainter.prototype.paintOne = function (ctx, el) {
  248. brushSingle(ctx, el);
  249. };
  250. CanvasPainter.prototype._paintList = function (list, prevList, redrawId) {
  251. if (this._redrawId !== redrawId) {
  252. return;
  253. }
  254. var finished = this._doPaintList(list, prevList);
  255. if (this._needsManuallyCompositing) {
  256. this._compositeManually();
  257. }
  258. if (!finished) {
  259. var self_1 = this;
  260. requestAnimationFrame(function () {
  261. self_1._paintList(list, prevList, redrawId);
  262. });
  263. }
  264. else {
  265. eachLayer(this._i, function (layer) {
  266. layer.afterBrush && layer.afterBrush();
  267. }, EACH_LAYER_BUILTIN_NOT_HOVER);
  268. this._paintHoverList(list);
  269. }
  270. };
  271. CanvasPainter.prototype._compositeManually = function () {
  272. var ctx = this._ensureLayer(CANVAS_ZLEVEL).ctx;
  273. var width = this._domRoot.width;
  274. var height = this._domRoot.height;
  275. ctx.clearRect(0, 0, width, height);
  276. eachLayer(this._i, function (layer) {
  277. if (layer.virtual) {
  278. ctx.drawImage(layer.dom, 0, 0, width, height);
  279. }
  280. }, EACH_LAYER_BUILTIN);
  281. };
  282. CanvasPainter.prototype._doPaintList = function (list, prevList) {
  283. var painter = this;
  284. var finished = true;
  285. eachLayer(this._i, function (layer) {
  286. var needDraw = false;
  287. eachCursorInLayer(layer, function (cursor) {
  288. if (cursor.drawIdx < cursor.endIdx
  289. || cursor.notClearIdx >= 0) {
  290. needDraw = true;
  291. }
  292. });
  293. if (!needDraw && !layer.__dirty) {
  294. return;
  295. }
  296. var repaintRects = (painter._opts.useDirtyRect && !isIncrementalLayer(layer))
  297. ? layer.createRepaintRects(list, prevList, painter._width, painter._height) : null;
  298. var firstLayerKey = painter._i.layerStack[0];
  299. var contentRetained = true;
  300. if (layer.__dirty) {
  301. contentRetained = false;
  302. layer.__dirty = false;
  303. var clearColor = (layer.zlevel === firstLayerKey.zl && layer.zlevel2 === firstLayerKey.zl2)
  304. ? painter._backgroundColor : null;
  305. layer.clear(false, clearColor, repaintRects);
  306. }
  307. eachCursorInLayer(layer, function (cursor) {
  308. var cursorFinished = painter._paintPerCursor(layer, cursor, list, repaintRects, contentRetained);
  309. finished = finished && cursorFinished;
  310. });
  311. }, EACH_LAYER_BUILTIN_NOT_HOVER);
  312. if (env.wxa) {
  313. eachLayer(this._i, function (layer) {
  314. if (layer && layer.ctx && layer.ctx.draw) {
  315. layer.ctx.draw();
  316. }
  317. });
  318. }
  319. return finished;
  320. };
  321. CanvasPainter.prototype._paintPerCursor = function (layer, layerCursor, list, repaintRects, contentRetained) {
  322. var ctx = layer.ctx;
  323. if (repaintRects) {
  324. if (!repaintRects.length) {
  325. layerCursor.drawIdx = layerCursor.endIdx;
  326. }
  327. else {
  328. var dpr = this.dpr;
  329. for (var r = 0; r < repaintRects.length; ++r) {
  330. var rect = repaintRects[r];
  331. ctx.save();
  332. ctx.beginPath();
  333. ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
  334. ctx.clip();
  335. this._paintPerCursorInRect(layer, layerCursor, list, rect, contentRetained);
  336. ctx.restore();
  337. }
  338. }
  339. }
  340. else {
  341. ctx.save();
  342. this._paintPerCursorInRect(layer, layerCursor, list, null, contentRetained);
  343. ctx.restore();
  344. }
  345. return layerCursor.drawIdx >= layerCursor.endIdx;
  346. };
  347. CanvasPainter.prototype._paintPerCursorInRect = function (layer, layerCursor, list, repaintRect, contentRetained) {
  348. var scope = {
  349. inHover: false,
  350. allClipped: false,
  351. prevEl: null,
  352. viewWidth: this._width,
  353. viewHeight: this._height,
  354. beforeBrushParam: { contentRetained: contentRetained }
  355. };
  356. var ctx = layer.ctx;
  357. var useTimer = isIncrementalLayer(layer);
  358. var startTime = useTimer && platformApi.getTime();
  359. var drawIdxBegin = layerCursor.drawIdx;
  360. var notClearIdx = layerCursor.notClearIdx;
  361. var idx = notClearIdx >= 0 ? Math.min(notClearIdx, drawIdxBegin) : drawIdxBegin;
  362. for (; idx < layerCursor.endIdx; idx++) {
  363. var el = list[idx];
  364. if (idx < drawIdxBegin && !el.notClear) {
  365. continue;
  366. }
  367. if (el.__inHover) {
  368. this._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT;
  369. }
  370. if (repaintRect != null) {
  371. var paintRect = el.getPaintRect();
  372. if (paintRect && paintRect.intersect(repaintRect)) {
  373. brush(ctx, el, scope);
  374. el.setPrevPaintRect(paintRect);
  375. }
  376. }
  377. else {
  378. brush(ctx, el, scope);
  379. }
  380. if (useTimer) {
  381. var dTime = platformApi.getTime() - startTime;
  382. if (dTime > 15) {
  383. idx++;
  384. break;
  385. }
  386. }
  387. }
  388. brushLoopFinalize(ctx, scope);
  389. layerCursor.drawIdx = Math.max(idx, drawIdxBegin);
  390. };
  391. CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
  392. return this._ensureLayer(zlevel, 0, virtual);
  393. };
  394. CanvasPainter.prototype._ensureLayer = function (zlevel, zlevel2, virtual) {
  395. zlevel2 = zlevel2 || 0;
  396. var singleCanvas = this._singleCanvas;
  397. if (singleCanvas && !this._needsManuallyCompositing) {
  398. zlevel = CANVAS_ZLEVEL;
  399. zlevel2 = 0;
  400. }
  401. var layer = ensureLayerListInZLevel(this._i, zlevel)[zlevel2];
  402. if (!layer) {
  403. layer = createBuiltinLayer('zr_' + zlevel + '.' + zlevel2, this, zlevel, zlevel2);
  404. if (this._layerConfig[zlevel]) {
  405. util.merge(layer, this._layerConfig[zlevel], true);
  406. }
  407. if (virtual
  408. || (singleCanvas && zlevel !== CANVAS_ZLEVEL)) {
  409. layer.virtual = true;
  410. }
  411. this._insertLayer(layer, zlevel, zlevel2, false);
  412. layer.initContext();
  413. }
  414. return layer;
  415. };
  416. CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
  417. this._insertLayer(layer, zlevel, 0, false);
  418. };
  419. CanvasPainter.prototype._insertLayer = function (layer, zlevel, zlevel2, suppressDOMInsert) {
  420. var internal = this._i;
  421. var layersMap = internal.layers;
  422. var layerStack = internal.layerStack;
  423. var domRoot = this._domRoot;
  424. var prevLayer = null;
  425. if (layersMap[zlevel] && layersMap[zlevel][zlevel2]) {
  426. if (process.env.NODE_ENV !== 'production') {
  427. util.logError('ZLevel ' + zlevel + '.' + zlevel2 + ' has been used already');
  428. }
  429. return;
  430. }
  431. if (!isLayerValid(layer)) {
  432. if (process.env.NODE_ENV !== 'production') {
  433. util.logError('Layer of zlevel ' + zlevel + ' is not valid');
  434. }
  435. return;
  436. }
  437. var len = layerStack.length;
  438. var i = 0;
  439. while (i < len
  440. && (layerStack[i].zl < zlevel
  441. || (layerStack[i].zl === zlevel && layerStack[i].zl2 < zlevel2))) {
  442. i++;
  443. }
  444. if (i > 0) {
  445. prevLayer = ensureLayerListInZLevel(internal, layerStack[i - 1].zl)[layerStack[i - 1].zl2];
  446. }
  447. layerStack.splice(i, 0, { zl: zlevel, zl2: zlevel2 });
  448. ensureLayerListInZLevel(internal, zlevel)[zlevel2] = layer;
  449. if (!suppressDOMInsert && !layer.virtual) {
  450. if (prevLayer) {
  451. var prevDom = prevLayer.dom;
  452. if (prevDom.nextSibling) {
  453. domRoot.insertBefore(layer.dom, prevDom.nextSibling);
  454. }
  455. else {
  456. domRoot.appendChild(layer.dom);
  457. }
  458. }
  459. else {
  460. if (domRoot.firstChild) {
  461. domRoot.insertBefore(layer.dom, domRoot.firstChild);
  462. }
  463. else {
  464. domRoot.appendChild(layer.dom);
  465. }
  466. }
  467. }
  468. layer.painter || (layer.painter = this);
  469. };
  470. CanvasPainter.prototype.eachLayer = function (cb, context) {
  471. return eachLayer(this._i, function (layer, zlevel) {
  472. cb.call(context, layer, zlevel);
  473. });
  474. };
  475. CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
  476. return eachLayer(this._i, function (layer, zlevel) {
  477. cb.call(context, layer, zlevel);
  478. }, EACH_LAYER_BUILTIN);
  479. };
  480. CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
  481. return eachLayer(this._i, function (layer, zlevel) {
  482. cb.call(context, layer, zlevel);
  483. }, EACH_LAYER_NOT_BUILTIN);
  484. };
  485. CanvasPainter.prototype.getLayers = function () {
  486. var layers = {};
  487. eachLayer(this._i, function (layer, zlevel, zlevel2) {
  488. layers[layer.id] = layer;
  489. });
  490. return layers;
  491. };
  492. CanvasPainter.prototype._updateLayerStatus = function (list, paintAll) {
  493. var painter = this;
  494. if (painter._singleCanvas) {
  495. for (var i = 1; i < list.length; i++) {
  496. var el = list[i];
  497. if (el.zlevel !== list[i - 1].zlevel || el.incremental) {
  498. painter._needsManuallyCompositing = true;
  499. break;
  500. }
  501. }
  502. }
  503. eachLayer(painter._i, function (layer) {
  504. layer.__dirty = false;
  505. eachCursorInLayer(layer, function (cursor) {
  506. cursor.used = false;
  507. cursor.endIdxNew = 0;
  508. cursor.notClearIdx = -1;
  509. });
  510. }, EACH_LAYER_BUILTIN_NOT_HOVER);
  511. var prevZLevel;
  512. var currLayer = null;
  513. var currCursor = null;
  514. var aboveIncrementalInCurrZLevel = false;
  515. for (var idx = 0, len = list.length; idx < len; idx++) {
  516. var el = list[idx];
  517. var zlevel = el.zlevel;
  518. var elIncremental = el.incremental;
  519. var zlevel2 = void 0;
  520. if (prevZLevel !== zlevel) {
  521. prevZLevel = zlevel;
  522. aboveIncrementalInCurrZLevel = false;
  523. }
  524. if (elIncremental) {
  525. aboveIncrementalInCurrZLevel = true;
  526. zlevel2 = ZLEVEL2_INCREMENTAL;
  527. }
  528. else {
  529. zlevel2 = aboveIncrementalInCurrZLevel ? ZLEVEL2_NORMAL_ABOVE : ZLEVEL2_NORMAL_BELOW;
  530. }
  531. if (!currLayer || zlevel !== currLayer.zlevel || zlevel2 !== currLayer.zlevel2) {
  532. currLayer = painter._ensureLayer(zlevel, zlevel2);
  533. currCursor = null;
  534. if (!currLayer.__builtin__) {
  535. util.logError('ZLevel ' + zlevel + ' has been used by unknown layer ' + currLayer.id);
  536. continue;
  537. }
  538. }
  539. if (!currCursor || elIncremental !== currCursor.key) {
  540. currCursor = ensureLayerDrawCursor(currLayer, elIncremental);
  541. if (!currCursor.used) {
  542. currCursor.used = true;
  543. if (!paintAll && currCursor.first === el.id) {
  544. var idxShift = idx - currCursor.startIdx;
  545. currCursor.startIdx = idx;
  546. currCursor.drawIdx += idxShift;
  547. currCursor.endIdx += idxShift;
  548. }
  549. else {
  550. currLayer.__dirty = true;
  551. currCursor.first = el.id;
  552. currCursor.startIdx = currCursor.drawIdx = idx;
  553. currCursor.endIdx = idx + 1;
  554. }
  555. }
  556. }
  557. currCursor.endIdxNew = idx + 1;
  558. if ((el.__dirty & REDRAW_BIT)
  559. && !el.__inHover) {
  560. if (!elIncremental
  561. || (!el.notClear && idx < currCursor.drawIdx)) {
  562. currLayer.__dirty = true;
  563. }
  564. if (elIncremental && el.notClear && currCursor.notClearIdx < 0) {
  565. currCursor.notClearIdx = idx;
  566. }
  567. }
  568. }
  569. eachLayer(painter._i, function (layer) {
  570. var cursorStack = layer.__cursorStack;
  571. var cursors = layer.__cursors;
  572. for (var i = cursorStack.length - 1; i >= 0; i--) {
  573. var cursor = cursors.get(cursorStack[i]);
  574. if (!cursor.used) {
  575. layer.__dirty = true;
  576. cursors.removeKey(cursorStack[i]);
  577. cursorStack.splice(i, 1);
  578. }
  579. else {
  580. var endIdxNew = cursor.endIdxNew;
  581. if (isIncrementalLayer(layer)
  582. ? endIdxNew < cursor.drawIdx
  583. : (endIdxNew !== cursor.endIdx
  584. || !endIdxNew
  585. || list[endIdxNew - 1].id !== cursor.last)) {
  586. layer.__dirty = true;
  587. }
  588. cursor.endIdx = cursor.endIdxNew;
  589. cursor.last = endIdxNew ? list[endIdxNew - 1].id : NaN;
  590. }
  591. }
  592. if (layer.__dirty) {
  593. eachCursorInLayer(layer, function (cursor) {
  594. cursor.drawIdx = cursor.startIdx;
  595. });
  596. if (painter._hoverLayerDirty === HOVER_LAYER_DIRTY_NO) {
  597. painter._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT_IF_EXISTING;
  598. }
  599. }
  600. }, EACH_LAYER_BUILTIN_NOT_HOVER);
  601. };
  602. CanvasPainter.prototype.clear = function () {
  603. eachLayer(this._i, function (layer) {
  604. layer.clear();
  605. resetLayerDrawCursors(layer);
  606. }, EACH_LAYER_BUILTIN);
  607. return this;
  608. };
  609. CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
  610. this._backgroundColor = backgroundColor;
  611. eachLayer(this._i, function (layer) {
  612. layer.setUnpainted();
  613. });
  614. };
  615. CanvasPainter.prototype.configLayer = function (zlevel, config) {
  616. if (config) {
  617. var layerConfig_1 = this._layerConfig;
  618. if (!layerConfig_1[zlevel]) {
  619. layerConfig_1[zlevel] = config;
  620. }
  621. else {
  622. util.merge(layerConfig_1[zlevel], config, true);
  623. }
  624. eachLayer(this._i, function (layer, zlevel) {
  625. util.merge(layer, layerConfig_1[zlevel], true);
  626. });
  627. }
  628. };
  629. CanvasPainter.prototype.delLayer = function (zlevel) {
  630. var layerStack = this._i.layerStack;
  631. var layersMap = this._i.layers;
  632. for (var i = layerStack.length - 1; i >= 0; i--) {
  633. var key = layerStack[i];
  634. if (key.zl === zlevel) {
  635. var layer = layersMap[zlevel][key.zl2];
  636. if (layer.__builtin__) {
  637. continue;
  638. }
  639. layerStack.splice(i, 1);
  640. layersMap[zlevel][key.zl2] = undefined;
  641. if (!layer.virtual) {
  642. var parentNode = layer.dom.parentNode;
  643. parentNode && parentNode.removeChild(layer.dom);
  644. }
  645. }
  646. }
  647. };
  648. CanvasPainter.prototype.resize = function (width, height) {
  649. if (!this._domRoot.style) {
  650. if (width == null || height == null) {
  651. return;
  652. }
  653. this._width = width;
  654. this._height = height;
  655. this._ensureLayer(CANVAS_ZLEVEL).resize(width, height);
  656. }
  657. else {
  658. var domRoot = this._domRoot;
  659. domRoot.style.display = 'none';
  660. var opts = this._opts;
  661. var root = this.root;
  662. width != null && (opts.width = width);
  663. height != null && (opts.height = height);
  664. width = getSize(root, 0, opts);
  665. height = getSize(root, 1, opts);
  666. domRoot.style.display = '';
  667. if (this._width !== width || height !== this._height) {
  668. domRoot.style.width = width + 'px';
  669. domRoot.style.height = height + 'px';
  670. eachLayer(this._i, function (layer) {
  671. layer.resize(width, height);
  672. });
  673. this.refresh({ paintAll: true });
  674. }
  675. this._width = width;
  676. this._height = height;
  677. }
  678. return this;
  679. };
  680. CanvasPainter.prototype.clearLayer = function (zlevel) {
  681. util.each(this._i.layers[zlevel], function (layer) {
  682. if (layer && !layer.__builtin__) {
  683. layer.clear();
  684. }
  685. });
  686. };
  687. CanvasPainter.prototype.dispose = function () {
  688. this.root.innerHTML = '';
  689. this.root =
  690. this.storage =
  691. this._domRoot =
  692. this._i = null;
  693. };
  694. CanvasPainter.prototype.getRenderedCanvas = function (opts) {
  695. opts = opts || {};
  696. if (this._singleCanvas && !this._compositeManually) {
  697. return this._i.layers[CANVAS_ZLEVEL][0].dom;
  698. }
  699. var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
  700. imageLayer.initContext();
  701. imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
  702. var ctx = imageLayer.ctx;
  703. if (opts.pixelRatio <= this.dpr) {
  704. this.refresh();
  705. var width_1 = imageLayer.dom.width;
  706. var height_1 = imageLayer.dom.height;
  707. eachLayer(this._i, function (layer) {
  708. if (layer.__builtin__) {
  709. ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
  710. }
  711. else if (layer.renderToCanvas) {
  712. ctx.save();
  713. layer.renderToCanvas(ctx);
  714. ctx.restore();
  715. }
  716. });
  717. }
  718. else {
  719. var scope = {
  720. inHover: false,
  721. viewWidth: this._width,
  722. viewHeight: this._height,
  723. beforeBrushParam: {}
  724. };
  725. var displayList = this.storage.getDisplayList(true);
  726. for (var i = 0, len = displayList.length; i < len; i++) {
  727. var el = displayList[i];
  728. brush(ctx, el, scope);
  729. }
  730. brushLoopFinalize(ctx, scope);
  731. }
  732. return imageLayer.dom;
  733. };
  734. CanvasPainter.prototype.getWidth = function () {
  735. return this._width;
  736. };
  737. CanvasPainter.prototype.getHeight = function () {
  738. return this._height;
  739. };
  740. return CanvasPainter;
  741. }());
  742. export default CanvasPainter;
  743. ;