/** * -------------------------------------------------------------------------- * Bootstrap (v5.2.3): util/swipe.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ import Config from './config' import EventHandler from '../dom/event-handler' import { execute } from './index' /** * Constants */ const NAME = 'swipe' const EVENT_KEY = '.bs.swipe' const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` const EVENT_TOUCHEND = `touchend${EVENT_KEY}` const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` const EVENT_POINTERUP = `pointerup${EVENT_KEY}` const POINTER_TYPE_TOUCH = 'touch' const POINTER_TYPE_PEN = 'pen' const CLASS_NAME_POINTER_EVENT = 'pointer-event' const SWIPE_THRESHOLD = 40 const Default = { endCallback: null, leftCallback: null, rightCallback: null } const DefaultType = { endCallback: '(function|null)', leftCallback: '(function|null)', rightCallback: '(function|null)' } /** * Class definition */ class Swipe extends Config { constructor(element, config) { super() this._element = element if (!element || !Swipe.isSupported()) { return } this._config = this._getConfig(config) this._deltaX = 0 this._supportPointerEvents = Boolean(window.PointerEvent) this._initEvents() } // Getters static get Default() { return Default } static get DefaultType() { return DefaultType } static get NAME() { return NAME } // Public dispose() { EventHandler.off(this._element, EVENT_KEY) } // Private _start(event) { if (!this._supportPointerEvents) { this._deltaX = event.touches[0].clientX return } if (this._eventIsPointerPenTouch(event)) { this._deltaX = event.clientX } } _end(event) { if (this._eventIsPointerPenTouch(event)) { this._deltaX = event.clientX - this._deltaX } this._handleSwipe() execute(this._config.endCallback) } _move(event) { this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX } _handleSwipe() { const absDeltaX = Math.abs(this._deltaX) if (absDeltaX <= SWIPE_THRESHOLD) { return } const direction = absDeltaX / this._deltaX this._deltaX = 0 if (!direction) { return } execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback) } _initEvents() { if (this._supportPointerEvents) { EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)) EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)) this._element.classList.add(CLASS_NAME_POINTER_EVENT) } else { EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)) EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)) EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)) } } _eventIsPointerPenTouch(event) { return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH) } // Static static isSupported() { return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 } } export default Swipe