Painter.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. var logError = require("../core/log");
  2. var vmlCore = require("./core");
  3. var _util = require("../core/util");
  4. var each = _util.each;
  5. /**
  6. * VML Painter.
  7. *
  8. * @module zrender/vml/Painter
  9. */
  10. function parseInt10(val) {
  11. return parseInt(val, 10);
  12. }
  13. /**
  14. * @alias module:zrender/vml/Painter
  15. */
  16. function VMLPainter(root, storage) {
  17. vmlCore.initVML();
  18. this.root = root;
  19. this.storage = storage;
  20. var vmlViewport = document.createElement('div');
  21. var vmlRoot = document.createElement('div');
  22. vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;';
  23. vmlRoot.style.cssText = 'position:absolute;left:0;top:0;';
  24. root.appendChild(vmlViewport);
  25. this._vmlRoot = vmlRoot;
  26. this._vmlViewport = vmlViewport;
  27. this.resize(); // 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. } // Set as already invisible
  78. el.__alreadyNotVisible = true;
  79. } else {
  80. if (el.__alreadyNotVisible) {
  81. el.onAdd(vmlRoot);
  82. }
  83. el.__alreadyNotVisible = false;
  84. if (el.__dirty) {
  85. el.beforeBrush && el.beforeBrush();
  86. (el.brushVML || el.brush).call(el, vmlRoot);
  87. el.afterBrush && el.afterBrush();
  88. }
  89. }
  90. el.__dirty = false;
  91. }
  92. if (this._firstPaint) {
  93. // Detached from document at first time
  94. // to avoid page refreshing too many times
  95. // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变
  96. this._vmlViewport.appendChild(vmlRoot);
  97. this._firstPaint = false;
  98. }
  99. },
  100. resize: function (width, height) {
  101. var width = width == null ? this._getWidth() : width;
  102. var height = height == null ? this._getHeight() : height;
  103. if (this._width !== width || this._height !== height) {
  104. this._width = width;
  105. this._height = height;
  106. var vmlViewportStyle = this._vmlViewport.style;
  107. vmlViewportStyle.width = width + 'px';
  108. vmlViewportStyle.height = height + 'px';
  109. }
  110. },
  111. dispose: function () {
  112. this.root.innerHTML = '';
  113. this._vmlRoot = this._vmlViewport = this.storage = null;
  114. },
  115. getWidth: function () {
  116. return this._width;
  117. },
  118. getHeight: function () {
  119. return this._height;
  120. },
  121. clear: function () {
  122. if (this._vmlViewport) {
  123. this.root.removeChild(this._vmlViewport);
  124. }
  125. },
  126. _getWidth: function () {
  127. var root = this.root;
  128. var stl = root.currentStyle;
  129. return (root.clientWidth || parseInt10(stl.width)) - parseInt10(stl.paddingLeft) - parseInt10(stl.paddingRight) | 0;
  130. },
  131. _getHeight: function () {
  132. var root = this.root;
  133. var stl = root.currentStyle;
  134. return (root.clientHeight || parseInt10(stl.height)) - parseInt10(stl.paddingTop) - parseInt10(stl.paddingBottom) | 0;
  135. }
  136. }; // Not supported methods
  137. function createMethodNotSupport(method) {
  138. return function () {
  139. logError('In IE8.0 VML mode painter not support method "' + method + '"');
  140. };
  141. } // Unsupported methods
  142. each(['getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', 'eachOtherLayer', 'getLayers', 'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'], function (name) {
  143. VMLPainter.prototype[name] = createMethodNotSupport(name);
  144. });
  145. var _default = VMLPainter;
  146. module.exports = _default;