zoom.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. define(function(require, exports, module) {
  2. var kity = require('../core/kity');
  3. var utils = require('../core/utils');
  4. var Minder = require('../core/minder');
  5. var MinderNode = require('../core/node');
  6. var Command = require('../core/command');
  7. var Module = require('../core/module');
  8. var Renderer = require('../core/render');
  9. Module.register('Zoom', function() {
  10. var me = this;
  11. var timeline;
  12. function setTextRendering() {
  13. var value = me._zoomValue >= 100 ? 'optimize-speed' : 'geometricPrecision';
  14. me.getRenderContainer().setAttr('text-rendering', value);
  15. }
  16. function fixPaperCTM(paper) {
  17. var node = paper.shapeNode;
  18. var ctm = node.getCTM();
  19. var matrix = new kity.Matrix(ctm.a, ctm.b, ctm.c, ctm.d, (ctm.e | 0) + 0.5, (ctm.f | 0) + 0.5);
  20. node.setAttribute('transform', 'matrix(' + matrix.toString() + ')');
  21. }
  22. kity.extendClass(Minder, {
  23. zoom: function(value) {
  24. var paper = this.getPaper();
  25. var viewport = paper.getViewPort();
  26. viewport.zoom = value / 100;
  27. viewport.center = {
  28. x: viewport.center.x,
  29. y: viewport.center.y
  30. };
  31. paper.setViewPort(viewport);
  32. if (value == 100) fixPaperCTM(paper);
  33. },
  34. getZoomValue: function() {
  35. return this._zoomValue;
  36. }
  37. });
  38. function zoomMinder(minder, value) {
  39. var paper = minder.getPaper();
  40. var viewport = paper.getViewPort();
  41. if (!value) return;
  42. setTextRendering();
  43. var duration = minder.getOption('zoomAnimationDuration');
  44. if (minder.getRoot().getComplex() > 200 || !duration) {
  45. minder._zoomValue = value;
  46. minder.zoom(value);
  47. minder.fire('viewchange');
  48. } else {
  49. var animator = new kity.Animator({
  50. beginValue: minder._zoomValue,
  51. finishValue: value,
  52. setter: function(target, value) {
  53. target.zoom(value);
  54. }
  55. });
  56. minder._zoomValue = value;
  57. if (timeline) {
  58. timeline.pause();
  59. }
  60. timeline = animator.start(minder, duration, 'easeInOutSine');
  61. timeline.on('finish', function() {
  62. minder.fire('viewchange');
  63. });
  64. }
  65. minder.fire('zoom', {
  66. zoom: value
  67. });
  68. }
  69. /**
  70. * @command Zoom
  71. * @description 缩放当前的视野到一定的比例(百分比)
  72. * @param {number} value 设置的比例,取值 100 则为原尺寸
  73. * @state
  74. * 0: 始终可用
  75. */
  76. var ZoomCommand = kity.createClass('Zoom', {
  77. base: Command,
  78. execute: zoomMinder,
  79. queryValue: function(minder) {
  80. return minder._zoomValue;
  81. }
  82. });
  83. /**
  84. * @command ZoomIn
  85. * @description 放大当前的视野到下一个比例等级(百分比)
  86. * @shortcut =
  87. * @state
  88. * 0: 如果当前脑图的配置中还有下一个比例等级
  89. * -1: 其它情况
  90. */
  91. var ZoomInCommand = kity.createClass('ZoomInCommand', {
  92. base: Command,
  93. execute: function(minder) {
  94. zoomMinder(minder, this.nextValue(minder));
  95. },
  96. queryState: function(minder) {
  97. return +!this.nextValue(minder);
  98. },
  99. nextValue: function(minder) {
  100. var stack = minder.getOption('zoom'),
  101. i;
  102. for (i = 0; i < stack.length; i++) {
  103. if (stack[i] > minder._zoomValue) return stack[i];
  104. }
  105. return 0;
  106. },
  107. enableReadOnly: true
  108. });
  109. /**
  110. * @command ZoomOut
  111. * @description 缩小当前的视野到上一个比例等级(百分比)
  112. * @shortcut -
  113. * @state
  114. * 0: 如果当前脑图的配置中还有上一个比例等级
  115. * -1: 其它情况
  116. */
  117. var ZoomOutCommand = kity.createClass('ZoomOutCommand', {
  118. base: Command,
  119. execute: function(minder) {
  120. zoomMinder(minder, this.nextValue(minder));
  121. },
  122. queryState: function(minder) {
  123. return +!this.nextValue(minder);
  124. },
  125. nextValue: function(minder) {
  126. var stack = minder.getOption('zoom'),
  127. i;
  128. for (i = stack.length - 1; i >= 0; i--) {
  129. if (stack[i] < minder._zoomValue) return stack[i];
  130. }
  131. return 0;
  132. },
  133. enableReadOnly: true
  134. });
  135. return {
  136. init: function() {
  137. this._zoomValue = 100;
  138. this.setDefaultOptions({
  139. zoom: [10, 20, 50, 100, 200]
  140. });
  141. setTextRendering();
  142. },
  143. commands: {
  144. 'zoomin': ZoomInCommand,
  145. 'zoomout': ZoomOutCommand,
  146. 'zoom': ZoomCommand
  147. },
  148. events: {
  149. 'normal.mousewheel readonly.mousewheel': function(e) {
  150. if (!e.originEvent.ctrlKey && !e.originEvent.metaKey) return;
  151. var delta = e.originEvent.wheelDelta;
  152. var me = this;
  153. // 稀释
  154. if (Math.abs(delta) > 100) {
  155. clearTimeout(this._wheelZoomTimeout);
  156. } else {
  157. return;
  158. }
  159. this._wheelZoomTimeout = setTimeout(function() {
  160. var value;
  161. var lastValue = me.getPaper()._zoom || 1;
  162. if (delta > 0) {
  163. me.execCommand('zoomin');
  164. } else if (delta < 0) {
  165. me.execCommand('zoomout');
  166. }
  167. }, 100);
  168. e.originEvent.preventDefault();
  169. }
  170. },
  171. commandShortcutKeys: {
  172. 'zoomin': 'ctrl+=',
  173. 'zoomout': 'ctrl+-'
  174. }
  175. };
  176. });
  177. });