您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

zoom.js 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /**
  2. * WHITEBOPHIR
  3. *********************************************************
  4. * @licstart The following is the entire license notice for the
  5. * JavaScript code in this page.
  6. *
  7. * Copyright (C) 2013 Ophir LOJKINE
  8. *
  9. *
  10. * The JavaScript code in this page is free software: you can
  11. * redistribute it and/or modify it under the terms of the GNU
  12. * General Public License (GNU GPL) as published by the Free Software
  13. * Foundation, either version 3 of the License, or (at your option)
  14. * any later version. The code is distributed WITHOUT ANY WARRANTY;
  15. * without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  17. *
  18. * As additional permission under GNU GPL version 3 section 7, you
  19. * may distribute non-source (e.g., minimized or compacted) forms of
  20. * that code without the copy of the GNU GPL normally required by
  21. * section 4, provided you include this license notice and a URL
  22. * through which recipients can access the Corresponding Source.
  23. *
  24. * @licend
  25. */
  26. (function () { //Code isolation
  27. var ZOOM_FACTOR = .5;
  28. var origin = {
  29. scrollX: window.scrollX,
  30. scrollY: window.scrollY,
  31. x: 0.0,
  32. y: 0.0,
  33. clientY: 0,
  34. scale: 1.0
  35. };
  36. var moved = false, pressed = false;
  37. function zoom(origin, scale) {
  38. var oldScale = origin.scale;
  39. var newScale = Tools.setScale(scale);
  40. window.scrollTo(
  41. origin.scrollX + origin.x * (newScale - oldScale),
  42. origin.scrollY + origin.y * (newScale - oldScale)
  43. );
  44. }
  45. var animation = null;
  46. function animate(scale) {
  47. cancelAnimationFrame(animation);
  48. animation = requestAnimationFrame(function () {
  49. zoom(origin, scale);
  50. });
  51. }
  52. function setOrigin(x, y, evt, isTouchEvent) {
  53. origin.scrollX = window.scrollX;
  54. origin.scrollY = window.scrollY;
  55. origin.x = x;
  56. origin.y = y;
  57. origin.clientY = getClientY(evt, isTouchEvent);
  58. origin.scale = Tools.getScale();
  59. }
  60. function press(x, y, evt, isTouchEvent) {
  61. evt.preventDefault();
  62. setOrigin(x, y, evt, isTouchEvent);
  63. moved = false;
  64. pressed = true;
  65. }
  66. function move(x, y, evt, isTouchEvent) {
  67. if (pressed) {
  68. evt.preventDefault();
  69. var delta = getClientY(evt, isTouchEvent) - origin.clientY;
  70. var scale = origin.scale * (1 + delta * ZOOM_FACTOR / 100);
  71. if (Math.abs(delta) > 1) moved = true;
  72. animation = animate(scale);
  73. }
  74. }
  75. function onwheel(evt) {
  76. evt.preventDefault();
  77. if (evt.ctrlKey || Tools.curTool === zoomTool) {
  78. var scale = Tools.getScale();
  79. var x = evt.pageX / scale;
  80. var y = evt.pageY / scale;
  81. setOrigin(x, y, evt, false);
  82. animate((1 - ((evt.deltaY > 0) - (evt.deltaY < 0)) * 0.25) * Tools.getScale());
  83. } else {
  84. window.scrollTo(window.scrollX + evt.deltaX, window.scrollY + evt.deltaY);
  85. }
  86. }
  87. Tools.board.addEventListener("wheel", onwheel, { passive: false });
  88. Tools.board.addEventListener("touchmove", function ontouchmove(evt) {
  89. // 2-finger pan to zoom
  90. var touches = evt.touches;
  91. if (touches.length === 2) {
  92. var x0 = touches[0].clientX, x1 = touches[1].clientX,
  93. y0 = touches[0].clientY, y1 = touches[1].clientY,
  94. dx = x0 - x1,
  95. dy = y0 - y1;
  96. var x = (touches[0].pageX + touches[1].pageX) / 2 / Tools.getScale(),
  97. y = (touches[0].pageY + touches[1].pageY) / 2 / Tools.getScale();
  98. var distance = Math.sqrt(dx * dx + dy * dy);
  99. if (!pressed) {
  100. pressed = true;
  101. setOrigin(x, y, evt, true);
  102. origin.distance = distance;
  103. } else {
  104. var delta = distance - origin.distance;
  105. var scale = origin.scale * (1 + delta * ZOOM_FACTOR / 100);
  106. animate(scale);
  107. }
  108. }
  109. }, { passive: true });
  110. function touchend() {
  111. pressed = false;
  112. }
  113. Tools.board.addEventListener("touchend", touchend);
  114. Tools.board.addEventListener("touchcancel", touchend);
  115. function release(x, y, evt, isTouchEvent) {
  116. if (pressed && !moved) {
  117. var delta = (evt.shiftKey === true) ? -1 : 1;
  118. var scale = Tools.getScale() * (1 + delta * ZOOM_FACTOR);
  119. zoom(origin, scale);
  120. }
  121. pressed = false;
  122. }
  123. function key(down) {
  124. return function (evt) {
  125. if (evt.key === "Shift") {
  126. Tools.svg.style.cursor = "zoom-" + (down ? "out" : "in");
  127. }
  128. }
  129. }
  130. function getClientY(evt, isTouchEvent) {
  131. return isTouchEvent ? evt.changedTouches[0].clientY : evt.clientY;
  132. }
  133. var keydown = key(true);
  134. var keyup = key(false);
  135. function onstart() {
  136. window.addEventListener("keydown", keydown);
  137. window.addEventListener("keyup", keyup);
  138. }
  139. function onquit() {
  140. window.removeEventListener("keydown", keydown);
  141. window.removeEventListener("keyup", keyup);
  142. }
  143. var zoomTool = {
  144. "name": "Zoom",
  145. "shortcut": "z",
  146. "listeners": {
  147. "press": press,
  148. "move": move,
  149. "release": release,
  150. },
  151. "onstart": onstart,
  152. "onquit": onquit,
  153. "mouseCursor": "zoom-in",
  154. "icon": "tools/zoom/icon.svg",
  155. "helpText": "click_to_zoom",
  156. };
  157. Tools.add(zoomTool);
  158. })(); //End of code isolation