RoamController.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. var zrUtil = require("zrender/lib/core/util");
  2. var Eventful = require("zrender/lib/mixin/Eventful");
  3. var eventTool = require("zrender/lib/core/event");
  4. var interactionMutex = require("./interactionMutex");
  5. /**
  6. * @alias module:echarts/component/helper/RoamController
  7. * @constructor
  8. * @mixin {module:zrender/mixin/Eventful}
  9. *
  10. * @param {module:zrender/zrender~ZRender} zr
  11. */
  12. function RoamController(zr) {
  13. /**
  14. * @type {Function}
  15. */
  16. this.pointerChecker;
  17. /**
  18. * @type {module:zrender}
  19. */
  20. this._zr = zr;
  21. /**
  22. * @type {Object}
  23. */
  24. this._opt = {}; // Avoid two roamController bind the same handler
  25. var bind = zrUtil.bind;
  26. var mousedownHandler = bind(mousedown, this);
  27. var mousemoveHandler = bind(mousemove, this);
  28. var mouseupHandler = bind(mouseup, this);
  29. var mousewheelHandler = bind(mousewheel, this);
  30. var pinchHandler = bind(pinch, this);
  31. Eventful.call(this);
  32. /**
  33. * @param {Function} pointerChecker
  34. * input: x, y
  35. * output: boolean
  36. */
  37. this.setPointerChecker = function (pointerChecker) {
  38. this.pointerChecker = pointerChecker;
  39. };
  40. /**
  41. * Notice: only enable needed types. For example, if 'zoom'
  42. * is not needed, 'zoom' should not be enabled, otherwise
  43. * default mousewheel behaviour (scroll page) will be disabled.
  44. *
  45. * @param {boolean|string} [controlType=true] Specify the control type,
  46. * which can be null/undefined or true/false
  47. * or 'pan/move' or 'zoom'/'scale'
  48. * @param {Object} [opt]
  49. * @param {Object} [opt.zoomOnMouseWheel=true]
  50. * @param {Object} [opt.moveOnMouseMove=true]
  51. * @param {Object} [opt.preventDefaultMouseMove=true] When pan.
  52. */
  53. this.enable = function (controlType, opt) {
  54. // Disable previous first
  55. this.disable();
  56. this._opt = zrUtil.defaults(zrUtil.clone(opt) || {}, {
  57. zoomOnMouseWheel: true,
  58. moveOnMouseMove: true,
  59. preventDefaultMouseMove: true
  60. });
  61. if (controlType == null) {
  62. controlType = true;
  63. }
  64. if (controlType === true || controlType === 'move' || controlType === 'pan') {
  65. zr.on('mousedown', mousedownHandler);
  66. zr.on('mousemove', mousemoveHandler);
  67. zr.on('mouseup', mouseupHandler);
  68. }
  69. if (controlType === true || controlType === 'scale' || controlType === 'zoom') {
  70. zr.on('mousewheel', mousewheelHandler);
  71. zr.on('pinch', pinchHandler);
  72. }
  73. };
  74. this.disable = function () {
  75. zr.off('mousedown', mousedownHandler);
  76. zr.off('mousemove', mousemoveHandler);
  77. zr.off('mouseup', mouseupHandler);
  78. zr.off('mousewheel', mousewheelHandler);
  79. zr.off('pinch', pinchHandler);
  80. };
  81. this.dispose = this.disable;
  82. this.isDragging = function () {
  83. return this._dragging;
  84. };
  85. this.isPinching = function () {
  86. return this._pinching;
  87. };
  88. }
  89. zrUtil.mixin(RoamController, Eventful);
  90. function mousedown(e) {
  91. if (eventTool.notLeftMouse(e) || e.target && e.target.draggable) {
  92. return;
  93. }
  94. var x = e.offsetX;
  95. var y = e.offsetY; // Only check on mosedown, but not mousemove.
  96. // Mouse can be out of target when mouse moving.
  97. if (this.pointerChecker && this.pointerChecker(e, x, y)) {
  98. this._x = x;
  99. this._y = y;
  100. this._dragging = true;
  101. }
  102. }
  103. function mousemove(e) {
  104. if (eventTool.notLeftMouse(e) || !checkKeyBinding(this, 'moveOnMouseMove', e) || !this._dragging || e.gestureEvent === 'pinch' || interactionMutex.isTaken(this._zr, 'globalPan')) {
  105. return;
  106. }
  107. var x = e.offsetX;
  108. var y = e.offsetY;
  109. var oldX = this._x;
  110. var oldY = this._y;
  111. var dx = x - oldX;
  112. var dy = y - oldY;
  113. this._x = x;
  114. this._y = y;
  115. this._opt.preventDefaultMouseMove && eventTool.stop(e.event);
  116. this.trigger('pan', dx, dy, oldX, oldY, x, y);
  117. }
  118. function mouseup(e) {
  119. if (!eventTool.notLeftMouse(e)) {
  120. this._dragging = false;
  121. }
  122. }
  123. function mousewheel(e) {
  124. // wheelDelta maybe -0 in chrome mac.
  125. if (!checkKeyBinding(this, 'zoomOnMouseWheel', e) || e.wheelDelta === 0) {
  126. return;
  127. } // Convenience:
  128. // Mac and VM Windows on Mac: scroll up: zoom out.
  129. // Windows: scroll up: zoom in.
  130. var zoomDelta = e.wheelDelta > 0 ? 1.1 : 1 / 1.1;
  131. zoom.call(this, e, zoomDelta, e.offsetX, e.offsetY);
  132. }
  133. function pinch(e) {
  134. if (interactionMutex.isTaken(this._zr, 'globalPan')) {
  135. return;
  136. }
  137. var zoomDelta = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
  138. zoom.call(this, e, zoomDelta, e.pinchX, e.pinchY);
  139. }
  140. function zoom(e, zoomDelta, zoomX, zoomY) {
  141. if (this.pointerChecker && this.pointerChecker(e, zoomX, zoomY)) {
  142. // When mouse is out of roamController rect,
  143. // default befavoius should not be be disabled, otherwise
  144. // page sliding is disabled, contrary to expectation.
  145. eventTool.stop(e.event);
  146. this.trigger('zoom', zoomDelta, zoomX, zoomY);
  147. }
  148. }
  149. function checkKeyBinding(roamController, prop, e) {
  150. var setting = roamController._opt[prop];
  151. return setting && (!zrUtil.isString(setting) || e.event[setting + 'Key']);
  152. }
  153. var _default = RoamController;
  154. module.exports = _default;