Spaces:
Running
Running
| /** | |
| * WHITEBOPHIR | |
| ********************************************************* | |
| * @licstart The following is the entire license notice for the | |
| * JavaScript code in this page. | |
| * | |
| * Copyright (C) 2013 Ophir LOJKINE | |
| * | |
| * | |
| * The JavaScript code in this page is free software: you can | |
| * redistribute it and/or modify it under the terms of the GNU | |
| * General Public License (GNU GPL) as published by the Free Software | |
| * Foundation, either version 3 of the License, or (at your option) | |
| * any later version. The code is distributed WITHOUT ANY WARRANTY; | |
| * without even the implied warranty of MERCHANTABILITY or FITNESS | |
| * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
| * | |
| * As additional permission under GNU GPL version 3 section 7, you | |
| * may distribute non-source (e.g., minimized or compacted) forms of | |
| * that code without the copy of the GNU GPL normally required by | |
| * section 4, provided you include this license notice and a URL | |
| * through which recipients can access the Corresponding Source. | |
| * | |
| * @licend | |
| */ | |
| (function () { | |
| //Code isolation | |
| var ZOOM_FACTOR = 0.5; | |
| var origin = { | |
| scrollX: document.documentElement.scrollLeft, | |
| scrollY: document.documentElement.scrollTop, | |
| x: 0.0, | |
| y: 0.0, | |
| clientY: 0, | |
| scale: 1.0, | |
| }; | |
| var moved = false, | |
| pressed = false; | |
| function zoom(origin, scale) { | |
| var oldScale = origin.scale; | |
| var newScale = Tools.setScale(scale); | |
| window.scrollTo( | |
| origin.scrollX + origin.x * (newScale - oldScale), | |
| origin.scrollY + origin.y * (newScale - oldScale), | |
| ); | |
| } | |
| var animation = null; | |
| function animate(scale) { | |
| cancelAnimationFrame(animation); | |
| animation = requestAnimationFrame(function () { | |
| zoom(origin, scale); | |
| }); | |
| } | |
| function setOrigin(x, y, evt, isTouchEvent) { | |
| origin.scrollX = document.documentElement.scrollLeft; | |
| origin.scrollY = document.documentElement.scrollTop; | |
| origin.x = x; | |
| origin.y = y; | |
| origin.clientY = getClientY(evt, isTouchEvent); | |
| origin.scale = Tools.getScale(); | |
| } | |
| function press(x, y, evt, isTouchEvent) { | |
| evt.preventDefault(); | |
| setOrigin(x, y, evt, isTouchEvent); | |
| moved = false; | |
| pressed = true; | |
| } | |
| function move(x, y, evt, isTouchEvent) { | |
| if (pressed) { | |
| evt.preventDefault(); | |
| var delta = getClientY(evt, isTouchEvent) - origin.clientY; | |
| var scale = origin.scale * (1 + (delta * ZOOM_FACTOR) / 100); | |
| if (Math.abs(delta) > 1) moved = true; | |
| animation = animate(scale); | |
| } | |
| } | |
| function onwheel(evt) { | |
| evt.preventDefault(); | |
| var multiplier = | |
| evt.deltaMode === WheelEvent.DOM_DELTA_LINE | |
| ? 30 | |
| : evt.deltaMode === WheelEvent.DOM_DELTA_PAGE | |
| ? 1000 | |
| : 1; | |
| var deltaX = evt.deltaX * multiplier, | |
| deltaY = evt.deltaY * multiplier; | |
| if (!evt.ctrlKey) { | |
| // zoom | |
| var scale = Tools.getScale(); | |
| var x = evt.pageX / scale; | |
| var y = evt.pageY / scale; | |
| setOrigin(x, y, evt, false); | |
| animate((1 - deltaY / 800) * Tools.getScale()); | |
| } else if (evt.altKey) { | |
| // make finer changes if shift is being held | |
| var change = evt.shiftKey ? 1 : 5; | |
| // change tool size | |
| Tools.setSize(Tools.getSize() - (deltaY / 100) * change); | |
| } else if (evt.shiftKey) { | |
| // scroll horizontally | |
| window.scrollTo( | |
| document.documentElement.scrollLeft + deltaY, | |
| document.documentElement.scrollTop + deltaX, | |
| ); | |
| } else { | |
| // regular scrolling | |
| window.scrollTo( | |
| document.documentElement.scrollLeft + deltaX, | |
| document.documentElement.scrollTop + deltaY, | |
| ); | |
| } | |
| } | |
| Tools.board.addEventListener("wheel", onwheel, { passive: false }); | |
| Tools.board.addEventListener( | |
| "touchmove", | |
| function ontouchmove(evt) { | |
| // 2-finger pan to zoom | |
| var touches = evt.touches; | |
| if (touches.length === 2) { | |
| var x0 = touches[0].clientX, | |
| x1 = touches[1].clientX, | |
| y0 = touches[0].clientY, | |
| y1 = touches[1].clientY, | |
| dx = x0 - x1, | |
| dy = y0 - y1; | |
| var x = (touches[0].pageX + touches[1].pageX) / 2 / Tools.getScale(), | |
| y = (touches[0].pageY + touches[1].pageY) / 2 / Tools.getScale(); | |
| var distance = Math.sqrt(dx * dx + dy * dy); | |
| if (!pressed) { | |
| pressed = true; | |
| setOrigin(x, y, evt, true); | |
| origin.distance = distance; | |
| } else { | |
| var delta = distance - origin.distance; | |
| var scale = origin.scale * (1 + (delta * ZOOM_FACTOR) / 100); | |
| animate(scale); | |
| } | |
| } | |
| }, | |
| { passive: true }, | |
| ); | |
| function touchend() { | |
| pressed = false; | |
| } | |
| Tools.board.addEventListener("touchend", touchend); | |
| Tools.board.addEventListener("touchcancel", touchend); | |
| function release(x, y, evt, isTouchEvent) { | |
| if (pressed && !moved) { | |
| var delta = evt.shiftKey === true ? -1 : 1; | |
| var scale = Tools.getScale() * (1 + delta * ZOOM_FACTOR); | |
| zoom(origin, scale); | |
| } | |
| pressed = false; | |
| } | |
| function key(down) { | |
| return function (evt) { | |
| if (evt.key === "Shift") { | |
| Tools.svg.style.cursor = "zoom-" + (down ? "out" : "in"); | |
| } | |
| }; | |
| } | |
| function getClientY(evt, isTouchEvent) { | |
| return isTouchEvent ? evt.changedTouches[0].clientY : evt.clientY; | |
| } | |
| var keydown = key(true); | |
| var keyup = key(false); | |
| function onstart() { | |
| window.addEventListener("keydown", keydown); | |
| window.addEventListener("keyup", keyup); | |
| } | |
| function onquit() { | |
| window.removeEventListener("keydown", keydown); | |
| window.removeEventListener("keyup", keyup); | |
| } | |
| var zoomTool = { | |
| name: "Zoom", | |
| shortcut: "z", | |
| listeners: { | |
| press: press, | |
| move: move, | |
| release: release, | |
| }, | |
| onstart: onstart, | |
| onquit: onquit, | |
| mouseCursor: "zoom-in", | |
| icon: "tools/zoom/icon.svg", | |
| helpText: "click_to_zoom", | |
| showMarker: true, | |
| }; | |
| Tools.add(zoomTool); | |
| })(); //End of code isolation | |