├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── demos ├── Drag │ ├── dragElement │ │ ├── index.html │ │ └── index.js │ ├── paint │ │ ├── index.html │ │ └── index.js │ ├── reveal │ │ ├── index.html │ │ ├── index.js │ │ ├── style.css │ │ └── swipeReveal.js │ └── swipe │ │ ├── index.html │ │ └── index.js ├── Longpress │ ├── index.html │ └── index.js ├── Pinch │ └── rotate │ │ ├── index.html │ │ ├── p5.min.js │ │ └── sketch.js ├── dist │ ├── drag.js │ ├── drag.js.map │ ├── drag.min.js │ ├── drag.min.js.map │ ├── index.js │ ├── index.js.map │ ├── index.min.js │ ├── index.min.js.map │ ├── interfaces.js │ ├── longpress.js │ ├── longpress.js.map │ ├── longpress.min.js │ ├── longpress.min.js.map │ ├── pinch.js │ ├── pinch.js.map │ ├── pinch.min.js │ ├── pinch.min.js.map │ └── shared.js ├── index.html ├── index.js └── style.css ├── dist ├── drag.js ├── drag.js.map ├── index.js ├── index.js.map ├── interfaces.js ├── longpress.js ├── longpress.js.map ├── pinch.js ├── pinch.js.map └── shared.js ├── lib ├── drag.ts ├── index.ts ├── interfaces.ts ├── longpress.ts ├── pinch.ts └── shared.ts ├── package-lock.json ├── package.json ├── rollup.config.js ├── tsconfig.json └── types ├── drag.d.ts ├── global.d.ts ├── index.d.ts ├── interfaces.d.ts ├── longpress.d.ts ├── pinch.d.ts ├── shared.d.ts └── svelte-jsx.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | test.js 2 | node_modules/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 4 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.ignoreWords": [ 3 | "dragmove", 4 | "dragstop", 5 | "ezgdragmove", 6 | "ezgdragstart", 7 | "ezgdragstop", 8 | "ezgesture", 9 | "ezglongpress", 10 | "ezgpinchend", 11 | "ezgpinchmove", 12 | "ezgpinchstart", 13 | "gzipped", 14 | "longpress", 15 | "pinchstart" 16 | ], 17 | "cSpell.words": [ 18 | "qurafi" 19 | ] 20 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Mohammed Al-Qurafi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EZGesture(~1KB GZipped) 2 | ![npm (tag)](https://img.shields.io/npm/v/ezgesture) ![GitHub](https://img.shields.io/github/license/mhmd-22/ezgesture) 3 | 4 | Easily add gestures functionality with simple native DOM events 5 | 6 | 7 | - [EZGesture(~1KB GZipped)](#ezgesture1kb-gzipped) 8 | - [Installation](#installation) 9 | - [Quick Start](#quick-start) 10 | - [Usage](#usage) 11 | - [Drag Events](#drag-events) 12 | - [Pinch Events](#pinch-events) 13 | - [`ezgpinchstart`](#ezgpinchstart) 14 | - [`ezgpinchmove`](#ezgpinchmove) 15 | - [`ezgpinchend`](#ezgpinchend) 16 | - [Longpress Events](#longpress-events) 17 | - [Integration with other frameworks](#integration-with-other-frameworks) 18 | - [Svelte](#svelte) 19 | - [Browser Support](#browser-support) 20 | 21 | 22 | ## Installation 23 | **NPM** 24 | 25 | `npm i ezgesture` 26 | 27 | **CDN:** 28 | 29 | ```html 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | ``` 39 | 40 | 41 | ## Quick Start 42 | ```javascript 43 | 44 | // drag events 45 | EZG.enableDragEvents(elm, options?: {threshold: 0}) 46 | elm.addEventListener("ezgdragstart", onDragStart) 47 | elm.addEventListener("ezgdragmove", onDragMove) 48 | elm.addEventListener("ezgdragstop", onDragMove) 49 | 50 | // pinch events 51 | EZG.enablePinchEvents(elm, options?: {distanceThreshold: 0, angleThreshold: 0}) 52 | elm.addEventListener("ezgpinchstart", onPinchStart) 53 | elm.addEventListener("ezgpinchmove", onPinchMove) 54 | elm.addEventListener("ezgpinchend", onPinchEnd) 55 | 56 | // longpress events 57 | EZG.enableLongPressEvents(elm, {duration: 700}) 58 | elm.addEventListener("ezglongpress", onLongPress) 59 | ``` 60 | [Full Demo](https://mhmd-22.github.io/ezgesture/) 61 | 62 | Source code available in [demos folder](demos/) 63 | 64 | 65 | 66 | 67 | ## Usage 68 | ### Drag Events 69 | To enable drag events: 70 | ```javascript 71 | EZG.enableDragEvent(elm, options?) 72 | ``` 73 | 74 | You can also supply `threshold` in options to set minimum distance to trigger events 75 | 76 | **Events** 77 | - `ezgdragstart` - cancelable with `e.preventDefault()` 78 | - `ezgdragmove` - cancelable. will stop calculating last offset. 79 | - `ezgdragstop` 80 | 81 | 82 | **Events parameters:** 83 | Use `e.detail` to access these event parameters: 84 | ```javascript 85 | 86 | // Initial drag position 87 | startX, startY 88 | 89 | // Last drag position 90 | lastX, lastY 91 | 92 | // Mouse delta from initial drag position 93 | offsetX, offsetY 94 | 95 | // Mouse delta from last mouse position 96 | movementX, movementY 97 | 98 | // it can be Touch or Mouse Event 99 | // so you could use properties like ctrlKey or altKey 100 | originalEvent 101 | ``` 102 | 103 | ### Pinch Events 104 | 105 | To enable pinch events: 106 | ```javascript 107 | EZG.enablePinchEvent(elm, options?) 108 | ``` 109 | 110 | Available options: 111 | * `distanceThreshold`: minimum distance to trigger event 112 | * `angleThreshold`: minimum angle(radians) 113 | 114 | ### `ezgpinchstart` 115 | **cancelable**: Yes, with `e.preventDefault()` 116 | 117 | 118 | **parameters**: 119 | ```javascript 120 | startTouches 121 | originalEvent 122 | ``` 123 | 124 | ### `ezgpinchmove` 125 | **cancelable**: Yes, It will stop calculating `lastXXX` parameters such as `lastOffset` and `lastDist` 126 | 127 | **parameters**: 128 | * `dx, dy`: difference between the two touches 129 | * `da`: angle difference from last movement 130 | * `dist`: distance between two fingers 131 | * `offset`: distance difference from last touch 132 | * `angle`: angle between two fingers (radians) 133 | * `midX, midY`: center position of two fingers 134 | * `dir`: direction of the pinch. -1=pinch in, 1=out, 0=no direction change 135 | * `startTouches` 136 | * `lastTouches` 137 | * `lastOffset` 138 | * `lastDist` 139 | * `lastAngle` 140 | 141 | ### `ezgpinchend` 142 | **cancelable**: No 143 | 144 | **parameters**: 145 | * `startTouches` 146 | * `lastTouches` 147 | * `lastOffset` 148 | * `lastDist` 149 | * `lastAngle` 150 | 151 | ### Longpress Events 152 | 153 | To enable longpress events: 154 | ```javascript 155 | EZG.enableLongPressEvents(elm, {duration: ms}) 156 | ``` 157 | The default duration is `700ms`. and it has only one parameter `originalEvent` 158 | 159 | ## Integration with other frameworks 160 | 161 | ### Svelte 162 | You could also listen to these events with framework that uses native dom events. For example in svelte you could use: 163 | 164 | ```svelte 165 |
166 | ``` 167 | 168 | [Example](https://svelte.dev/repl/e426f80d0f31427f85943e11ad337a36?version=3.37.0) 169 | 170 | ## Browser Support 171 | Should support most of latest 5 years browsers. if you want more support you could through polyfills 172 | 173 | -------------------------------------------------------------------------------- /demos/Drag/dragElement/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 47 | 48 | 49 | 50 |
You cannot overlap me
51 |
52 |

Drag me

53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /demos/Drag/dragElement/index.js: -------------------------------------------------------------------------------- 1 | const zone = document.getElementById("zone"); 2 | const div = document.getElementById("box"); 3 | EZG.enableDragEvents(div); 4 | 5 | let divOffsetX = 0; 6 | let divOffsetY = 0; 7 | 8 | div.addEventListener("ezgdragmove", (e) => { 9 | let { movementX, movementY, clientX, clientY } = e.detail; 10 | 11 | const divRect = div.getBoundingClientRect(); 12 | const elmRect = zone.getBoundingClientRect(); 13 | 14 | const isInZone = 15 | divRect.right + movementX >= elmRect.left && // x 16 | divRect.left + movementX <= elmRect.right && 17 | divRect.bottom + movementY >= elmRect.top && // y 18 | divRect.top + movementY <= elmRect.bottom; 19 | 20 | if (isInZone) { 21 | if (clientX > elmRect.right + divRect.width / 2) { 22 | setBoxOffset(elmRect.right, elmRect.top); 23 | } else if (clientX < elmRect.left - divRect.width / 2) { 24 | setBoxOffset(elmRect.left - divRect.width, elmRect.top); 25 | } 26 | 27 | if (clientY > elmRect.bottom + divRect.height / 2) { 28 | setBoxOffset(elmRect.left, elmRect.bottom); 29 | } else if (clientY < elmRect.top - divRect.height / 2) { 30 | setBoxOffset(elmRect.left, elmRect.top - divRect.height); 31 | } 32 | 33 | return; 34 | } 35 | 36 | setBoxOffset(divOffsetX + movementX, divOffsetY + movementY); 37 | }); 38 | 39 | function setBoxOffset(nx = divOffsetX, ny = divOffsetY) { 40 | divOffsetX = nx; 41 | divOffsetY = ny; 42 | div.style.transform = `translate(${divOffsetX}px, ${divOffsetY}px)`; 43 | } 44 | -------------------------------------------------------------------------------- /demos/Drag/paint/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |

🎨Easy Paint

43 |

44 | Easily create paint app with just 23 lines of code with both 45 | support for touch and mouse inputs 46 |

47 |
48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /demos/Drag/paint/index.js: -------------------------------------------------------------------------------- 1 | const canvas = document.querySelector("canvas"); 2 | const ctx = canvas.getContext("2d"); 3 | EZG.enableDragEvents(canvas); 4 | 5 | window.onresize = function () { 6 | canvas.width = window.innerWidth - 4; 7 | canvas.height = window.innerHeight / 2; 8 | 9 | ctx.strokeStyle = "#ccc"; 10 | ctx.lineWidth = 5; 11 | ctx.lineCap = "round"; 12 | ctx.lineJoin = "round"; 13 | }; 14 | 15 | window.onresize(); 16 | 17 | canvas.addEventListener("ezgdragmove", (e) => { 18 | const { clientX, clientY, lastX, lastY } = e.detail; 19 | const canvasRect = canvas.getBoundingClientRect(); // to get mouse position relative to canvas position 20 | ctx.beginPath(); 21 | ctx.moveTo(lastX - canvasRect.left, lastY - canvasRect.top); 22 | ctx.lineTo(clientX - canvasRect.left, clientY - canvasRect.top); 23 | ctx.closePath(); 24 | ctx.stroke(); 25 | }); 26 | -------------------------------------------------------------------------------- /demos/Drag/reveal/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 |
26 | 27 | 28 |
29 |

Hello 👋

30 |

< Swipe right on the edge of the screen to reveal the sidebar

31 |
32 |
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /demos/Drag/reveal/index.js: -------------------------------------------------------------------------------- 1 | const aside = document.querySelector("aside"); 2 | EZG.enableDragEvents(document); 3 | 4 | const toggleSideBar = enableSwipeToReveal(aside, { swipeArea: 65 }); 5 | 6 | const menu = document.getElementById("menu"); 7 | menu.addEventListener("click", (e) => { 8 | const show = !aside.classList.contains("active"); 9 | toggleSideBar(show); 10 | }); 11 | -------------------------------------------------------------------------------- /demos/Drag/reveal/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100vh; 3 | } 4 | body{ 5 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 6 | margin: 0; 7 | height: 100%; 8 | 9 | color: #ccc; 10 | } 11 | 12 | 13 | aside { 14 | position: fixed; 15 | top: 0; 16 | width: max(25vw, 200px); 17 | height: 100%; 18 | background-color: rgb(219, 85, 61); 19 | padding: 1em; 20 | display: none; 21 | user-select: none; 22 | 23 | } 24 | 25 | aside.active { 26 | box-shadow: -12px 0 50px rgba(93, 50, 50, 0.8) 27 | } 28 | 29 | main { 30 | padding: 1em 4em 31 | } 32 | 33 | #menu { 34 | display: inline-block; 35 | width: 2em; 36 | height: 2em; 37 | margin: 0; 38 | margin-top: 1em; 39 | font-size: 24pt; 40 | cursor: pointer; 41 | -webkit-tap-highlight-color: #00000000; 42 | } 43 | 44 | input { 45 | padding: .5em 1em; 46 | } -------------------------------------------------------------------------------- /demos/Drag/reveal/swipeReveal.js: -------------------------------------------------------------------------------- 1 | const defaults = { 2 | axis: "X", 3 | swipeArea: 30, 4 | minOffset: 50, 5 | touchActions: true, // enable automatic disabling of the pan-x/y touch-actions depends the axis 6 | }; 7 | 8 | function enableSwipeToReveal(elm, options = {}) { 9 | options = { ...defaults, options }; 10 | 11 | const { axis, swipeArea, minOffset, touchActions } = options; 12 | 13 | let isOpen; 14 | function swipeOn(on) { 15 | elm.style.transform = `translate${axis}(${on ? "0" : "-100%"})`; 16 | isOpen = on; 17 | 18 | elm.classList.toggle("active", on); 19 | 20 | // slide it back when clicking outside element 21 | if (on) { 22 | document.addEventListener("mouseup", close); 23 | document.addEventListener("touchend", close); 24 | } 25 | } 26 | 27 | elm.style.transition = "transform 0.2s"; 28 | elm.style.display = "block"; 29 | 30 | // hide it 31 | swipeOn(false); 32 | 33 | // make sure we disable panning-x/y gestures actions in browser to prevent scroll or other related actions (e.g. swipe-to-refresh) 34 | if (touchActions) 35 | document.body.style.touchAction = `pan-${axis == "X" ? "y" : "x"}`; 36 | 37 | document.addEventListener("ezgdragstart", (e) => { 38 | // cancel dragging when it is not in swipe area 39 | if (!isOpen && e.detail[`start${axis}`] >= swipeArea) 40 | return e.preventDefault(); 41 | 42 | // temporarily disable user selection 43 | document.body.style.userSelect = "none"; 44 | }); 45 | 46 | document.addEventListener("ezgdragstop", (e) => { 47 | // const { offsetX } = e.detail; 48 | const offset = e.detail[`offset${axis}`]; 49 | 50 | // reset user selection 51 | document.body.style.userSelect = ""; 52 | 53 | // set minimum distance to swipe to avoid accident swipes 54 | if (Math.abs(offset) < minOffset) return; 55 | 56 | //offsetX > 0 -> swipe right 57 | swipeOn(offset > 0); 58 | }); 59 | 60 | function close(e) { 61 | // check if the target is not the elm children or itself(click outside elm) 62 | if (elm.contains(e.target)) return; 63 | 64 | swipeOn(false); 65 | document.removeEventListener("mouseup", close); 66 | document.removeEventListener("touchend", close); 67 | } 68 | 69 | return swipeOn; 70 | } 71 | -------------------------------------------------------------------------------- /demos/Drag/swipe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 37 | 38 | 39 | 40 |
Swipe me
41 | 42 | 43 | -------------------------------------------------------------------------------- /demos/Drag/swipe/index.js: -------------------------------------------------------------------------------- 1 | const div = document.querySelector("div"); 2 | EZG.enableDragEvents(div); 3 | 4 | const maxOffset = Math.min(200, window.innerWidth / 4); 5 | 6 | div.addEventListener("ezgdragmove", (e) => { 7 | const { offsetX } = e.detail; 8 | 9 | const p = Math.abs(offsetX) / maxOffset; 10 | div.style.transform = `translateX(${offsetX}px)`; 11 | div.style.opacity = 1 - p; 12 | }); 13 | 14 | div.addEventListener("ezgdragstop", (e) => { 15 | const { offsetX } = e.detail; 16 | 17 | div.style.transform = ""; 18 | div.style.opacity = ""; 19 | 20 | if (Math.abs(offsetX) >= maxOffset) { 21 | div.style.display = "none"; 22 | alert("Removed!"); 23 | div.style.display = ""; 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /demos/Longpress/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 43 | 44 | 45 | 46 |
47 |

Long-press

48 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /demos/Longpress/index.js: -------------------------------------------------------------------------------- 1 | const button = document.getElementById("button"); 2 | const content = document.getElementById("content"); 3 | EZG.enableLongPressEvents(button); 4 | 5 | button.addEventListener("ezglongpress", (e) => { 6 | content.hidden = false; 7 | }); 8 | -------------------------------------------------------------------------------- /demos/Pinch/rotate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demos/Pinch/rotate/sketch.js: -------------------------------------------------------------------------------- 1 | let movingTouches; 2 | let pinchDistance; 3 | let pinchAngle = 0; 4 | let centerX, centerY; 5 | let direction; 6 | 7 | function onPinchStart(e) { 8 | // 9 | console.log("started"); 10 | } 11 | 12 | function onPinchMove(e) { 13 | const { dist, touches, midX, midY, da, dir } = e.detail; 14 | 15 | movingTouches = touches; 16 | 17 | console.log("move"); 18 | 19 | pinchDistance = dist; 20 | 21 | pinchAngle += da * 2; // human wrist will break :D 22 | 23 | direction = dir; 24 | 25 | centerX = midX; 26 | centerY = midY; 27 | } 28 | 29 | function onPinchEnd() { 30 | movingTouches = undefined; 31 | } 32 | 33 | function initPinchEvents(elem) { 34 | EZG.enablePinchEvents(elem); 35 | elem.addEventListener("ezgpinchstart", onPinchStart); 36 | elem.addEventListener("ezgpinchmove", onPinchMove); 37 | elem.addEventListener("ezgpinchend", onPinchEnd); 38 | } 39 | 40 | function setup() { 41 | createCanvas(window.innerWidth, window.innerHeight / 2); 42 | initPinchEvents(drawingContext.canvas); 43 | } 44 | 45 | function getRelativePos(x, y) { 46 | let canvas = drawingContext.canvas; 47 | return [x - canvas.offsetLeft, y - canvas.offsetTop]; 48 | } 49 | 50 | function getRelativeTPos(t) { 51 | return getRelativePos(t.clientX, t.clientY); 52 | } 53 | 54 | function drawTouch(t) { 55 | const [x, y] = getRelativeTPos(t); 56 | circle(x, y, 35); 57 | } 58 | 59 | function draw() { 60 | background(0); 61 | 62 | fill(255); 63 | textSize(18); 64 | textAlign(LEFT, TOP); 65 | if (movingTouches) { 66 | const [p1, p2] = movingTouches; 67 | drawTouch(p1); 68 | drawTouch(p2); 69 | 70 | const [x1, y1] = getRelativeTPos(p1); 71 | const [x2, y2] = getRelativeTPos(p2); 72 | 73 | const [xx, yy] = getRelativePos(centerX, centerY); 74 | circle(xx, yy, 15); 75 | 76 | text(`Distance ${pinchDistance | 0}`, 0, 0); 77 | text(`Pinch ${["in", "", "out"][direction + 1]}`, 0, 18); 78 | } 79 | translate(width / 2, height / 2); 80 | rotate(pinchAngle); 81 | textAlign(CENTER, CENTER); 82 | text("Pinch and Rotate Me", 0, 0); 83 | } 84 | -------------------------------------------------------------------------------- /demos/dist/drag.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /*! ***************************************************************************** 8 | Copyright (c) Microsoft Corporation. 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************************************************** */ 21 | 22 | var __assign = function() { 23 | __assign = Object.assign || function __assign(t) { 24 | for (var s, i = 1, n = arguments.length; i < n; i++) { 25 | s = arguments[i]; 26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 27 | } 28 | return t; 29 | }; 30 | return __assign.apply(this, arguments); 31 | }; 32 | 33 | function dispatchCustomEvent(name, elm, detail, cancelable) { 34 | if (cancelable === void 0) { cancelable = true; } 35 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 36 | } 37 | 38 | var activeDraggedElement; 39 | var startX, startY; 40 | var lastX, lastY; 41 | var checkDragPos; 42 | var defaults = { 43 | threshold: 0, 44 | }; 45 | var options = new WeakMap(); 46 | function enableDragEvents(elm, opt) { 47 | if (opt === void 0) { opt = defaults; } 48 | elm.addEventListener("touchstart", onPointerDown, true); 49 | elm.addEventListener("mousedown", onPointerDown, true); 50 | options.set(elm, opt); 51 | } 52 | function getPointerPosition(e) { 53 | if (e.changedTouches) 54 | e = e.changedTouches[0]; 55 | return [e.clientX, e.clientY]; 56 | } 57 | function onPointerDown(e) { 58 | var _a; 59 | activeDraggedElement = e.currentTarget; 60 | checkDragPos = true; 61 | _a = getPointerPosition(e), startX = _a[0], startY = _a[1]; 62 | addOrRemoveEvents(); 63 | } 64 | function onPointerMove(e) { 65 | var _a, _b; 66 | e.preventDefault(); 67 | if (!activeDraggedElement) 68 | return; 69 | var _c = getPointerPosition(e), x = _c[0], y = _c[1]; 70 | if (checkDragPos) { 71 | var opt = options.get(activeDraggedElement); 72 | if (Math.hypot(x - startX, y - startY) < opt.threshold) 73 | return; 74 | checkDragPos = false; 75 | _a = [x, y], lastX = _a[0], lastY = _a[1]; 76 | if (!dispatchDragEvent("dragstart", e)) { 77 | removeDragEvents(); 78 | } 79 | } 80 | else if (dispatchDragEvent("dragmove", e)) { 81 | _b = [x, y], lastX = _b[0], lastY = _b[1]; 82 | } 83 | } 84 | function getDragPositions(e) { 85 | var _a = getPointerPosition(e), clientX = _a[0], clientY = _a[1]; 86 | return { 87 | startX: startX, 88 | startY: startY, 89 | lastX: lastX, 90 | lastY: lastY, 91 | //current mouse position 92 | clientX: clientX, 93 | clientY: clientY, 94 | // mouse delta from initial drag position 95 | offsetX: clientX - startX, 96 | offsetY: clientY - startY, 97 | // mouse delta from last drag position 98 | movementX: clientX - lastX, 99 | movementY: clientY - lastY, 100 | }; 101 | } 102 | function removeDragEvents() { 103 | activeDraggedElement = undefined; 104 | addOrRemoveEvents(true); 105 | } 106 | function onPointerUp(e) { 107 | if (activeDraggedElement && !checkDragPos) { 108 | dispatchDragEvent("dragstop", e, false); 109 | } 110 | removeDragEvents(); 111 | } 112 | function addOrRemoveEvents(remove) { 113 | if (remove === void 0) { remove = false; } 114 | var fn = remove ? "removeEventListener" : "addEventListener"; 115 | document[fn]("mouseup", onPointerUp); 116 | document[fn]("touchend", onPointerUp); 117 | document[fn]("mousemove", onPointerMove); 118 | document[fn]("touchmove", onPointerMove); 119 | } 120 | function dispatchDragEvent(name, e, cancelable) { 121 | if (cancelable === void 0) { cancelable = true; } 122 | return !dispatchCustomEvent(name, activeDraggedElement, __assign(__assign({}, getDragPositions(e)), { originalEvent: e }), cancelable); 123 | } 124 | 125 | exports.enableDragEvents = enableDragEvents; 126 | 127 | Object.defineProperty(exports, '__esModule', { value: true }); 128 | 129 | }))); 130 | //# sourceMappingURL=drag.js.map 131 | -------------------------------------------------------------------------------- /demos/dist/drag.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"drag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /demos/dist/drag.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).EZG=e.EZG||{})}(this,(function(e){"use strict";let t,n,o,c,s,u;const i={threshold:0},r=new WeakMap;function d(e){return e.changedTouches&&(e=e.changedTouches[0]),[e.clientX,e.clientY]}function f(e){t=e.currentTarget,u=!0,[n,o]=d(e),h()}function a(e){if(e.preventDefault(),!t)return;const[i,f]=d(e);if(u){const d=r.get(t);if(Math.hypot(i-n,f-o)= distanceThreshold && da >= angleThreshold) { 168 | var isCancelled = dispatchCustomEvent("pinchstart", e.currentTarget, { 169 | startTouches: startTouches, 170 | originalEvent: e, 171 | }); 172 | if (isCancelled) { 173 | e.currentTarget.removeEventListener("touchmove", onTouchMove); 174 | return; 175 | } 176 | activeElement = e.currentTarget; 177 | lastDist = startDist; 178 | lastAngle = startAngle; 179 | lastOffset = 0; 180 | checkPinch = false; 181 | document.addEventListener("touchend", onTouchEnd); 182 | } 183 | } 184 | function pinchMoveHandler(e, props) { 185 | var angle = props.angle, offset = props.offset, dist = props.dist; 186 | var isCancelled = dispatchPinchEvent("move", e.currentTarget, __assign(__assign({}, props), { originalEvent: e, touches: e.touches })); 187 | // will stop counting lastDist/Offset when cancelled 188 | if (isCancelled) 189 | return; 190 | lastDist = dist; 191 | lastAngle = angle; 192 | lastOffset = offset; 193 | } 194 | function calculatePinchProps(touches) { 195 | var p1 = touches[0], p2 = touches[1]; 196 | var dx = p1.clientX - p2.clientX; 197 | var dy = p1.clientY - p2.clientY; 198 | var dist = Math.hypot(dx, dy); 199 | var offset = dist - lastDist; 200 | var angle = Math.atan2(dy, dx); 201 | var da = angle - lastAngle; 202 | var midX = (p1.clientX + p2.clientX) / 2; 203 | var midY = (p1.clientY + p2.clientY) / 2; 204 | var dir = Math.sign(dist - (lastDist || dist)); 205 | return { dx: dx, dy: dy, da: da, dist: dist, angle: angle, offset: offset, midX: midX, midY: midY, dir: dir }; 206 | } 207 | function onTouchEnd(e) { 208 | if (!checkPinch && activeElement) { 209 | var detail = { 210 | originalEvent: e, 211 | }; 212 | dispatchPinchEvent("end", activeElement, detail, false); 213 | activeElement = undefined; 214 | } 215 | } 216 | function dispatchPinchEvent(ev, elm, detail, cancelable) { 217 | if (cancelable === void 0) { cancelable = true; } 218 | detail = __assign(__assign({}, detail), { startTouches: startTouches, 219 | lastTouches: lastTouches, 220 | lastOffset: lastOffset, 221 | lastDist: lastDist, 222 | lastAngle: lastAngle }); 223 | return dispatchCustomEvent("pinch" + ev, elm, detail, cancelable); 224 | } 225 | 226 | function enableLongPressEvents(elm, opt) { 227 | if (opt === void 0) { opt = {}; } 228 | function onPointerDown(e) { 229 | var timeout = setTimeout(function () { 230 | dispatchCustomEvent("longpress", elm, { 231 | originalEvent: e, 232 | }); 233 | }, opt.duration || 700); 234 | function onPointerUp() { 235 | clearTimeout(timeout); 236 | } 237 | var options = { once: true }; 238 | elm.addEventListener("touchend", onPointerUp, options); 239 | elm.addEventListener("mouseup", onPointerUp, options); 240 | } 241 | elm.addEventListener("touchstart", onPointerDown, true); 242 | elm.addEventListener("mousedown", onPointerDown, true); 243 | } 244 | 245 | exports.enableDragEvents = enableDragEvents; 246 | exports.enableLongPressEvents = enableLongPressEvents; 247 | exports.enablePinchEvents = enablePinchEvents; 248 | 249 | Object.defineProperty(exports, '__esModule', { value: true }); 250 | 251 | }))); 252 | //# sourceMappingURL=index.js.map 253 | -------------------------------------------------------------------------------- /demos/dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /demos/dist/index.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).EZG={})}(this,(function(e){"use strict";function t(e,t,n,o=!0){return!t.dispatchEvent(new CustomEvent(`ezg${e}`,{detail:n,cancelable:o}))}let n,o,c,s,i,r;const u={threshold:0},a=new WeakMap;function d(e){return e.changedTouches&&(e=e.changedTouches[0]),[e.clientX,e.clientY]}function l(e){n=e.currentTarget,r=!0,[o,c]=d(e),m()}function f(e){if(e.preventDefault(),!n)return;const[t,u]=d(e);if(r){const d=a.get(n);if(Math.hypot(t-o,u-c)=i&&a>=r){if(t("pinchstart",e.currentTarget,{startTouches:E,originalEvent:e}))return elm.removeEventListener("touchmove",O);T=e.currentTarget,X=c,y=s,Y=0,b=!1,document.addEventListener("touchend",x)}}(e,n):function(e,t){const{angle:n,offset:o,dist:c}=t;if(D("move",e.currentTarget,{...t,originalEvent:e,touches:e.touches}))return;X=c,y=n,Y=o}(e,n)}function j(e){const[t,n]=e,o=t.clientX-n.clientX,c=t.clientY-n.clientY,s=Math.hypot(o,c),i=s-X,r=Math.atan2(c,o);return{dx:o,dy:c,da:r-y,dist:s,angle:r,offset:i,midX:(t.clientX+n.clientX)/2,midY:(t.clientY+n.clientY)/2,dir:Math.sign(s-(X||s))}}function x(e){!b&&T&&(D("end",T,null,!1),T=void 0)}function D(e,n,o,c){return t(`pinch${e}`,n,o={...o,startTouches:E,lastTouches:undefined,lastOffset:Y,lastDist:X,lastAngle:y},c)}e.enableDragEvents=function(e,t=u){e.addEventListener("touchstart",l,!0),e.addEventListener("mousedown",l,!0),a.set(e,t)},e.enablePinchEvents=function(e,t=M){L.set(e,t),e.addEventListener("touchstart",w)},Object.defineProperty(e,"__esModule",{value:!0})})); 2 | //# sourceMappingURL=index.min.js.map 3 | -------------------------------------------------------------------------------- /demos/dist/index.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.min.js","sources":["../lib/shared.js","../lib/drag.js","../lib/pinch.js"],"sourcesContent":["export function dispatchCustomEvent(name, elm, detail, cancelable = true) {\r\n return !elm.dispatchEvent(\r\n new CustomEvent(`ezg${name}`, { detail, cancelable })\r\n );\r\n}\r\n","import { dispatchCustomEvent } from \"./shared\";\n\nlet activeDraggedElement;\nlet startX, startY;\nlet lastX, lastY;\nlet checkDragPos;\n\nconst defaults = {\n threshold: 0,\n};\n\nconst options = new WeakMap();\n\nexport function enableDragEvents(elm, opt = defaults) {\n elm.addEventListener(\"touchstart\", onPointerDown, true);\n elm.addEventListener(\"mousedown\", onPointerDown, true);\n options.set(elm, opt);\n}\n\n// create dummy mouse event object to get mouse related properties like e.clientX e.clientY, e.altKey, etc..\nconst MOUSE_EVENT_PROPS = Object.keys(\n Object.getPrototypeOf(new MouseEvent(\"\"))\n);\n\nconst TOUCH_EVENT_PROPS = [\"changedTouches\", \"touches\", \"targetTouches\"];\n\nfunction getPointerPosition(e) {\n if (e.changedTouches) e = e.changedTouches[0];\n return [e.clientX, e.clientY];\n}\n\nfunction onPointerDown(e) {\n activeDraggedElement = e.currentTarget;\n checkDragPos = true;\n\n [startX, startY] = getPointerPosition(e);\n\n addOrRemoveEvents();\n}\n\nfunction onPointerMove(e) {\n e.preventDefault();\n if (!activeDraggedElement) return;\n\n const [x, y] = getPointerPosition(e);\n\n if (checkDragPos) {\n const opt = options.get(activeDraggedElement);\n\n if (Math.hypot(x - startX, y - startY) < opt.threshold) return;\n\n checkDragPos = false;\n [lastX, lastY] = [x, y];\n\n if (!dispatchDragEvent(\"dragstart\", e)) {\n removeDragEvents();\n }\n } else if (dispatchDragEvent(\"dragmove\", e)) {\n [lastX, lastY] = [x, y];\n }\n}\n\nfunction getDragPositions(e) {\n const [clientX, clientY] = getPointerPosition(e);\n return {\n startX,\n startY,\n lastX,\n lastY,\n\n //current mouse position\n clientX,\n clientY,\n\n // mouse delta from initial drag position\n offsetX: clientX - startX,\n offsetY: clientY - startY,\n\n // mouse delta from last drag position\n movementX: clientX - lastX,\n movementY: clientY - lastY,\n };\n}\n\nfunction removeDragEvents() {\n activeDraggedElement = undefined;\n\n addOrRemoveEvents(true);\n}\n\nfunction onPointerUp(e) {\n if (activeDraggedElement && !checkDragPos) {\n dispatchDragEvent(\"dragstop\", e, false);\n }\n\n removeDragEvents();\n}\n\nfunction addOrRemoveEvents(remove) {\n const fn = remove ? \"removeEventListener\" : \"addEventListener\";\n document[fn](\"mouseup\", onPointerUp);\n document[fn](\"touchend\", onPointerUp);\n document[fn](\"mousemove\", onPointerMove);\n document[fn](\"touchmove\", onPointerMove);\n}\n\nfunction dispatchDragEvent(name, e, cancelable = true) {\n return !dispatchCustomEvent(\n name,\n activeDraggedElement,\n {\n ...getDragPositions(e),\n originalEvent: e,\n },\n cancelable\n );\n}\n","import { dispatchCustomEvent } from \"./shared\";\n\nlet startTouches;\nlet lastTouches;\n\nlet activeElement;\nlet checkPinch;\n\nlet lastDist;\nlet lastOffset;\nlet lastAngle;\n\nconst defaults = {\n distanceThreshold: 0,\n angleThreshold: 0,\n};\n\nconst options = new WeakMap();\n\nexport function enablePinchEvents(elm, opt = defaults) {\n options.set(elm, opt);\n elm.addEventListener(\"touchstart\", onTouchStart);\n}\n\nfunction onTouchStart(e) {\n startTouches = e.touches;\n checkPinch = true;\n e.currentTarget.addEventListener(\"touchmove\", onTouchMove);\n}\n\nfunction onTouchMove(e) {\n e.preventDefault();\n if (e.touches.length != 2) return;\n\n const props = calculatePinchProps(e.touches);\n\n if (checkPinch) {\n pinchStartHandler(e, props);\n } else {\n pinchMoveHandler(e, props);\n }\n}\n\nfunction pinchStartHandler(e, { dist, angle }) {\n if (startTouches.length != 2) return;\n const { dist: startDist, angle: startAngle } = calculatePinchProps(\n startTouches\n );\n\n const { distanceThreshold, angleThreshold } = options.get(e.currentTarget);\n\n const dd = Math.abs(dist - startDist);\n const da = Math.abs(angle - startAngle);\n\n if (dd >= distanceThreshold && da >= angleThreshold) {\n const isCancelled = dispatchCustomEvent(\"pinchstart\", e.currentTarget, {\n startTouches,\n originalEvent: e,\n });\n\n if (isCancelled) {\n return elm.removeEventListener(\"touchmove\", onTouchMove);\n }\n\n activeElement = e.currentTarget;\n lastDist = startDist;\n lastAngle = startAngle;\n lastOffset = 0;\n checkPinch = false;\n document.addEventListener(\"touchend\", onTouchEnd);\n }\n}\n\nfunction pinchMoveHandler(e, props) {\n const { angle, offset, dist } = props;\n const isCancelled = dispatchPinchEvent(\"move\", e.currentTarget, {\n ...props,\n originalEvent: e,\n touches: e.touches,\n });\n\n // will stop counting lastDist/Offset when cancelled\n if (isCancelled) return;\n\n lastDist = dist;\n lastAngle = angle;\n lastOffset = offset;\n}\n\nfunction calculatePinchProps(touches) {\n const [p1, p2] = touches;\n\n const dx = p1.clientX - p2.clientX;\n const dy = p1.clientY - p2.clientY;\n\n const dist = Math.hypot(dx, dy);\n const offset = dist - lastDist;\n\n const angle = Math.atan2(dy, dx);\n const da = angle - lastAngle;\n\n const midX = (p1.clientX + p2.clientX) / 2;\n const midY = (p1.clientY + p2.clientY) / 2;\n\n const dir = Math.sign(dist - (lastDist || dist));\n\n return { dx, dy, da, dist, angle, offset, midX, midY, dir };\n}\n\nfunction onTouchEnd(e) {\n if (!checkPinch && activeElement) {\n dispatchPinchEvent(\"end\", activeElement, null, false);\n activeElement = undefined;\n }\n}\n\nfunction dispatchPinchEvent(ev, elm, detail, cancelable) {\n detail = {\n ...detail,\n startTouches,\n lastTouches,\n lastOffset,\n lastDist,\n lastAngle,\n };\n return dispatchCustomEvent(`pinch${ev}`, elm, detail, cancelable);\n}\n"],"names":["dispatchCustomEvent","name","elm","detail","cancelable","dispatchEvent","CustomEvent","activeDraggedElement","startX","startY","lastX","lastY","checkDragPos","defaults","threshold","options","WeakMap","getPointerPosition","e","changedTouches","clientX","clientY","onPointerDown","currentTarget","addOrRemoveEvents","onPointerMove","preventDefault","x","y","opt","get","Math","hypot","dispatchDragEvent","removeDragEvents","getDragPositions","offsetX","offsetY","movementX","movementY","undefined","onPointerUp","remove","fn","document","originalEvent","startTouches","activeElement","checkPinch","lastDist","lastOffset","lastAngle","Object","keys","getPrototypeOf","MouseEvent","distanceThreshold","angleThreshold","onTouchStart","touches","addEventListener","onTouchMove","length","props","calculatePinchProps","dist","angle","startDist","startAngle","dd","abs","da","removeEventListener","onTouchEnd","pinchStartHandler","offset","dispatchPinchEvent","pinchMoveHandler","p1","p2","dx","dy","atan2","midX","midY","dir","sign","ev","lastTouches","set"],"mappings":"2OAAO,SAASA,EAAoBC,EAAMC,EAAKC,EAAQC,GAAa,GAChE,OAAQF,EAAIG,cACR,IAAIC,YAAY,MAAML,IAAQ,CAAEE,OAAAA,EAAQC,WAAAA,KCAhD,IAAIG,EACAC,EAAQC,EACRC,EAAOC,EACPC,EAEJ,MAAMC,EAAW,CACbC,UAAW,GAGTC,EAAU,IAAIC,QAepB,SAASC,EAAmBC,GAExB,OADIA,EAAEC,iBAAgBD,EAAIA,EAAEC,eAAe,IACpC,CAACD,EAAEE,QAASF,EAAEG,SAGzB,SAASC,EAAcJ,GACnBX,EAAuBW,EAAEK,cACzBX,GAAe,GAEdJ,EAAQC,GAAUQ,EAAmBC,GAEtCM,IAGJ,SAASC,EAAcP,GAEnB,GADAA,EAAEQ,kBACGnB,EAAsB,OAE3B,MAAOoB,EAAGC,GAAKX,EAAmBC,GAElC,GAAIN,EAAc,CACd,MAAMiB,EAAMd,EAAQe,IAAIvB,GAExB,GAAIwB,KAAKC,MAAML,EAAInB,EAAQoB,EAAInB,GAAUoB,EAAIf,UAAW,OAExDF,GAAe,GACdF,EAAOC,GAAS,CAACgB,EAAGC,GAEhBK,EAAkB,YAAaf,IAChCgB,SAEGD,EAAkB,WAAYf,MACpCR,EAAOC,GAAS,CAACgB,EAAGC,IAI7B,SAASO,EAAiBjB,GACtB,MAAOE,EAASC,GAAWJ,EAAmBC,GAC9C,MAAO,CACHV,OAAAA,EACAC,OAAAA,EACAC,MAAAA,EACAC,MAAAA,EAGAS,QAAAA,EACAC,QAAAA,EAGAe,QAAShB,EAAUZ,EACnB6B,QAAShB,EAAUZ,EAGnB6B,UAAWlB,EAAUV,EACrB6B,UAAWlB,EAAUV,GAI7B,SAASuB,IACL3B,OAAuBiC,EAEvBhB,GAAkB,GAGtB,SAASiB,EAAYvB,GACbX,IAAyBK,GACzBqB,EAAkB,WAAYf,GAAG,GAGrCgB,IAGJ,SAASV,EAAkBkB,GACvB,MAAMC,EAAKD,EAAS,sBAAwB,mBAC5CE,SAASD,GAAI,UAAWF,GACxBG,SAASD,GAAI,WAAYF,GACzBG,SAASD,GAAI,YAAalB,GAC1BmB,SAASD,GAAI,YAAalB,GAG9B,SAASQ,EAAkBhC,EAAMiB,EAAGd,GAAa,GAC7C,OAAQJ,EACJC,EACAM,EACA,IACO4B,EAAiBjB,GACpB2B,cAAe3B,GAEnBd,GChHR,IAAI0C,EAGAC,EACAC,EAEAC,EACAC,EACAC,EDUsBC,OAAOC,KAC7BD,OAAOE,eAAe,IAAIC,WAAW,MCTzC,MAAM1C,EAAW,CACb2C,kBAAmB,EACnBC,eAAgB,GAGd1C,EAAU,IAAIC,QAOpB,SAAS0C,EAAaxC,GAClB4B,EAAe5B,EAAEyC,QACjBX,GAAa,EACb9B,EAAEK,cAAcqC,iBAAiB,YAAaC,GAGlD,SAASA,EAAY3C,GAEjB,GADAA,EAAEQ,iBACsB,GAApBR,EAAEyC,QAAQG,OAAa,OAE3B,MAAMC,EAAQC,EAAoB9C,EAAEyC,SAEhCX,EAOR,SAA2B9B,GAAG+C,KAAEA,EAAIC,MAAEA,IAClC,GAA2B,GAAvBpB,EAAagB,OAAa,OAC9B,MAAQG,KAAME,EAAWD,MAAOE,GAAeJ,EAC3ClB,IAGEU,kBAAEA,EAAiBC,eAAEA,GAAmB1C,EAAQe,IAAIZ,EAAEK,eAEtD8C,EAAKtC,KAAKuC,IAAIL,EAAOE,GACrBI,EAAKxC,KAAKuC,IAAIJ,EAAQE,GAE5B,GAAIC,GAAMb,GAAqBe,GAAMd,EAAgB,CAMjD,GALoBzD,EAAoB,aAAckB,EAAEK,cAAe,CACnEuB,aAAAA,EACAD,cAAe3B,IAIf,OAAOhB,IAAIsE,oBAAoB,YAAaX,GAGhDd,EAAgB7B,EAAEK,cAClB0B,EAAWkB,EACXhB,EAAYiB,EACZlB,EAAa,EACbF,GAAa,EACbJ,SAASgB,iBAAiB,WAAYa,IAhCtCC,CAAkBxD,EAAG6C,GAoC7B,SAA0B7C,EAAG6C,GACzB,MAAMG,MAAEA,EAAKS,OAAEA,EAAMV,KAAEA,GAASF,EAQhC,GAPoBa,EAAmB,OAAQ1D,EAAEK,cAAe,IACzDwC,EACHlB,cAAe3B,EACfyC,QAASzC,EAAEyC,UAIE,OAEjBV,EAAWgB,EACXd,EAAYe,EACZhB,EAAayB,EA/CTE,CAAiB3D,EAAG6C,GAkD5B,SAASC,EAAoBL,GACzB,MAAOmB,EAAIC,GAAMpB,EAEXqB,EAAKF,EAAG1D,QAAU2D,EAAG3D,QACrB6D,EAAKH,EAAGzD,QAAU0D,EAAG1D,QAErB4C,EAAOlC,KAAKC,MAAMgD,EAAIC,GACtBN,EAASV,EAAOhB,EAEhBiB,EAAQnC,KAAKmD,MAAMD,EAAID,GAQ7B,MAAO,CAAEA,GAAAA,EAAIC,GAAAA,EAAIV,GAPNL,EAAQf,EAOEc,KAAAA,EAAMC,MAAAA,EAAOS,OAAAA,EAAQQ,MAL5BL,EAAG1D,QAAU2D,EAAG3D,SAAW,EAKOgE,MAJlCN,EAAGzD,QAAU0D,EAAG1D,SAAW,EAIagE,IAF1CtD,KAAKuD,KAAKrB,GAAQhB,GAAYgB,KAK9C,SAASQ,EAAWvD,IACX8B,GAAcD,IACf6B,EAAmB,MAAO7B,EAAe,MAAM,GAC/CA,OAAgBP,GAIxB,SAASoC,EAAmBW,EAAIrF,EAAKC,EAAQC,GASzC,OAAOJ,EAAoB,QAAQuF,IAAMrF,EARzCC,EAAS,IACFA,EACH2C,aAAAA,EACA0C,YArHJA,UAsHItC,WAAAA,EACAD,SAAAA,EACAE,UAAAA,GAEkD/C,sBDhHnD,SAA0BF,EAAK2B,EAAMhB,GACxCX,EAAI0D,iBAAiB,aAActC,GAAe,GAClDpB,EAAI0D,iBAAiB,YAAatC,GAAe,GACjDP,EAAQ0E,IAAIvF,EAAK2B,wBCGd,SAA2B3B,EAAK2B,EAAMhB,GACzCE,EAAQ0E,IAAIvF,EAAK2B,GACjB3B,EAAI0D,iBAAiB,aAAcF"} -------------------------------------------------------------------------------- /demos/dist/interfaces.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /demos/dist/longpress.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | function dispatchCustomEvent(name, elm, detail, cancelable) { 8 | if (cancelable === void 0) { cancelable = true; } 9 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 10 | } 11 | 12 | function enableLongPressEvents(elm, opt) { 13 | if (opt === void 0) { opt = {}; } 14 | function onPointerDown(e) { 15 | var timeout = setTimeout(function () { 16 | dispatchCustomEvent("longpress", elm, { 17 | originalEvent: e, 18 | }); 19 | }, opt.duration || 700); 20 | function onPointerUp() { 21 | clearTimeout(timeout); 22 | } 23 | var options = { once: true }; 24 | elm.addEventListener("touchend", onPointerUp, options); 25 | elm.addEventListener("mouseup", onPointerUp, options); 26 | } 27 | elm.addEventListener("touchstart", onPointerDown, true); 28 | elm.addEventListener("mousedown", onPointerDown, true); 29 | } 30 | 31 | exports.enableLongPressEvents = enableLongPressEvents; 32 | 33 | Object.defineProperty(exports, '__esModule', { value: true }); 34 | 35 | }))); 36 | //# sourceMappingURL=longpress.js.map 37 | -------------------------------------------------------------------------------- /demos/dist/longpress.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"longpress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /demos/dist/longpress.min.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === "object" && typeof module !== "undefined" 3 | ? factory(exports) 4 | : typeof define === "function" && define.amd 5 | ? define(["exports"], factory) 6 | : ((global = 7 | typeof globalThis !== "undefined" ? globalThis : global || self), 8 | factory((global.EZG = global.EZG || {}))); 9 | })(this, function (exports) { 10 | "use strict"; 11 | 12 | function dispatchCustomEvent(name, elm, detail, cancelable = true) { 13 | return !elm.dispatchEvent( 14 | new CustomEvent(`ezg${name}`, { detail, cancelable }) 15 | ); 16 | } 17 | 18 | function enableLongPressEvents(elm, opt = {}) { 19 | function onPointerDown(e) { 20 | const timeout = setTimeout(() => { 21 | dispatchCustomEvent("longpress", elm, { 22 | originalEvent: e, 23 | }); 24 | }, opt.duration || 700); 25 | 26 | function onPointerUp() { 27 | clearTimeout(timeout); 28 | } 29 | 30 | const options = { once: true }; 31 | elm.addEventListener("touchend", onPointerUp, options); 32 | elm.addEventListener("mouseup", onPointerUp, options); 33 | } 34 | elm.addEventListener("touchstart", onPointerDown, true); 35 | elm.addEventListener("mousedown", onPointerDown, true); 36 | } 37 | 38 | exports.enableLongPressEvents = enableLongPressEvents; 39 | 40 | Object.defineProperty(exports, "__esModule", { value: true }); 41 | }); 42 | //# sourceMappingURL=longpress.min.js.map 43 | -------------------------------------------------------------------------------- /demos/dist/longpress.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"longpress.min.js","sources":["../lib/shared.js","../lib/longpress.js"],"sourcesContent":["export function dispatchCustomEvent(name, elm, detail, cancelable = true) {\r\n return !elm.dispatchEvent(\r\n new CustomEvent(`ezg${name}`, { detail, cancelable })\r\n );\r\n}\r\n","import { dispatchCustomEvent } from \"./shared\";\r\n\r\nexport function enableLongPressEvents(elm, opt = {}) {\r\n function onPointerDown(e) {\r\n const timeout = setTimeout(() => {\r\n dispatchCustomEvent(\"longpress\", elm, {\r\n originalEvent: e,\r\n });\r\n }, opt.duration || 700);\r\n\r\n function onPointerUp() {\r\n clearTimeout(timeout);\r\n }\r\n\r\n const options = { once: true };\r\n elm.addEventListener(\"touchend\", onPointerUp, options);\r\n elm.addEventListener(\"mouseup\", onPointerUp, options);\r\n }\r\n elm.addEventListener(\"touchstart\", onPointerDown, true);\r\n elm.addEventListener(\"mousedown\", onPointerDown, true);\r\n}\r\n"],"names":[],"mappings":";;;;;;IAAO,SAAS,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE;IAC1E,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;IAC7B,QAAQ,IAAI,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC7D,KAAK,CAAC;IACN;;ICFO,SAAS,qBAAqB,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;IACrD,IAAI,SAAS,aAAa,CAAC,CAAC,EAAE;IAC9B,QAAQ,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM;IACzC,YAAY,mBAAmB,CAAC,WAAW,EAAE,GAAG,EAAE;IAClD,gBAAgB,aAAa,EAAE,CAAC;IAChC,aAAa,CAAC,CAAC;IACf,SAAS,EAAE,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;AAChC;IACA,QAAQ,SAAS,WAAW,GAAG;IAC/B,YAAY,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,SAAS;AACT;IACA,QAAQ,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACvC,QAAQ,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/D,QAAQ,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9D,KAAK;IACL,IAAI,GAAG,CAAC,gBAAgB,CAAC,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IAC3D;;;;;;;;;;"} -------------------------------------------------------------------------------- /demos/dist/pinch.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /*! ***************************************************************************** 8 | Copyright (c) Microsoft Corporation. 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************************************************** */ 21 | 22 | var __assign = function() { 23 | __assign = Object.assign || function __assign(t) { 24 | for (var s, i = 1, n = arguments.length; i < n; i++) { 25 | s = arguments[i]; 26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 27 | } 28 | return t; 29 | }; 30 | return __assign.apply(this, arguments); 31 | }; 32 | 33 | function dispatchCustomEvent(name, elm, detail, cancelable) { 34 | if (cancelable === void 0) { cancelable = true; } 35 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 36 | } 37 | 38 | var startTouches; 39 | var lastTouches; 40 | var activeElement; 41 | var checkPinch; 42 | var lastDist; 43 | var lastOffset; 44 | var lastAngle; 45 | var defaults = { 46 | distanceThreshold: 0, 47 | angleThreshold: 0, 48 | }; 49 | var options = new WeakMap(); 50 | function enablePinchEvents(elm, opt) { 51 | if (opt === void 0) { opt = defaults; } 52 | options.set(elm, opt); 53 | elm.addEventListener("touchstart", onTouchStart); 54 | } 55 | function onTouchStart(e) { 56 | startTouches = e.touches; 57 | checkPinch = true; 58 | this.addEventListener("touchmove", onTouchMove); 59 | } 60 | function onTouchMove(e) { 61 | e.preventDefault(); 62 | if (e.touches.length != 2) 63 | return; 64 | var props = calculatePinchProps(e.touches); 65 | if (checkPinch) { 66 | pinchStartHandler(e, props); 67 | } 68 | else { 69 | pinchMoveHandler(e, props); 70 | } 71 | } 72 | function pinchStartHandler(e, _a) { 73 | var dist = _a.dist, angle = _a.angle; 74 | if (startTouches.length != 2) 75 | return; 76 | var _b = calculatePinchProps(startTouches), startDist = _b.dist, startAngle = _b.angle; 77 | var _c = options.get(e.currentTarget), distanceThreshold = _c.distanceThreshold, angleThreshold = _c.angleThreshold; 78 | var dd = Math.abs(dist - startDist); 79 | var da = Math.abs(angle - startAngle); 80 | if (dd >= distanceThreshold && da >= angleThreshold) { 81 | var isCancelled = dispatchCustomEvent("pinchstart", e.currentTarget, { 82 | startTouches: startTouches, 83 | originalEvent: e, 84 | }); 85 | if (isCancelled) { 86 | e.currentTarget.removeEventListener("touchmove", onTouchMove); 87 | return; 88 | } 89 | activeElement = e.currentTarget; 90 | lastDist = startDist; 91 | lastAngle = startAngle; 92 | lastOffset = 0; 93 | checkPinch = false; 94 | document.addEventListener("touchend", onTouchEnd); 95 | } 96 | } 97 | function pinchMoveHandler(e, props) { 98 | var angle = props.angle, offset = props.offset, dist = props.dist; 99 | var isCancelled = dispatchPinchEvent("move", e.currentTarget, __assign(__assign({}, props), { originalEvent: e, touches: e.touches })); 100 | // will stop counting lastDist/Offset when cancelled 101 | if (isCancelled) 102 | return; 103 | lastDist = dist; 104 | lastAngle = angle; 105 | lastOffset = offset; 106 | } 107 | function calculatePinchProps(touches) { 108 | var p1 = touches[0], p2 = touches[1]; 109 | var dx = p1.clientX - p2.clientX; 110 | var dy = p1.clientY - p2.clientY; 111 | var dist = Math.hypot(dx, dy); 112 | var offset = dist - lastDist; 113 | var angle = Math.atan2(dy, dx); 114 | var da = angle - lastAngle; 115 | var midX = (p1.clientX + p2.clientX) / 2; 116 | var midY = (p1.clientY + p2.clientY) / 2; 117 | var dir = Math.sign(dist - (lastDist || dist)); 118 | return { dx: dx, dy: dy, da: da, dist: dist, angle: angle, offset: offset, midX: midX, midY: midY, dir: dir }; 119 | } 120 | function onTouchEnd(e) { 121 | if (!checkPinch && activeElement) { 122 | var detail = { 123 | originalEvent: e, 124 | }; 125 | dispatchPinchEvent("end", activeElement, detail, false); 126 | activeElement = undefined; 127 | } 128 | } 129 | function dispatchPinchEvent(ev, elm, detail, cancelable) { 130 | if (cancelable === void 0) { cancelable = true; } 131 | detail = __assign(__assign({}, detail), { startTouches: startTouches, 132 | lastTouches: lastTouches, 133 | lastOffset: lastOffset, 134 | lastDist: lastDist, 135 | lastAngle: lastAngle }); 136 | return dispatchCustomEvent("pinch" + ev, elm, detail, cancelable); 137 | } 138 | 139 | exports.enablePinchEvents = enablePinchEvents; 140 | 141 | Object.defineProperty(exports, '__esModule', { value: true }); 142 | 143 | }))); 144 | //# sourceMappingURL=pinch.js.map 145 | -------------------------------------------------------------------------------- /demos/dist/pinch.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"pinch.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /demos/dist/pinch.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).EZG=e.EZG||{})}(this,(function(e){"use strict";function t(e,t,n,i=!0){return!t.dispatchEvent(new CustomEvent(`ezg${e}`,{detail:n,cancelable:i}))}let n,i,o,s,c,r;const a={distanceThreshold:0,angleThreshold:0},u=new WeakMap;function l(e){n=e.touches,o=!0,e.currentTarget.addEventListener("touchmove",d)}function d(e){if(e.preventDefault(),2!=e.touches.length)return;const a=f(e.touches);o?function(e,{dist:a,angle:l}){if(2!=n.length)return;const{dist:g,angle:v}=f(n),{distanceThreshold:p,angleThreshold:T}=u.get(e.currentTarget),m=Math.abs(a-g),E=Math.abs(l-v);if(m>=p&&E>=T){if(t("pinchstart",e.currentTarget,{startTouches:n,originalEvent:e}))return elm.removeEventListener("touchmove",d);i=e.currentTarget,s=g,r=v,c=0,o=!1,document.addEventListener("touchend",h)}}(e,a):function(e,t){const{angle:n,offset:i,dist:o}=t;if(g("move",e.currentTarget,{...t,originalEvent:e,touches:e.touches}))return;s=o,r=n,c=i}(e,a)}function f(e){const[t,n]=e,i=t.clientX-n.clientX,o=t.clientY-n.clientY,c=Math.hypot(i,o),a=c-s,u=Math.atan2(o,i);return{dx:i,dy:o,da:u-r,dist:c,angle:u,offset:a,midX:(t.clientX+n.clientX)/2,midY:(t.clientY+n.clientY)/2,dir:Math.sign(c-(s||c))}}function h(e){!o&&i&&(g("end",i,null,!1),i=void 0)}function g(e,i,o,a){return t(`pinch${e}`,i,o={...o,startTouches:n,lastTouches:undefined,lastOffset:c,lastDist:s,lastAngle:r},a)}e.enablePinchEvents=function(e,t=a){u.set(e,t),e.addEventListener("touchstart",l)},Object.defineProperty(e,"__esModule",{value:!0})})); 2 | //# sourceMappingURL=pinch.min.js.map 3 | -------------------------------------------------------------------------------- /demos/dist/pinch.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"pinch.min.js","sources":["../lib/shared.js","../lib/pinch.js"],"sourcesContent":["export function dispatchCustomEvent(name, elm, detail, cancelable = true) {\r\n return !elm.dispatchEvent(\r\n new CustomEvent(`ezg${name}`, { detail, cancelable })\r\n );\r\n}\r\n","import { dispatchCustomEvent } from \"./shared\";\n\nlet startTouches;\nlet lastTouches;\n\nlet activeElement;\nlet checkPinch;\n\nlet lastDist;\nlet lastOffset;\nlet lastAngle;\n\nconst defaults = {\n distanceThreshold: 0,\n angleThreshold: 0,\n};\n\nconst options = new WeakMap();\n\nexport function enablePinchEvents(elm, opt = defaults) {\n options.set(elm, opt);\n elm.addEventListener(\"touchstart\", onTouchStart);\n}\n\nfunction onTouchStart(e) {\n startTouches = e.touches;\n checkPinch = true;\n e.currentTarget.addEventListener(\"touchmove\", onTouchMove);\n}\n\nfunction onTouchMove(e) {\n e.preventDefault();\n if (e.touches.length != 2) return;\n\n const props = calculatePinchProps(e.touches);\n\n if (checkPinch) {\n pinchStartHandler(e, props);\n } else {\n pinchMoveHandler(e, props);\n }\n}\n\nfunction pinchStartHandler(e, { dist, angle }) {\n if (startTouches.length != 2) return;\n const { dist: startDist, angle: startAngle } = calculatePinchProps(\n startTouches\n );\n\n const { distanceThreshold, angleThreshold } = options.get(e.currentTarget);\n\n const dd = Math.abs(dist - startDist);\n const da = Math.abs(angle - startAngle);\n\n if (dd >= distanceThreshold && da >= angleThreshold) {\n const isCancelled = dispatchCustomEvent(\"pinchstart\", e.currentTarget, {\n startTouches,\n originalEvent: e,\n });\n\n if (isCancelled) {\n return elm.removeEventListener(\"touchmove\", onTouchMove);\n }\n\n activeElement = e.currentTarget;\n lastDist = startDist;\n lastAngle = startAngle;\n lastOffset = 0;\n checkPinch = false;\n document.addEventListener(\"touchend\", onTouchEnd);\n }\n}\n\nfunction pinchMoveHandler(e, props) {\n const { angle, offset, dist } = props;\n const isCancelled = dispatchPinchEvent(\"move\", e.currentTarget, {\n ...props,\n originalEvent: e,\n touches: e.touches,\n });\n\n // will stop counting lastDist/Offset when cancelled\n if (isCancelled) return;\n\n lastDist = dist;\n lastAngle = angle;\n lastOffset = offset;\n}\n\nfunction calculatePinchProps(touches) {\n const [p1, p2] = touches;\n\n const dx = p1.clientX - p2.clientX;\n const dy = p1.clientY - p2.clientY;\n\n const dist = Math.hypot(dx, dy);\n const offset = dist - lastDist;\n\n const angle = Math.atan2(dy, dx);\n const da = angle - lastAngle;\n\n const midX = (p1.clientX + p2.clientX) / 2;\n const midY = (p1.clientY + p2.clientY) / 2;\n\n const dir = Math.sign(dist - (lastDist || dist));\n\n return { dx, dy, da, dist, angle, offset, midX, midY, dir };\n}\n\nfunction onTouchEnd(e) {\n if (!checkPinch && activeElement) {\n dispatchPinchEvent(\"end\", activeElement, null, false);\n activeElement = undefined;\n }\n}\n\nfunction dispatchPinchEvent(ev, elm, detail, cancelable) {\n detail = {\n ...detail,\n startTouches,\n lastTouches,\n lastOffset,\n lastDist,\n lastAngle,\n };\n return dispatchCustomEvent(`pinch${ev}`, elm, detail, cancelable);\n}\n"],"names":["dispatchCustomEvent","name","elm","detail","cancelable","dispatchEvent","CustomEvent","startTouches","activeElement","checkPinch","lastDist","lastOffset","lastAngle","defaults","distanceThreshold","angleThreshold","options","WeakMap","onTouchStart","e","touches","currentTarget","addEventListener","onTouchMove","preventDefault","length","props","calculatePinchProps","dist","angle","startDist","startAngle","get","dd","Math","abs","da","originalEvent","removeEventListener","document","onTouchEnd","pinchStartHandler","offset","dispatchPinchEvent","pinchMoveHandler","p1","p2","dx","clientX","dy","clientY","hypot","atan2","midX","midY","dir","sign","undefined","ev","lastTouches","opt","set"],"mappings":"kPAAO,SAASA,EAAoBC,EAAMC,EAAKC,EAAQC,GAAa,GAChE,OAAQF,EAAIG,cACR,IAAIC,YAAY,MAAML,IAAQ,CAAEE,OAAAA,EAAQC,WAAAA,KCAhD,IAAIG,EAGAC,EACAC,EAEAC,EACAC,EACAC,EAEJ,MAAMC,EAAW,CACbC,kBAAmB,EACnBC,eAAgB,GAGdC,EAAU,IAAIC,QAOpB,SAASC,EAAaC,GAClBZ,EAAeY,EAAEC,QACjBX,GAAa,EACbU,EAAEE,cAAcC,iBAAiB,YAAaC,GAGlD,SAASA,EAAYJ,GAEjB,GADAA,EAAEK,iBACsB,GAApBL,EAAEC,QAAQK,OAAa,OAE3B,MAAMC,EAAQC,EAAoBR,EAAEC,SAEhCX,EAOR,SAA2BU,GAAGS,KAAEA,EAAIC,MAAEA,IAClC,GAA2B,GAAvBtB,EAAakB,OAAa,OAC9B,MAAQG,KAAME,EAAWD,MAAOE,GAAeJ,EAC3CpB,IAGEO,kBAAEA,EAAiBC,eAAEA,GAAmBC,EAAQgB,IAAIb,EAAEE,eAEtDY,EAAKC,KAAKC,IAAIP,EAAOE,GACrBM,EAAKF,KAAKC,IAAIN,EAAQE,GAE5B,GAAIE,GAAMnB,GAAqBsB,GAAMrB,EAAgB,CAMjD,GALoBf,EAAoB,aAAcmB,EAAEE,cAAe,CACnEd,aAAAA,EACA8B,cAAelB,IAIf,OAAOjB,IAAIoC,oBAAoB,YAAaf,GAGhDf,EAAgBW,EAAEE,cAClBX,EAAWoB,EACXlB,EAAYmB,EACZpB,EAAa,EACbF,GAAa,EACb8B,SAASjB,iBAAiB,WAAYkB,IAhCtCC,CAAkBtB,EAAGO,GAoC7B,SAA0BP,EAAGO,GACzB,MAAMG,MAAEA,EAAKa,OAAEA,EAAMd,KAAEA,GAASF,EAQhC,GAPoBiB,EAAmB,OAAQxB,EAAEE,cAAe,IACzDK,EACHW,cAAelB,EACfC,QAASD,EAAEC,UAIE,OAEjBV,EAAWkB,EACXhB,EAAYiB,EACZlB,EAAa+B,EA/CTE,CAAiBzB,EAAGO,GAkD5B,SAASC,EAAoBP,GACzB,MAAOyB,EAAIC,GAAM1B,EAEX2B,EAAKF,EAAGG,QAAUF,EAAGE,QACrBC,EAAKJ,EAAGK,QAAUJ,EAAGI,QAErBtB,EAAOM,KAAKiB,MAAMJ,EAAIE,GACtBP,EAASd,EAAOlB,EAEhBmB,EAAQK,KAAKkB,MAAMH,EAAIF,GAQ7B,MAAO,CAAEA,GAAAA,EAAIE,GAAAA,EAAIb,GAPNP,EAAQjB,EAOEgB,KAAAA,EAAMC,MAAAA,EAAOa,OAAAA,EAAQW,MAL5BR,EAAGG,QAAUF,EAAGE,SAAW,EAKOM,MAJlCT,EAAGK,QAAUJ,EAAGI,SAAW,EAIaK,IAF1CrB,KAAKsB,KAAK5B,GAAQlB,GAAYkB,KAK9C,SAASY,EAAWrB,IACXV,GAAcD,IACfmC,EAAmB,MAAOnC,EAAe,MAAM,GAC/CA,OAAgBiD,GAIxB,SAASd,EAAmBe,EAAIxD,EAAKC,EAAQC,GASzC,OAAOJ,EAAoB,QAAQ0D,IAAMxD,EARzCC,EAAS,IACFA,EACHI,aAAAA,EACAoD,YArHJA,UAsHIhD,WAAAA,EACAD,SAAAA,EACAE,UAAAA,GAEkDR,uBA1GnD,SAA2BF,EAAK0D,EAAM/C,GACzCG,EAAQ6C,IAAI3D,EAAK0D,GACjB1D,EAAIoB,iBAAiB,aAAcJ"} -------------------------------------------------------------------------------- /demos/dist/shared.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.dispatchCustomEvent = void 0; 4 | function dispatchCustomEvent(name, elm, detail, cancelable) { 5 | if (cancelable === void 0) { cancelable = true; } 6 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 7 | } 8 | exports.dispatchCustomEvent = dispatchCustomEvent; 9 | -------------------------------------------------------------------------------- /demos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
Loading...
17 | 18 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /demos/index.js: -------------------------------------------------------------------------------- 1 | const nav = document.getElementById("nav"); 2 | const iframe = document.querySelector("iframe"); 3 | const loading = document.getElementById("loading"); 4 | const demos = [ 5 | ["Drag", "Drag/dragElement/index.html"], 6 | ["Paint", "Drag/paint/index.html"], 7 | ["Swipe", "Drag/swipe/index.html"], 8 | ["Swipe to reveal", "Drag/reveal/index.html"], 9 | ["Longpress", "Longpress/index.html"], 10 | ["Pinch", "Pinch/rotate/index.html"], 11 | ]; 12 | 13 | iframe.onload = function () { 14 | loading.style.display = "none"; 15 | iframe.style.opacity = 1; 16 | }; 17 | 18 | let active; 19 | window.onhashchange = function () { 20 | loading.style.display = ""; 21 | iframe.style.opacity = 0; // hiding iframe cause issues with sizing 22 | 23 | const current = decodeURIComponent(location.hash.slice(1)); 24 | const route = demos.find((v) => v[0] == current) || demos[0]; 25 | 26 | iframe.src = route[1]; 27 | console.log(active, active && active.offsetLeft); 28 | 29 | if (active) { 30 | active.classList.remove("active"); 31 | _scrollLeft = active.offsetLeft; 32 | } 33 | 34 | active = route[2]; 35 | active.classList.add("active"); 36 | nav.scrollTo({ 37 | top: 0, 38 | left: active.offsetLeft, 39 | behavior: "smooth", 40 | }); 41 | }; 42 | 43 | demos.forEach((v, i) => { 44 | const a = document.createElement("a"); 45 | a.href = `#${v[0]}`; 46 | a.textContent = v[0]; 47 | nav.appendChild(a); 48 | demos[i].push(a); 49 | }); 50 | 51 | window.onhashchange(); 52 | -------------------------------------------------------------------------------- /demos/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | touch-action: none; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 5 | 6 | background: #333; 7 | color: #ccc; 8 | 9 | display: flex; 10 | } 11 | 12 | 13 | * { 14 | box-sizing: border-box; 15 | } 16 | 17 | main { 18 | width: 100vw; 19 | height: 100vh; 20 | display: flex; 21 | flex-direction: column; 22 | } 23 | 24 | 25 | nav { 26 | display: flex; 27 | position: relative; 28 | flex-direction: column; 29 | align-items: center; 30 | background: #444; 31 | font-size: max(1.3vw, 12pt); 32 | overflow: auto;; 33 | } 34 | 35 | nav a { 36 | display: flex; 37 | align-items: center; 38 | width: 100%; 39 | cursor: pointer; 40 | color: rgb(228, 93, 93); 41 | text-decoration: none; 42 | padding: 1em; 43 | } 44 | 45 | nav a:hover, nav a.active { 46 | background: #555555; 47 | 48 | } 49 | 50 | iframe { 51 | height: 100%; 52 | } 53 | 54 | footer { 55 | /* position: absolute; */ 56 | bottom: 0; 57 | padding: 1em; 58 | width: 100%; 59 | text-align: center; 60 | } 61 | 62 | footer a { 63 | color: #ccc; 64 | text-decoration: none; 65 | } 66 | 67 | @media only screen and (max-width: 600px) { 68 | body { 69 | flex-direction: column; 70 | } 71 | 72 | nav { 73 | flex-direction: row; 74 | align-items: stretch; 75 | } 76 | 77 | nav a { 78 | flex: 0 0 8em; 79 | justify-content: center; 80 | } 81 | } -------------------------------------------------------------------------------- /dist/drag.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /*! ***************************************************************************** 8 | Copyright (c) Microsoft Corporation. 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************************************************** */ 21 | 22 | var __assign = function() { 23 | __assign = Object.assign || function __assign(t) { 24 | for (var s, i = 1, n = arguments.length; i < n; i++) { 25 | s = arguments[i]; 26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 27 | } 28 | return t; 29 | }; 30 | return __assign.apply(this, arguments); 31 | }; 32 | 33 | function dispatchCustomEvent(name, elm, detail, cancelable) { 34 | if (cancelable === void 0) { cancelable = true; } 35 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 36 | } 37 | 38 | var activeDraggedElement; 39 | var startX, startY; 40 | var lastX, lastY; 41 | var checkDragPos; 42 | var defaults = { 43 | threshold: 0, 44 | }; 45 | var options = new WeakMap(); 46 | function enableDragEvents(elm, opt) { 47 | if (opt === void 0) { opt = defaults; } 48 | elm.addEventListener("touchstart", onPointerDown, true); 49 | elm.addEventListener("mousedown", onPointerDown, true); 50 | options.set(elm, opt); 51 | } 52 | function getPointerPosition(e) { 53 | if (e.changedTouches) 54 | e = e.changedTouches[0]; 55 | return [e.clientX, e.clientY]; 56 | } 57 | function onPointerDown(e) { 58 | var _a; 59 | activeDraggedElement = e.currentTarget; 60 | checkDragPos = true; 61 | _a = getPointerPosition(e), startX = _a[0], startY = _a[1]; 62 | addOrRemoveEvents(); 63 | } 64 | function onPointerMove(e) { 65 | var _a, _b; 66 | e.preventDefault(); 67 | if (!activeDraggedElement) 68 | return; 69 | var _c = getPointerPosition(e), x = _c[0], y = _c[1]; 70 | if (checkDragPos) { 71 | var opt = options.get(activeDraggedElement); 72 | if (Math.hypot(x - startX, y - startY) < opt.threshold) 73 | return; 74 | checkDragPos = false; 75 | _a = [x, y], lastX = _a[0], lastY = _a[1]; 76 | if (!dispatchDragEvent("dragstart", e)) { 77 | removeDragEvents(); 78 | } 79 | } 80 | else if (dispatchDragEvent("dragmove", e)) { 81 | _b = [x, y], lastX = _b[0], lastY = _b[1]; 82 | } 83 | } 84 | function getDragPositions(e) { 85 | var _a = getPointerPosition(e), clientX = _a[0], clientY = _a[1]; 86 | return { 87 | startX: startX, 88 | startY: startY, 89 | lastX: lastX, 90 | lastY: lastY, 91 | //current mouse position 92 | clientX: clientX, 93 | clientY: clientY, 94 | // mouse delta from initial drag position 95 | offsetX: clientX - startX, 96 | offsetY: clientY - startY, 97 | // mouse delta from last drag position 98 | movementX: clientX - lastX, 99 | movementY: clientY - lastY, 100 | }; 101 | } 102 | function removeDragEvents() { 103 | activeDraggedElement = undefined; 104 | addOrRemoveEvents(true); 105 | } 106 | function onPointerUp(e) { 107 | if (activeDraggedElement && !checkDragPos) { 108 | dispatchDragEvent("dragstop", e, false); 109 | } 110 | removeDragEvents(); 111 | } 112 | function addOrRemoveEvents(remove) { 113 | if (remove === void 0) { remove = false; } 114 | var fn = remove ? "removeEventListener" : "addEventListener"; 115 | document[fn]("mouseup", onPointerUp); 116 | document[fn]("touchend", onPointerUp); 117 | document[fn]("mousemove", onPointerMove); 118 | document[fn]("touchmove", onPointerMove); 119 | } 120 | function dispatchDragEvent(name, e, cancelable) { 121 | if (cancelable === void 0) { cancelable = true; } 122 | return !dispatchCustomEvent(name, activeDraggedElement, __assign(__assign({}, getDragPositions(e)), { originalEvent: e }), cancelable); 123 | } 124 | 125 | exports.enableDragEvents = enableDragEvents; 126 | 127 | Object.defineProperty(exports, '__esModule', { value: true }); 128 | 129 | }))); 130 | //# sourceMappingURL=drag.js.map 131 | -------------------------------------------------------------------------------- /dist/drag.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"drag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /*! ***************************************************************************** 8 | Copyright (c) Microsoft Corporation. 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************************************************** */ 21 | 22 | var __assign = function() { 23 | __assign = Object.assign || function __assign(t) { 24 | for (var s, i = 1, n = arguments.length; i < n; i++) { 25 | s = arguments[i]; 26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 27 | } 28 | return t; 29 | }; 30 | return __assign.apply(this, arguments); 31 | }; 32 | 33 | function dispatchCustomEvent(name, elm, detail, cancelable) { 34 | if (cancelable === void 0) { cancelable = true; } 35 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 36 | } 37 | 38 | var activeDraggedElement; 39 | var startX, startY; 40 | var lastX, lastY; 41 | var checkDragPos; 42 | var defaults$1 = { 43 | threshold: 0, 44 | }; 45 | var options$1 = new WeakMap(); 46 | function enableDragEvents(elm, opt) { 47 | if (opt === void 0) { opt = defaults$1; } 48 | elm.addEventListener("touchstart", onPointerDown, true); 49 | elm.addEventListener("mousedown", onPointerDown, true); 50 | options$1.set(elm, opt); 51 | } 52 | function getPointerPosition(e) { 53 | if (e.changedTouches) 54 | e = e.changedTouches[0]; 55 | return [e.clientX, e.clientY]; 56 | } 57 | function onPointerDown(e) { 58 | var _a; 59 | activeDraggedElement = e.currentTarget; 60 | checkDragPos = true; 61 | _a = getPointerPosition(e), startX = _a[0], startY = _a[1]; 62 | addOrRemoveEvents(); 63 | } 64 | function onPointerMove(e) { 65 | var _a, _b; 66 | e.preventDefault(); 67 | if (!activeDraggedElement) 68 | return; 69 | var _c = getPointerPosition(e), x = _c[0], y = _c[1]; 70 | if (checkDragPos) { 71 | var opt = options$1.get(activeDraggedElement); 72 | if (Math.hypot(x - startX, y - startY) < opt.threshold) 73 | return; 74 | checkDragPos = false; 75 | _a = [x, y], lastX = _a[0], lastY = _a[1]; 76 | if (!dispatchDragEvent("dragstart", e)) { 77 | removeDragEvents(); 78 | } 79 | } 80 | else if (dispatchDragEvent("dragmove", e)) { 81 | _b = [x, y], lastX = _b[0], lastY = _b[1]; 82 | } 83 | } 84 | function getDragPositions(e) { 85 | var _a = getPointerPosition(e), clientX = _a[0], clientY = _a[1]; 86 | return { 87 | startX: startX, 88 | startY: startY, 89 | lastX: lastX, 90 | lastY: lastY, 91 | //current mouse position 92 | clientX: clientX, 93 | clientY: clientY, 94 | // mouse delta from initial drag position 95 | offsetX: clientX - startX, 96 | offsetY: clientY - startY, 97 | // mouse delta from last drag position 98 | movementX: clientX - lastX, 99 | movementY: clientY - lastY, 100 | }; 101 | } 102 | function removeDragEvents() { 103 | activeDraggedElement = undefined; 104 | addOrRemoveEvents(true); 105 | } 106 | function onPointerUp(e) { 107 | if (activeDraggedElement && !checkDragPos) { 108 | dispatchDragEvent("dragstop", e, false); 109 | } 110 | removeDragEvents(); 111 | } 112 | function addOrRemoveEvents(remove) { 113 | if (remove === void 0) { remove = false; } 114 | var fn = remove ? "removeEventListener" : "addEventListener"; 115 | document[fn]("mouseup", onPointerUp); 116 | document[fn]("touchend", onPointerUp); 117 | document[fn]("mousemove", onPointerMove); 118 | document[fn]("touchmove", onPointerMove); 119 | } 120 | function dispatchDragEvent(name, e, cancelable) { 121 | if (cancelable === void 0) { cancelable = true; } 122 | return !dispatchCustomEvent(name, activeDraggedElement, __assign(__assign({}, getDragPositions(e)), { originalEvent: e }), cancelable); 123 | } 124 | 125 | var startTouches; 126 | var lastTouches; 127 | var activeElement; 128 | var checkPinch; 129 | var lastDist; 130 | var lastOffset; 131 | var lastAngle; 132 | var defaults = { 133 | distanceThreshold: 0, 134 | angleThreshold: 0, 135 | }; 136 | var options = new WeakMap(); 137 | function enablePinchEvents(elm, opt) { 138 | if (opt === void 0) { opt = defaults; } 139 | options.set(elm, opt); 140 | elm.addEventListener("touchstart", onTouchStart); 141 | } 142 | function onTouchStart(e) { 143 | startTouches = e.touches; 144 | checkPinch = true; 145 | this.addEventListener("touchmove", onTouchMove); 146 | } 147 | function onTouchMove(e) { 148 | e.preventDefault(); 149 | if (e.touches.length != 2) 150 | return; 151 | var props = calculatePinchProps(e.touches); 152 | if (checkPinch) { 153 | pinchStartHandler(e, props); 154 | } 155 | else { 156 | pinchMoveHandler(e, props); 157 | } 158 | } 159 | function pinchStartHandler(e, _a) { 160 | var dist = _a.dist, angle = _a.angle; 161 | if (startTouches.length != 2) 162 | return; 163 | var _b = calculatePinchProps(startTouches), startDist = _b.dist, startAngle = _b.angle; 164 | var _c = options.get(e.currentTarget), distanceThreshold = _c.distanceThreshold, angleThreshold = _c.angleThreshold; 165 | var dd = Math.abs(dist - startDist); 166 | var da = Math.abs(angle - startAngle); 167 | if (dd >= distanceThreshold && da >= angleThreshold) { 168 | var isCancelled = dispatchCustomEvent("pinchstart", e.currentTarget, { 169 | startTouches: startTouches, 170 | originalEvent: e, 171 | }); 172 | if (isCancelled) { 173 | e.currentTarget.removeEventListener("touchmove", onTouchMove); 174 | return; 175 | } 176 | activeElement = e.currentTarget; 177 | lastDist = startDist; 178 | lastAngle = startAngle; 179 | lastOffset = 0; 180 | checkPinch = false; 181 | document.addEventListener("touchend", onTouchEnd); 182 | } 183 | } 184 | function pinchMoveHandler(e, props) { 185 | var angle = props.angle, offset = props.offset, dist = props.dist; 186 | var isCancelled = dispatchPinchEvent("move", e.currentTarget, __assign(__assign({}, props), { originalEvent: e, touches: e.touches })); 187 | // will stop counting lastDist/Offset when cancelled 188 | if (isCancelled) 189 | return; 190 | lastDist = dist; 191 | lastAngle = angle; 192 | lastOffset = offset; 193 | } 194 | function calculatePinchProps(touches) { 195 | var p1 = touches[0], p2 = touches[1]; 196 | var dx = p1.clientX - p2.clientX; 197 | var dy = p1.clientY - p2.clientY; 198 | var dist = Math.hypot(dx, dy); 199 | var offset = dist - lastDist; 200 | var angle = Math.atan2(dy, dx); 201 | var da = angle - lastAngle; 202 | var midX = (p1.clientX + p2.clientX) / 2; 203 | var midY = (p1.clientY + p2.clientY) / 2; 204 | var dir = Math.sign(dist - (lastDist || dist)); 205 | return { dx: dx, dy: dy, da: da, dist: dist, angle: angle, offset: offset, midX: midX, midY: midY, dir: dir }; 206 | } 207 | function onTouchEnd(e) { 208 | if (!checkPinch && activeElement) { 209 | var detail = { 210 | originalEvent: e, 211 | }; 212 | dispatchPinchEvent("end", activeElement, detail, false); 213 | activeElement = undefined; 214 | } 215 | } 216 | function dispatchPinchEvent(ev, elm, detail, cancelable) { 217 | if (cancelable === void 0) { cancelable = true; } 218 | detail = __assign(__assign({}, detail), { startTouches: startTouches, 219 | lastTouches: lastTouches, 220 | lastOffset: lastOffset, 221 | lastDist: lastDist, 222 | lastAngle: lastAngle }); 223 | return dispatchCustomEvent("pinch" + ev, elm, detail, cancelable); 224 | } 225 | 226 | function enableLongPressEvents(elm, opt) { 227 | if (opt === void 0) { opt = {}; } 228 | function onPointerDown(e) { 229 | var timeout = setTimeout(function () { 230 | dispatchCustomEvent("longpress", elm, { 231 | originalEvent: e, 232 | }); 233 | }, opt.duration || 700); 234 | function onPointerUp() { 235 | clearTimeout(timeout); 236 | } 237 | var options = { once: true }; 238 | elm.addEventListener("touchend", onPointerUp, options); 239 | elm.addEventListener("mouseup", onPointerUp, options); 240 | } 241 | elm.addEventListener("touchstart", onPointerDown, true); 242 | elm.addEventListener("mousedown", onPointerDown, true); 243 | } 244 | 245 | exports.enableDragEvents = enableDragEvents; 246 | exports.enableLongPressEvents = enableLongPressEvents; 247 | exports.enablePinchEvents = enablePinchEvents; 248 | 249 | Object.defineProperty(exports, '__esModule', { value: true }); 250 | 251 | }))); 252 | //# sourceMappingURL=index.js.map 253 | -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /dist/interfaces.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /dist/longpress.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | function dispatchCustomEvent(name, elm, detail, cancelable) { 8 | if (cancelable === void 0) { cancelable = true; } 9 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 10 | } 11 | 12 | function enableLongPressEvents(elm, opt) { 13 | if (opt === void 0) { opt = {}; } 14 | function onPointerDown(e) { 15 | var timeout = setTimeout(function () { 16 | dispatchCustomEvent("longpress", elm, { 17 | originalEvent: e, 18 | }); 19 | }, opt.duration || 700); 20 | function onPointerUp() { 21 | clearTimeout(timeout); 22 | } 23 | var options = { once: true }; 24 | elm.addEventListener("touchend", onPointerUp, options); 25 | elm.addEventListener("mouseup", onPointerUp, options); 26 | } 27 | elm.addEventListener("touchstart", onPointerDown, true); 28 | elm.addEventListener("mousedown", onPointerDown, true); 29 | } 30 | 31 | exports.enableLongPressEvents = enableLongPressEvents; 32 | 33 | Object.defineProperty(exports, '__esModule', { value: true }); 34 | 35 | }))); 36 | //# sourceMappingURL=longpress.js.map 37 | -------------------------------------------------------------------------------- /dist/longpress.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"longpress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /dist/pinch.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.EZG = global.EZG || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /*! ***************************************************************************** 8 | Copyright (c) Microsoft Corporation. 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************************************************** */ 21 | 22 | var __assign = function() { 23 | __assign = Object.assign || function __assign(t) { 24 | for (var s, i = 1, n = arguments.length; i < n; i++) { 25 | s = arguments[i]; 26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 27 | } 28 | return t; 29 | }; 30 | return __assign.apply(this, arguments); 31 | }; 32 | 33 | function dispatchCustomEvent(name, elm, detail, cancelable) { 34 | if (cancelable === void 0) { cancelable = true; } 35 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 36 | } 37 | 38 | var startTouches; 39 | var lastTouches; 40 | var activeElement; 41 | var checkPinch; 42 | var lastDist; 43 | var lastOffset; 44 | var lastAngle; 45 | var defaults = { 46 | distanceThreshold: 0, 47 | angleThreshold: 0, 48 | }; 49 | var options = new WeakMap(); 50 | function enablePinchEvents(elm, opt) { 51 | if (opt === void 0) { opt = defaults; } 52 | options.set(elm, opt); 53 | elm.addEventListener("touchstart", onTouchStart); 54 | } 55 | function onTouchStart(e) { 56 | startTouches = e.touches; 57 | checkPinch = true; 58 | this.addEventListener("touchmove", onTouchMove); 59 | } 60 | function onTouchMove(e) { 61 | e.preventDefault(); 62 | if (e.touches.length != 2) 63 | return; 64 | var props = calculatePinchProps(e.touches); 65 | if (checkPinch) { 66 | pinchStartHandler(e, props); 67 | } 68 | else { 69 | pinchMoveHandler(e, props); 70 | } 71 | } 72 | function pinchStartHandler(e, _a) { 73 | var dist = _a.dist, angle = _a.angle; 74 | if (startTouches.length != 2) 75 | return; 76 | var _b = calculatePinchProps(startTouches), startDist = _b.dist, startAngle = _b.angle; 77 | var _c = options.get(e.currentTarget), distanceThreshold = _c.distanceThreshold, angleThreshold = _c.angleThreshold; 78 | var dd = Math.abs(dist - startDist); 79 | var da = Math.abs(angle - startAngle); 80 | if (dd >= distanceThreshold && da >= angleThreshold) { 81 | var isCancelled = dispatchCustomEvent("pinchstart", e.currentTarget, { 82 | startTouches: startTouches, 83 | originalEvent: e, 84 | }); 85 | if (isCancelled) { 86 | e.currentTarget.removeEventListener("touchmove", onTouchMove); 87 | return; 88 | } 89 | activeElement = e.currentTarget; 90 | lastDist = startDist; 91 | lastAngle = startAngle; 92 | lastOffset = 0; 93 | checkPinch = false; 94 | document.addEventListener("touchend", onTouchEnd); 95 | } 96 | } 97 | function pinchMoveHandler(e, props) { 98 | var angle = props.angle, offset = props.offset, dist = props.dist; 99 | var isCancelled = dispatchPinchEvent("move", e.currentTarget, __assign(__assign({}, props), { originalEvent: e, touches: e.touches })); 100 | // will stop counting lastDist/Offset when cancelled 101 | if (isCancelled) 102 | return; 103 | lastDist = dist; 104 | lastAngle = angle; 105 | lastOffset = offset; 106 | } 107 | function calculatePinchProps(touches) { 108 | var p1 = touches[0], p2 = touches[1]; 109 | var dx = p1.clientX - p2.clientX; 110 | var dy = p1.clientY - p2.clientY; 111 | var dist = Math.hypot(dx, dy); 112 | var offset = dist - lastDist; 113 | var angle = Math.atan2(dy, dx); 114 | var da = angle - lastAngle; 115 | var midX = (p1.clientX + p2.clientX) / 2; 116 | var midY = (p1.clientY + p2.clientY) / 2; 117 | var dir = Math.sign(dist - (lastDist || dist)); 118 | return { dx: dx, dy: dy, da: da, dist: dist, angle: angle, offset: offset, midX: midX, midY: midY, dir: dir }; 119 | } 120 | function onTouchEnd(e) { 121 | if (!checkPinch && activeElement) { 122 | var detail = { 123 | originalEvent: e, 124 | }; 125 | dispatchPinchEvent("end", activeElement, detail, false); 126 | activeElement = undefined; 127 | } 128 | } 129 | function dispatchPinchEvent(ev, elm, detail, cancelable) { 130 | if (cancelable === void 0) { cancelable = true; } 131 | detail = __assign(__assign({}, detail), { startTouches: startTouches, 132 | lastTouches: lastTouches, 133 | lastOffset: lastOffset, 134 | lastDist: lastDist, 135 | lastAngle: lastAngle }); 136 | return dispatchCustomEvent("pinch" + ev, elm, detail, cancelable); 137 | } 138 | 139 | exports.enablePinchEvents = enablePinchEvents; 140 | 141 | Object.defineProperty(exports, '__esModule', { value: true }); 142 | 143 | }))); 144 | //# sourceMappingURL=pinch.js.map 145 | -------------------------------------------------------------------------------- /dist/pinch.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"pinch.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /dist/shared.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.dispatchCustomEvent = void 0; 4 | function dispatchCustomEvent(name, elm, detail, cancelable) { 5 | if (cancelable === void 0) { cancelable = true; } 6 | return !elm.dispatchEvent(new CustomEvent("ezg" + name, { detail: detail, cancelable: cancelable })); 7 | } 8 | exports.dispatchCustomEvent = dispatchCustomEvent; 9 | -------------------------------------------------------------------------------- /lib/drag.ts: -------------------------------------------------------------------------------- 1 | import { dispatchCustomEvent } from "./shared"; 2 | 3 | let activeDraggedElement; 4 | let startX, startY; 5 | let lastX, lastY; 6 | let checkDragPos; 7 | 8 | const defaults = { 9 | threshold: 0, 10 | }; 11 | 12 | const options = new WeakMap(); 13 | 14 | export function enableDragEvents(elm: Element, opt = defaults) { 15 | elm.addEventListener("touchstart", onPointerDown, true); 16 | elm.addEventListener("mousedown", onPointerDown, true); 17 | options.set(elm, opt); 18 | } 19 | 20 | function getPointerPosition(e) { 21 | if (e.changedTouches) e = e.changedTouches[0]; 22 | return [e.clientX, e.clientY]; 23 | } 24 | 25 | function onPointerDown(e) { 26 | activeDraggedElement = e.currentTarget; 27 | checkDragPos = true; 28 | 29 | [startX, startY] = getPointerPosition(e); 30 | 31 | addOrRemoveEvents(); 32 | } 33 | 34 | function onPointerMove(e) { 35 | e.preventDefault(); 36 | if (!activeDraggedElement) return; 37 | 38 | const [x, y] = getPointerPosition(e); 39 | 40 | if (checkDragPos) { 41 | const opt = options.get(activeDraggedElement); 42 | 43 | if (Math.hypot(x - startX, y - startY) < opt.threshold) return; 44 | 45 | checkDragPos = false; 46 | [lastX, lastY] = [x, y]; 47 | 48 | if (!dispatchDragEvent("dragstart", e)) { 49 | removeDragEvents(); 50 | } 51 | } else if (dispatchDragEvent("dragmove", e)) { 52 | [lastX, lastY] = [x, y]; 53 | } 54 | } 55 | 56 | function getDragPositions(e) { 57 | const [clientX, clientY] = getPointerPosition(e); 58 | return { 59 | startX, 60 | startY, 61 | lastX, 62 | lastY, 63 | 64 | //current mouse position 65 | clientX, 66 | clientY, 67 | 68 | // mouse delta from initial drag position 69 | offsetX: clientX - startX, 70 | offsetY: clientY - startY, 71 | 72 | // mouse delta from last drag position 73 | movementX: clientX - lastX, 74 | movementY: clientY - lastY, 75 | }; 76 | } 77 | 78 | function removeDragEvents() { 79 | activeDraggedElement = undefined; 80 | 81 | addOrRemoveEvents(true); 82 | } 83 | 84 | function onPointerUp(e) { 85 | if (activeDraggedElement && !checkDragPos) { 86 | dispatchDragEvent("dragstop", e, false); 87 | } 88 | 89 | removeDragEvents(); 90 | } 91 | 92 | function addOrRemoveEvents(remove = false) { 93 | const fn = remove ? "removeEventListener" : "addEventListener"; 94 | document[fn]("mouseup", onPointerUp); 95 | document[fn]("touchend", onPointerUp); 96 | document[fn]("mousemove", onPointerMove); 97 | document[fn]("touchmove", onPointerMove); 98 | } 99 | 100 | function dispatchDragEvent(name, e, cancelable = true) { 101 | return !dispatchCustomEvent( 102 | name, 103 | activeDraggedElement, 104 | { 105 | ...getDragPositions(e), 106 | originalEvent: e, 107 | }, 108 | cancelable 109 | ); 110 | } 111 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | export { enableDragEvents } from "./drag"; 2 | export { enablePinchEvents } from "./pinch"; 3 | export { enableLongPressEvents } from "./longpress"; 4 | -------------------------------------------------------------------------------- /lib/interfaces.ts: -------------------------------------------------------------------------------- 1 | interface EZGDragEventDetail { 2 | startX: number; 3 | startY: number; 4 | 5 | lastX: number; 6 | lastY: number; 7 | 8 | clientX: number; 9 | clientY: number; 10 | 11 | offsetX: number; 12 | offsetY: number; 13 | 14 | movementX: number; 15 | movementY: number; 16 | 17 | originalEvent: MouseEvent | TouchEvent; 18 | } 19 | 20 | interface EZGPinchBaseDetail { 21 | startTouches: TouchList; 22 | lastTouches: TouchList; 23 | lastOffset: number; 24 | lastDist: number; 25 | lastAngle: number; 26 | originalEvent: TouchEvent; 27 | } 28 | 29 | type EZGPinchEndDetail = EZGPinchBaseDetail; 30 | 31 | interface EZGPinchStartDetail { 32 | startTouches: TouchEvent; 33 | originalEvent: TouchEvent; 34 | } 35 | 36 | interface EZGPinchMoveDetail extends EZGPinchBaseDetail { 37 | dx: number; 38 | dy: number; 39 | da: number; 40 | dist: number; 41 | angle: number; 42 | offset: number; 43 | midX: number; 44 | midY: number; 45 | dir: number; 46 | touches: TouchList; 47 | } 48 | 49 | interface EZGLongPressDetail { 50 | originalEvent: MouseEvent | TouchEvent; 51 | } 52 | 53 | type EZGDragEvent = CustomEvent; 54 | 55 | type EZGPinchStartEvent = CustomEvent; 56 | type EZGPinchMoveEvent = CustomEvent; 57 | type EZGPinchEndEvent = CustomEvent; 58 | 59 | type EZGLongPressEvent = CustomEvent; 60 | -------------------------------------------------------------------------------- /lib/longpress.ts: -------------------------------------------------------------------------------- 1 | import { dispatchCustomEvent } from "./shared"; 2 | 3 | interface Options { 4 | duration?: number; 5 | } 6 | 7 | export function enableLongPressEvents(elm: Element, opt: Options = {}) { 8 | function onPointerDown(e) { 9 | const timeout = setTimeout(() => { 10 | dispatchCustomEvent("longpress", elm, { 11 | originalEvent: e, 12 | }); 13 | }, opt.duration || 700); 14 | 15 | function onPointerUp() { 16 | clearTimeout(timeout); 17 | } 18 | 19 | const options = { once: true }; 20 | elm.addEventListener("touchend", onPointerUp, options); 21 | elm.addEventListener("mouseup", onPointerUp, options); 22 | } 23 | elm.addEventListener("touchstart", onPointerDown, true); 24 | elm.addEventListener("mousedown", onPointerDown, true); 25 | } 26 | -------------------------------------------------------------------------------- /lib/pinch.ts: -------------------------------------------------------------------------------- 1 | import { dispatchCustomEvent } from "./shared"; 2 | 3 | let startTouches; 4 | let lastTouches; 5 | 6 | let activeElement; 7 | let checkPinch; 8 | 9 | let lastDist; 10 | let lastOffset; 11 | let lastAngle; 12 | 13 | const defaults = { 14 | distanceThreshold: 0, 15 | angleThreshold: 0, 16 | }; 17 | 18 | const options = new WeakMap(); 19 | 20 | export function enablePinchEvents(elm: HTMLElement, opt = defaults) { 21 | options.set(elm, opt); 22 | elm.addEventListener("touchstart", onTouchStart); 23 | } 24 | 25 | function onTouchStart(this: Element, e: TouchEvent) { 26 | startTouches = e.touches; 27 | checkPinch = true; 28 | this.addEventListener("touchmove", onTouchMove); 29 | } 30 | 31 | function onTouchMove(e) { 32 | e.preventDefault(); 33 | if (e.touches.length != 2) return; 34 | 35 | const props = calculatePinchProps(e.touches); 36 | 37 | if (checkPinch) { 38 | pinchStartHandler(e, props); 39 | } else { 40 | pinchMoveHandler(e, props); 41 | } 42 | } 43 | 44 | function pinchStartHandler(e, { dist, angle }) { 45 | if (startTouches.length != 2) return; 46 | const { dist: startDist, angle: startAngle } = 47 | calculatePinchProps(startTouches); 48 | 49 | const { distanceThreshold, angleThreshold } = options.get(e.currentTarget); 50 | 51 | const dd = Math.abs(dist - startDist); 52 | const da = Math.abs(angle - startAngle); 53 | 54 | if (dd >= distanceThreshold && da >= angleThreshold) { 55 | const isCancelled = dispatchCustomEvent("pinchstart", e.currentTarget, { 56 | startTouches, 57 | originalEvent: e, 58 | }); 59 | 60 | if (isCancelled) { 61 | e.currentTarget.removeEventListener("touchmove", onTouchMove); 62 | return; 63 | } 64 | 65 | activeElement = e.currentTarget; 66 | lastDist = startDist; 67 | lastAngle = startAngle; 68 | lastOffset = 0; 69 | checkPinch = false; 70 | document.addEventListener("touchend", onTouchEnd); 71 | } 72 | } 73 | 74 | function pinchMoveHandler(e, props) { 75 | const { angle, offset, dist } = props; 76 | const isCancelled = dispatchPinchEvent("move", e.currentTarget, { 77 | ...props, 78 | originalEvent: e, 79 | touches: e.touches, 80 | }); 81 | 82 | // will stop counting lastDist/Offset when cancelled 83 | if (isCancelled) return; 84 | 85 | lastDist = dist; 86 | lastAngle = angle; 87 | lastOffset = offset; 88 | } 89 | 90 | function calculatePinchProps(touches) { 91 | const [p1, p2] = touches; 92 | 93 | const dx = p1.clientX - p2.clientX; 94 | const dy = p1.clientY - p2.clientY; 95 | 96 | const dist = Math.hypot(dx, dy); 97 | const offset = dist - lastDist; 98 | 99 | const angle = Math.atan2(dy, dx); 100 | const da = angle - lastAngle; 101 | 102 | const midX = (p1.clientX + p2.clientX) / 2; 103 | const midY = (p1.clientY + p2.clientY) / 2; 104 | 105 | const dir = Math.sign(dist - (lastDist || dist)); 106 | 107 | return { dx, dy, da, dist, angle, offset, midX, midY, dir }; 108 | } 109 | 110 | function onTouchEnd(e) { 111 | if (!checkPinch && activeElement) { 112 | const detail = { 113 | originalEvent: e, 114 | }; 115 | dispatchPinchEvent("end", activeElement, detail, false); 116 | activeElement = undefined; 117 | } 118 | } 119 | 120 | function dispatchPinchEvent(ev, elm, detail, cancelable = true) { 121 | detail = { 122 | ...detail, 123 | startTouches, 124 | lastTouches, 125 | lastOffset, 126 | lastDist, 127 | lastAngle, 128 | }; 129 | return dispatchCustomEvent(`pinch${ev}`, elm, detail, cancelable); 130 | } 131 | -------------------------------------------------------------------------------- /lib/shared.ts: -------------------------------------------------------------------------------- 1 | export function dispatchCustomEvent(name, elm, detail, cancelable = true) { 2 | return !elm.dispatchEvent( 3 | new CustomEvent(`ezg${name}`, { detail, cancelable }) 4 | ); 5 | } 6 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ezgesture", 3 | "version": "1.1.4", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.12.13", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", 10 | "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.12.13" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.12.11", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", 19 | "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.13.10", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", 25 | "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.12.11", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | } 32 | }, 33 | "@rollup/plugin-typescript": { 34 | "version": "8.2.1", 35 | "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz", 36 | "integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==", 37 | "dev": true, 38 | "requires": { 39 | "@rollup/pluginutils": "^3.1.0", 40 | "resolve": "^1.17.0" 41 | } 42 | }, 43 | "@rollup/pluginutils": { 44 | "version": "3.1.0", 45 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 46 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 47 | "dev": true, 48 | "requires": { 49 | "@types/estree": "0.0.39", 50 | "estree-walker": "^1.0.1", 51 | "picomatch": "^2.2.2" 52 | } 53 | }, 54 | "@types/estree": { 55 | "version": "0.0.39", 56 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 57 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 58 | "dev": true 59 | }, 60 | "@types/node": { 61 | "version": "14.14.35", 62 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", 63 | "integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==", 64 | "dev": true 65 | }, 66 | "ansi-styles": { 67 | "version": "3.2.1", 68 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 69 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 70 | "dev": true, 71 | "requires": { 72 | "color-convert": "^1.9.0" 73 | } 74 | }, 75 | "buffer-from": { 76 | "version": "1.1.1", 77 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 78 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 79 | "dev": true 80 | }, 81 | "chalk": { 82 | "version": "2.4.2", 83 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 84 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 85 | "dev": true, 86 | "requires": { 87 | "ansi-styles": "^3.2.1", 88 | "escape-string-regexp": "^1.0.5", 89 | "supports-color": "^5.3.0" 90 | } 91 | }, 92 | "color-convert": { 93 | "version": "1.9.3", 94 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 95 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 96 | "dev": true, 97 | "requires": { 98 | "color-name": "1.1.3" 99 | } 100 | }, 101 | "color-name": { 102 | "version": "1.1.3", 103 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 104 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 105 | "dev": true 106 | }, 107 | "commander": { 108 | "version": "2.20.3", 109 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 110 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 111 | "dev": true 112 | }, 113 | "commondir": { 114 | "version": "1.0.1", 115 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 116 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 117 | "dev": true 118 | }, 119 | "escape-string-regexp": { 120 | "version": "1.0.5", 121 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 122 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 123 | "dev": true 124 | }, 125 | "estree-walker": { 126 | "version": "1.0.1", 127 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 128 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 129 | "dev": true 130 | }, 131 | "find-cache-dir": { 132 | "version": "3.3.1", 133 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", 134 | "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", 135 | "dev": true, 136 | "requires": { 137 | "commondir": "^1.0.1", 138 | "make-dir": "^3.0.2", 139 | "pkg-dir": "^4.1.0" 140 | } 141 | }, 142 | "find-up": { 143 | "version": "4.1.0", 144 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 145 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 146 | "dev": true, 147 | "requires": { 148 | "locate-path": "^5.0.0", 149 | "path-exists": "^4.0.0" 150 | } 151 | }, 152 | "fs-extra": { 153 | "version": "8.1.0", 154 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 155 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 156 | "dev": true, 157 | "requires": { 158 | "graceful-fs": "^4.2.0", 159 | "jsonfile": "^4.0.0", 160 | "universalify": "^0.1.0" 161 | } 162 | }, 163 | "fsevents": { 164 | "version": "2.3.2", 165 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 166 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 167 | "dev": true, 168 | "optional": true 169 | }, 170 | "function-bind": { 171 | "version": "1.1.1", 172 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 173 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 174 | "dev": true 175 | }, 176 | "graceful-fs": { 177 | "version": "4.2.6", 178 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", 179 | "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", 180 | "dev": true 181 | }, 182 | "has": { 183 | "version": "1.0.3", 184 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 185 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 186 | "dev": true, 187 | "requires": { 188 | "function-bind": "^1.1.1" 189 | } 190 | }, 191 | "has-flag": { 192 | "version": "3.0.0", 193 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 194 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 195 | "dev": true 196 | }, 197 | "is-core-module": { 198 | "version": "2.4.0", 199 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", 200 | "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", 201 | "dev": true, 202 | "requires": { 203 | "has": "^1.0.3" 204 | } 205 | }, 206 | "jest-worker": { 207 | "version": "26.6.2", 208 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", 209 | "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", 210 | "dev": true, 211 | "requires": { 212 | "@types/node": "*", 213 | "merge-stream": "^2.0.0", 214 | "supports-color": "^7.0.0" 215 | }, 216 | "dependencies": { 217 | "has-flag": { 218 | "version": "4.0.0", 219 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 220 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 221 | "dev": true 222 | }, 223 | "supports-color": { 224 | "version": "7.2.0", 225 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 226 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 227 | "dev": true, 228 | "requires": { 229 | "has-flag": "^4.0.0" 230 | } 231 | } 232 | } 233 | }, 234 | "js-tokens": { 235 | "version": "4.0.0", 236 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 237 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 238 | "dev": true 239 | }, 240 | "jsonfile": { 241 | "version": "4.0.0", 242 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 243 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 244 | "dev": true, 245 | "requires": { 246 | "graceful-fs": "^4.1.6" 247 | } 248 | }, 249 | "locate-path": { 250 | "version": "5.0.0", 251 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 252 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 253 | "dev": true, 254 | "requires": { 255 | "p-locate": "^4.1.0" 256 | } 257 | }, 258 | "make-dir": { 259 | "version": "3.1.0", 260 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 261 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 262 | "dev": true, 263 | "requires": { 264 | "semver": "^6.0.0" 265 | } 266 | }, 267 | "merge-stream": { 268 | "version": "2.0.0", 269 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 270 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 271 | "dev": true 272 | }, 273 | "p-limit": { 274 | "version": "2.3.0", 275 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 276 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 277 | "dev": true, 278 | "requires": { 279 | "p-try": "^2.0.0" 280 | } 281 | }, 282 | "p-locate": { 283 | "version": "4.1.0", 284 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 285 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 286 | "dev": true, 287 | "requires": { 288 | "p-limit": "^2.2.0" 289 | } 290 | }, 291 | "p-try": { 292 | "version": "2.2.0", 293 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 294 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 295 | "dev": true 296 | }, 297 | "path-exists": { 298 | "version": "4.0.0", 299 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 300 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 301 | "dev": true 302 | }, 303 | "path-parse": { 304 | "version": "1.0.6", 305 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 306 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 307 | "dev": true 308 | }, 309 | "picomatch": { 310 | "version": "2.2.3", 311 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", 312 | "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", 313 | "dev": true 314 | }, 315 | "pkg-dir": { 316 | "version": "4.2.0", 317 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 318 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 319 | "dev": true, 320 | "requires": { 321 | "find-up": "^4.0.0" 322 | } 323 | }, 324 | "randombytes": { 325 | "version": "2.1.0", 326 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 327 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 328 | "dev": true, 329 | "requires": { 330 | "safe-buffer": "^5.1.0" 331 | } 332 | }, 333 | "resolve": { 334 | "version": "1.20.0", 335 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 336 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 337 | "dev": true, 338 | "requires": { 339 | "is-core-module": "^2.2.0", 340 | "path-parse": "^1.0.6" 341 | } 342 | }, 343 | "rollup": { 344 | "version": "2.41.5", 345 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.41.5.tgz", 346 | "integrity": "sha512-uG+WNNxhOYyeuO7oRt98GA2CNVRgQ67zca75UQVMPzMrLG9FUKzTCgvYVWhtB18TNbV7Uqxo97h+wErAnpFNJw==", 347 | "dev": true, 348 | "requires": { 349 | "fsevents": "~2.3.1" 350 | } 351 | }, 352 | "rollup-plugin-terser": { 353 | "version": "7.0.2", 354 | "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", 355 | "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", 356 | "dev": true, 357 | "requires": { 358 | "@babel/code-frame": "^7.10.4", 359 | "jest-worker": "^26.2.1", 360 | "serialize-javascript": "^4.0.0", 361 | "terser": "^5.0.0" 362 | } 363 | }, 364 | "rollup-plugin-typescript2": { 365 | "version": "0.30.0", 366 | "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.30.0.tgz", 367 | "integrity": "sha512-NUFszIQyhgDdhRS9ya/VEmsnpTe+GERDMmFo0Y+kf8ds51Xy57nPNGglJY+W6x1vcouA7Au7nsTgsLFj2I0PxQ==", 368 | "dev": true, 369 | "requires": { 370 | "@rollup/pluginutils": "^4.1.0", 371 | "find-cache-dir": "^3.3.1", 372 | "fs-extra": "8.1.0", 373 | "resolve": "1.20.0", 374 | "tslib": "2.1.0" 375 | }, 376 | "dependencies": { 377 | "@rollup/pluginutils": { 378 | "version": "4.1.0", 379 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.0.tgz", 380 | "integrity": "sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ==", 381 | "dev": true, 382 | "requires": { 383 | "estree-walker": "^2.0.1", 384 | "picomatch": "^2.2.2" 385 | } 386 | }, 387 | "estree-walker": { 388 | "version": "2.0.2", 389 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 390 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 391 | "dev": true 392 | }, 393 | "tslib": { 394 | "version": "2.1.0", 395 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", 396 | "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", 397 | "dev": true 398 | } 399 | } 400 | }, 401 | "safe-buffer": { 402 | "version": "5.2.1", 403 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 404 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 405 | "dev": true 406 | }, 407 | "semver": { 408 | "version": "6.3.0", 409 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 410 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 411 | "dev": true 412 | }, 413 | "serialize-javascript": { 414 | "version": "4.0.0", 415 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", 416 | "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", 417 | "dev": true, 418 | "requires": { 419 | "randombytes": "^2.1.0" 420 | } 421 | }, 422 | "source-map": { 423 | "version": "0.7.3", 424 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", 425 | "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", 426 | "dev": true 427 | }, 428 | "source-map-support": { 429 | "version": "0.5.19", 430 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 431 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 432 | "dev": true, 433 | "requires": { 434 | "buffer-from": "^1.0.0", 435 | "source-map": "^0.6.0" 436 | }, 437 | "dependencies": { 438 | "source-map": { 439 | "version": "0.6.1", 440 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 441 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 442 | "dev": true 443 | } 444 | } 445 | }, 446 | "supports-color": { 447 | "version": "5.5.0", 448 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 449 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 450 | "dev": true, 451 | "requires": { 452 | "has-flag": "^3.0.0" 453 | } 454 | }, 455 | "terser": { 456 | "version": "5.6.0", 457 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz", 458 | "integrity": "sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==", 459 | "dev": true, 460 | "requires": { 461 | "commander": "^2.20.0", 462 | "source-map": "~0.7.2", 463 | "source-map-support": "~0.5.19" 464 | } 465 | }, 466 | "tslib": { 467 | "version": "2.2.0", 468 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", 469 | "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", 470 | "dev": true 471 | }, 472 | "typescript": { 473 | "version": "4.2.4", 474 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", 475 | "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", 476 | "dev": true 477 | }, 478 | "universalify": { 479 | "version": "0.1.2", 480 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 481 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 482 | "dev": true 483 | } 484 | } 485 | } 486 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ezgesture", 3 | "version": "1.1.4", 4 | "description": "Easily add gestures functionality with simple native DOM events", 5 | "main": "./dist/index.js", 6 | "exports": { 7 | ".": "./dist/index.js", 8 | "./pinch": "./dist/pinch.js", 9 | "./drag": "./dist/drag.js", 10 | "./longpress": "./dist/longpress.js" 11 | }, 12 | "types": "types/", 13 | "scripts": { 14 | "dev": "rollup -cw", 15 | "build": "rollup -c", 16 | "copy-dist": "mkdir -p demos/dist && cp -r dist/ demos/", 17 | "publish-ghp": "git subtree push --prefix demos origin gh-pages", 18 | "prepublishOnly": "rollup -c" 19 | }, 20 | "files": [ 21 | "lib/*", 22 | "dist/*", 23 | "types/*", 24 | "README.md", 25 | "LICENSE" 26 | ], 27 | "keywords": [ 28 | "gesture", 29 | "pinch", 30 | "drag", 31 | "move", 32 | "mouse", 33 | "touch", 34 | "dom", 35 | "event", 36 | "interaction" 37 | ], 38 | "devDependencies": { 39 | "@rollup/plugin-typescript": "^8.2.1", 40 | "rollup": "^2.41.5", 41 | "rollup-plugin-terser": "^7.0.2", 42 | "rollup-plugin-typescript2": "^0.30.0", 43 | "terser": "^5.6.0", 44 | "tslib": "^2.2.0", 45 | "typescript": "^4.2.4" 46 | }, 47 | "author": "Mohammed Al-Qurafi", 48 | "license": "MIT", 49 | "homepage": "https://github.com/mhmd-22/ezgesture#readme", 50 | "bugs": { 51 | "url": "https://github.com/mhmd-22/ezgesture/issues" 52 | }, 53 | "repository": { 54 | "type": "git", 55 | "url": "https://github.com/mhmd-22/ezgesture.git" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "rollup-plugin-typescript2"; 2 | 3 | const files = ["drag", "pinch", "longpress", "index"]; 4 | 5 | export default files.map((file) => ({ 6 | input: `lib/${file}.ts`, 7 | output: { 8 | file: `dist/${file}.js`, 9 | format: "umd", 10 | name: "EZG", 11 | extend: file !== "index", 12 | sourcemap: true, 13 | }, 14 | plugins: [typescript({ useTsconfigDeclarationDir: true })], 15 | })); 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 8 | // "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | "lib": ["DOM"], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | "declarationDir": "types/", 15 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 16 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 17 | // "outFile": "./", /* Concatenate and emit output to single file. */ 18 | "outDir": "dist/", /* Redirect output structure to the directory. */ 19 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 20 | // "composite": true, /* Enable project compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | // "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | "baseUrl": "lib", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 55 | 56 | /* Source Map Options */ 57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 61 | 62 | /* Experimental Options */ 63 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 64 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 65 | 66 | /* Advanced Options */ 67 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 68 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /types/drag.d.ts: -------------------------------------------------------------------------------- 1 | export declare function enableDragEvents(elm: Element, opt?: { 2 | threshold: number; 3 | }): void; 4 | -------------------------------------------------------------------------------- /types/global.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface HTMLElementEventMap { 4 | ezgdragstart: EZGDragEvent; 5 | ezgdragmove: EZGDragEvent; 6 | ezgdragstop: EZGDragEvent; 7 | ezgpinchstart: EZGPinchStartEvent; 8 | ezgpinchmove: EZGPinchMoveEvent; 9 | ezgpinchend: EZGPinchEndEvent; 10 | ezglongpress: EZGLongPressEvent; 11 | } 12 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | export { enableDragEvents } from "./drag"; 2 | export { enablePinchEvents } from "./pinch"; 3 | export { enableLongPressEvents } from "./longpress"; 4 | -------------------------------------------------------------------------------- /types/interfaces.d.ts: -------------------------------------------------------------------------------- 1 | interface EZGDragEventDetail { 2 | startX: number; 3 | startY: number; 4 | lastX: number; 5 | lastY: number; 6 | clientX: number; 7 | clientY: number; 8 | offsetX: number; 9 | offsetY: number; 10 | movementX: number; 11 | movementY: number; 12 | originalEvent: MouseEvent | TouchEvent; 13 | } 14 | interface EZGPinchBaseDetail { 15 | startTouches: TouchList; 16 | lastTouches: TouchList; 17 | lastOffset: number; 18 | lastDist: number; 19 | lastAngle: number; 20 | originalEvent: TouchEvent; 21 | } 22 | declare type EZGPinchEndDetail = EZGPinchBaseDetail; 23 | interface EZGPinchStartDetail { 24 | startTouches: TouchEvent; 25 | originalEvent: TouchEvent; 26 | } 27 | interface EZGPinchMoveDetail extends EZGPinchBaseDetail { 28 | dx: number; 29 | dy: number; 30 | da: number; 31 | dist: number; 32 | angle: number; 33 | offset: number; 34 | midX: number; 35 | midY: number; 36 | dir: number; 37 | touches: TouchList; 38 | } 39 | interface EZGLongPressDetail { 40 | originalEvent: MouseEvent | TouchEvent; 41 | } 42 | declare type EZGDragEvent = CustomEvent; 43 | declare type EZGPinchStartEvent = CustomEvent; 44 | declare type EZGPinchMoveEvent = CustomEvent; 45 | declare type EZGPinchEndEvent = CustomEvent; 46 | declare type EZGLongPressEvent = CustomEvent; 47 | -------------------------------------------------------------------------------- /types/longpress.d.ts: -------------------------------------------------------------------------------- 1 | interface Options { 2 | duration?: number; 3 | } 4 | export declare function enableLongPressEvents(elm: Element, opt?: Options): void; 5 | export {}; 6 | -------------------------------------------------------------------------------- /types/pinch.d.ts: -------------------------------------------------------------------------------- 1 | export declare function enablePinchEvents(elm: HTMLElement, opt?: { 2 | distanceThreshold: number; 3 | angleThreshold: number; 4 | }): void; 5 | -------------------------------------------------------------------------------- /types/shared.d.ts: -------------------------------------------------------------------------------- 1 | export declare function dispatchCustomEvent(name: any, elm: any, detail: any, cancelable?: boolean): boolean; 2 | -------------------------------------------------------------------------------- /types/svelte-jsx.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare namespace svelte.JSX { 4 | type EventHandler< 5 | E extends Event = Event, 6 | T extends EventTarget = HTMLElement 7 | > = (event: E & { currentTarget: EventTarget & T }) => any; 8 | 9 | interface HTMLProps { 10 | onezgdragstart?: EventHandler; 11 | onezgdragmove?: EventHandler; 12 | onezgdragstop?: EventHandler; 13 | onezgpinchstart?: EventHandler; 14 | onezgpinchmove?: EventHandler; 15 | onezgpinchend?: EventHandler; 16 | onezglongpress?: EventHandler; 17 | } 18 | } 19 | --------------------------------------------------------------------------------