Painter.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /**
  2. * VML Painter.
  3. *
  4. * @module zrender/vml/Painter
  5. */
  6. import logError from '../core/log';
  7. import * as vmlCore from './core';
  8. import {each} from '../core/util';
  9. function parseInt10(val) {
  10. return parseInt(val, 10);
  11. }
  12. /**
  13. * @alias module:zrender/vml/Painter
  14. */
  15. function VMLPainter(root, storage) {
  16. vmlCore.initVML();
  17. this.root = root;
  18. this.storage = storage;
  19. var vmlViewport = document.createElement('div');
  20. var vmlRoot = document.createElement('div');
  21. vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;';
  22. vmlRoot.style.cssText = 'position:absolute;left:0;top:0;';
  23. root.appendChild(vmlViewport);
  24. this._vmlRoot = vmlRoot;
  25. this._vmlViewport = vmlViewport;
  26. this.resize();
  27. // Modify storage
  28. var oldDelFromStorage = storage.delFromStorage;
  29. var oldAddToStorage = storage.addToStorage;
  30. storage.delFromStorage = function (el) {
  31. oldDelFromStorage.call(storage, el);
  32. if (el) {
  33. el.onRemove && el.onRemove(vmlRoot);
  34. }
  35. };
  36. storage.addToStorage = function (el) {
  37. // Displayable already has a vml node
  38. el.onAdd && el.onAdd(vmlRoot);
  39. oldAddToStorage.call(storage, el);
  40. };
  41. this._firstPaint = true;
  42. }
  43. VMLPainter.prototype = {
  44. constructor: VMLPainter,
  45. getType: function () {
  46. return 'vml';
  47. },
  48. /**
  49. * @return {HTMLDivElement}
  50. */
  51. getViewportRoot: function () {
  52. return this._vmlViewport;
  53. },
  54. getViewportRootOffset: function () {
  55. var viewportRoot = this.getViewportRoot();
  56. if (viewportRoot) {
  57. return {
  58. offsetLeft: viewportRoot.offsetLeft || 0,
  59. offsetTop: viewportRoot.offsetTop || 0
  60. };
  61. }
  62. },
  63. /**
  64. * 刷新
  65. */
  66. refresh: function () {
  67. var list = this.storage.getDisplayList(true, true);
  68. this._paintList(list);
  69. },
  70. _paintList: function (list) {
  71. var vmlRoot = this._vmlRoot;
  72. for (var i = 0; i < list.length; i++) {
  73. var el = list[i];
  74. if (el.invisible || el.ignore) {
  75. if (!el.__alreadyNotVisible) {
  76. el.onRemove(vmlRoot);
  77. }
  78. // Set as already invisible
  79. el.__alreadyNotVisible = true;
  80. }
  81. else {
  82. if (el.__alreadyNotVisible) {
  83. el.onAdd(vmlRoot);
  84. }
  85. el.__alreadyNotVisible = false;
  86. if (el.__dirty) {
  87. el.beforeBrush && el.beforeBrush();
  88. (el.brushVML || el.brush).call(el, vmlRoot);
  89. el.afterBrush && el.afterBrush();
  90. }
  91. }
  92. el.__dirty = false;
  93. }
  94. if (this._firstPaint) {
  95. // Detached from document at first time
  96. // to avoid page refreshing too many times
  97. // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变
  98. this._vmlViewport.appendChild(vmlRoot);
  99. this._firstPaint = false;
  100. }
  101. },
  102. resize: function (width, height) {
  103. var width = width == null ? this._getWidth() : width;
  104. var height = height == null ? this._getHeight() : height;
  105. if (this._width !== width || this._height !== height) {
  106. this._width = width;
  107. this._height = height;
  108. var vmlViewportStyle = this._vmlViewport.style;
  109. vmlViewportStyle.width = width + 'px';
  110. vmlViewportStyle.height = height + 'px';
  111. }
  112. },
  113. dispose: function () {
  114. this.root.innerHTML = '';
  115. this._vmlRoot =
  116. this._vmlViewport =
  117. this.storage = null;
  118. },
  119. getWidth: function () {
  120. return this._width;
  121. },
  122. getHeight: function () {
  123. return this._height;
  124. },
  125. clear: function () {
  126. if (this._vmlViewport) {
  127. this.root.removeChild(this._vmlViewport);
  128. }
  129. },
  130. _getWidth: function () {
  131. var root = this.root;
  132. var stl = root.currentStyle;
  133. return ((root.clientWidth || parseInt10(stl.width))
  134. - parseInt10(stl.paddingLeft)
  135. - parseInt10(stl.paddingRight)) | 0;
  136. },
  137. _getHeight: function () {
  138. var root = this.root;
  139. var stl = root.currentStyle;
  140. return ((root.clientHeight || parseInt10(stl.height))
  141. - parseInt10(stl.paddingTop)
  142. - parseInt10(stl.paddingBottom)) | 0;
  143. }
  144. };
  145. // Not supported methods
  146. function createMethodNotSupport(method) {
  147. return function () {
  148. logError('In IE8.0 VML mode painter not support method "' + method + '"');
  149. };
  150. }
  151. // Unsupported methods
  152. each([
  153. 'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', 'eachOtherLayer', 'getLayers',
  154. 'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'
  155. ], function (name) {
  156. VMLPainter.prototype[name] = createMethodNotSupport(name);
  157. });
  158. export default VMLPainter;