diff options
Diffstat (limited to 'ui/static/js/touch_handler.js')
-rw-r--r-- | ui/static/js/touch_handler.js | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/ui/static/js/touch_handler.js b/ui/static/js/touch_handler.js new file mode 100644 index 00000000..69488a50 --- /dev/null +++ b/ui/static/js/touch_handler.js @@ -0,0 +1,94 @@ +class TouchHandler { + constructor() { + this.reset(); + } + + reset() { + this.touch = { + start: {x: -1, y: -1}, + move: {x: -1, y: -1}, + element: null + }; + } + + calculateDistance() { + if (this.touch.start.x >= -1 && this.touch.move.x >= -1) { + let horizontalDistance = Math.abs(this.touch.move.x - this.touch.start.x); + let verticalDistance = Math.abs(this.touch.move.y - this.touch.start.y); + + if (horizontalDistance > 30 && verticalDistance < 70) { + return this.touch.move.x - this.touch.start.x; + } + } + + return 0; + } + + findElement(element) { + if (element.classList.contains("touch-item")) { + return element; + } + + return DomHelper.findParent(element, "touch-item"); + } + + onTouchStart(event) { + if (event.touches === undefined || event.touches.length !== 1) { + return; + } + + this.reset(); + this.touch.start.x = event.touches[0].clientX; + this.touch.start.y = event.touches[0].clientY; + this.touch.element = this.findElement(event.touches[0].target); + } + + onTouchMove(event) { + if (event.touches === undefined || event.touches.length !== 1 || this.element === null) { + return; + } + + this.touch.move.x = event.touches[0].clientX; + this.touch.move.y = event.touches[0].clientY; + + let distance = this.calculateDistance(); + let absDistance = Math.abs(distance); + + if (absDistance > 0) { + let opacity = 1 - (absDistance > 75 ? 0.9 : absDistance / 75 * 0.9); + let tx = distance > 75 ? 75 : (distance < -75 ? -75 : distance); + + this.touch.element.style.opacity = opacity; + this.touch.element.style.transform = "translateX(" + tx + "px)"; + } + } + + onTouchEnd(event) { + if (event.touches === undefined) { + return; + } + + if (this.touch.element !== null) { + let distance = Math.abs(this.calculateDistance()); + + if (distance > 75) { + EntryHandler.toggleEntryStatus(this.touch.element); + } + this.touch.element.style.opacity = 1; + this.touch.element.style.transform = "none"; + } + + this.reset(); + } + + listen() { + let elements = document.querySelectorAll(".touch-item"); + + elements.forEach((element) => { + element.addEventListener("touchstart", (e) => this.onTouchStart(e), false); + element.addEventListener("touchmove", (e) => this.onTouchMove(e), false); + element.addEventListener("touchend", (e) => this.onTouchEnd(e), false); + element.addEventListener("touchcancel", () => this.reset(), false); + }); + } +} |