説明なし

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // SVG pan and zoom library.
  2. // See copyright notice in string constant below.
  3. package svgpan
  4. // https://github.com/aleofreddi/svgpan
  5. // JSSource returns the svgpan.js file
  6. const JSSource = `
  7. /**
  8. * SVGPan library 1.2.2
  9. * ======================
  10. *
  11. * Given an unique existing element with id "viewport" (or when missing, the
  12. * first g-element), including the library into any SVG adds the following
  13. * capabilities:
  14. *
  15. * - Mouse panning
  16. * - Mouse zooming (using the wheel)
  17. * - Object dragging
  18. *
  19. * You can configure the behaviour of the pan/zoom/drag with the variables
  20. * listed in the CONFIGURATION section of this file.
  21. *
  22. * Known issues:
  23. *
  24. * - Zooming (while panning) on Safari has still some issues
  25. *
  26. * Releases:
  27. *
  28. * 1.2.2, Tue Aug 30 17:21:56 CEST 2011, Andrea Leofreddi
  29. * - Fixed viewBox on root tag (#7)
  30. * - Improved zoom speed (#2)
  31. *
  32. * 1.2.1, Mon Jul 4 00:33:18 CEST 2011, Andrea Leofreddi
  33. * - Fixed a regression with mouse wheel (now working on Firefox 5)
  34. * - Working with viewBox attribute (#4)
  35. * - Added "use strict;" and fixed resulting warnings (#5)
  36. * - Added configuration variables, dragging is disabled by default (#3)
  37. *
  38. * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
  39. * Fixed a bug with browser mouse handler interaction
  40. *
  41. * 1.1, Wed Feb 3 17:39:33 GMT 2010, Zeng Xiaohui
  42. * Updated the zoom code to support the mouse wheel on Safari/Chrome
  43. *
  44. * 1.0, Andrea Leofreddi
  45. * First release
  46. *
  47. * This code is licensed under the following BSD license:
  48. *
  49. * Copyright 2009-2017 Andrea Leofreddi <a.leofreddi@vleo.net>. All rights reserved.
  50. *
  51. * Redistribution and use in source and binary forms, with or without modification, are
  52. * permitted provided that the following conditions are met:
  53. *
  54. * 1. Redistributions of source code must retain the above copyright
  55. * notice, this list of conditions and the following disclaimer.
  56. * 2. Redistributions in binary form must reproduce the above copyright
  57. * notice, this list of conditions and the following disclaimer in the
  58. * documentation and/or other materials provided with the distribution.
  59. * 3. Neither the name of the copyright holder nor the names of its
  60. * contributors may be used to endorse or promote products derived from
  61. * this software without specific prior written permission.
  62. *
  63. * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY EXPRESS
  64. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  65. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR
  66. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  67. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  68. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  70. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  71. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72. *
  73. * The views and conclusions contained in the software and documentation are those of the
  74. * authors and should not be interpreted as representing official policies, either expressed
  75. * or implied, of Andrea Leofreddi.
  76. */
  77. "use strict";
  78. /// CONFIGURATION
  79. /// ====>
  80. var enablePan = 1; // 1 or 0: enable or disable panning (default enabled)
  81. var enableZoom = 1; // 1 or 0: enable or disable zooming (default enabled)
  82. var enableDrag = 0; // 1 or 0: enable or disable dragging (default disabled)
  83. var zoomScale = 0.2; // Zoom sensitivity
  84. /// <====
  85. /// END OF CONFIGURATION
  86. var root = document.documentElement;
  87. var state = 'none', svgRoot = null, stateTarget, stateOrigin, stateTf;
  88. setupHandlers(root);
  89. /**
  90. * Register handlers
  91. */
  92. function setupHandlers(root){
  93. setAttributes(root, {
  94. "onmouseup" : "handleMouseUp(evt)",
  95. "onmousedown" : "handleMouseDown(evt)",
  96. "onmousemove" : "handleMouseMove(evt)",
  97. //"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
  98. });
  99. if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
  100. window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
  101. else
  102. window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
  103. }
  104. /**
  105. * Retrieves the root element for SVG manipulation. The element is then cached into the svgRoot global variable.
  106. */
  107. function getRoot(root) {
  108. if(svgRoot == null) {
  109. var r = root.getElementById("viewport") ? root.getElementById("viewport") : root.documentElement, t = r;
  110. while(t != root) {
  111. if(t.getAttribute("viewBox")) {
  112. setCTM(r, t.getCTM());
  113. t.removeAttribute("viewBox");
  114. }
  115. t = t.parentNode;
  116. }
  117. svgRoot = r;
  118. }
  119. return svgRoot;
  120. }
  121. /**
  122. * Instance an SVGPoint object with given event coordinates.
  123. */
  124. function getEventPoint(evt) {
  125. var p = root.createSVGPoint();
  126. p.x = evt.clientX;
  127. p.y = evt.clientY;
  128. return p;
  129. }
  130. /**
  131. * Sets the current transform matrix of an element.
  132. */
  133. function setCTM(element, matrix) {
  134. var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
  135. element.setAttribute("transform", s);
  136. }
  137. /**
  138. * Dumps a matrix to a string (useful for debug).
  139. */
  140. function dumpMatrix(matrix) {
  141. var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n 0, 0, 1 ]";
  142. return s;
  143. }
  144. /**
  145. * Sets attributes of an element.
  146. */
  147. function setAttributes(element, attributes){
  148. for (var i in attributes)
  149. element.setAttributeNS(null, i, attributes[i]);
  150. }
  151. /**
  152. * Handle mouse wheel event.
  153. */
  154. function handleMouseWheel(evt) {
  155. if(!enableZoom)
  156. return;
  157. if(evt.preventDefault)
  158. evt.preventDefault();
  159. evt.returnValue = false;
  160. var svgDoc = evt.target.ownerDocument;
  161. var delta;
  162. if(evt.wheelDelta)
  163. delta = evt.wheelDelta / 360; // Chrome/Safari
  164. else
  165. delta = evt.detail / -9; // Mozilla
  166. var z = Math.pow(1 + zoomScale, delta);
  167. var g = getRoot(svgDoc);
  168. var p = getEventPoint(evt);
  169. p = p.matrixTransform(g.getCTM().inverse());
  170. // Compute new scale matrix in current mouse position
  171. var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
  172. setCTM(g, g.getCTM().multiply(k));
  173. if(typeof(stateTf) == "undefined")
  174. stateTf = g.getCTM().inverse();
  175. stateTf = stateTf.multiply(k.inverse());
  176. }
  177. /**
  178. * Handle mouse move event.
  179. */
  180. function handleMouseMove(evt) {
  181. if(evt.preventDefault)
  182. evt.preventDefault();
  183. evt.returnValue = false;
  184. var svgDoc = evt.target.ownerDocument;
  185. var g = getRoot(svgDoc);
  186. if(state == 'pan' && enablePan) {
  187. // Pan mode
  188. var p = getEventPoint(evt).matrixTransform(stateTf);
  189. setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
  190. } else if(state == 'drag' && enableDrag) {
  191. // Drag mode
  192. var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
  193. setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
  194. stateOrigin = p;
  195. }
  196. }
  197. /**
  198. * Handle click event.
  199. */
  200. function handleMouseDown(evt) {
  201. if(evt.preventDefault)
  202. evt.preventDefault();
  203. evt.returnValue = false;
  204. var svgDoc = evt.target.ownerDocument;
  205. var g = getRoot(svgDoc);
  206. if(
  207. evt.target.tagName == "svg"
  208. || !enableDrag // Pan anyway when drag is disabled and the user clicked on an element
  209. ) {
  210. // Pan mode
  211. state = 'pan';
  212. stateTf = g.getCTM().inverse();
  213. stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
  214. } else {
  215. // Drag mode
  216. state = 'drag';
  217. stateTarget = evt.target;
  218. stateTf = g.getCTM().inverse();
  219. stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
  220. }
  221. }
  222. /**
  223. * Handle mouse button release event.
  224. */
  225. function handleMouseUp(evt) {
  226. if(evt.preventDefault)
  227. evt.preventDefault();
  228. evt.returnValue = false;
  229. var svgDoc = evt.target.ownerDocument;
  230. if(state == 'pan' || state == 'drag') {
  231. // Quit pan mode
  232. state = '';
  233. }
  234. }
  235. `