@ribajs/extras
Advanced tools
Comparing version 1.9.0-alpha.0 to 1.9.0-alpha.1
@@ -1,2 +0,2 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { Binder } from "@ribajs/core"; | ||
/** | ||
@@ -3,0 +3,0 @@ * rv-data-scroll-position |
@@ -17,67 +17,82 @@ "use strict"; | ||
exports.dataScrollPositionYBinder = { | ||
name: 'data-scroll-position-y', | ||
customData: {}, | ||
bind() { | ||
if (!this.customData) { | ||
this.customData = {}; | ||
name: "data-scroll-position-y", | ||
customData: {}, | ||
bind() { | ||
if (!this.customData) { | ||
this.customData = {}; | ||
} | ||
this.customData.onScroll = () => { | ||
if (this.customData.elementSelector === "window") { | ||
const element = this.customData.watchScrollOnElement; | ||
if (element.scrollY <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = "top"; | ||
} else if ( | ||
element.innerHeight + | ||
element.pageYOffset + | ||
this.customData.offsetBottom >= | ||
document.body.offsetHeight | ||
) { | ||
this.el.dataset.scrollPositionY = "bottom"; | ||
} else { | ||
this.el.dataset.scrollPositionY = "scrolled"; | ||
} | ||
this.customData.onScroll = () => { | ||
if (this.customData.elementSelector === 'window') { | ||
const element = this.customData.watchScrollOnElement; | ||
if (element.scrollY <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = 'top'; | ||
} | ||
else if ((element.innerHeight + element.pageYOffset + this.customData.offsetBottom) >= document.body.offsetHeight) { | ||
this.el.dataset.scrollPositionY = 'bottom'; | ||
} | ||
else { | ||
this.el.dataset.scrollPositionY = 'scrolled'; | ||
} | ||
} | ||
else { | ||
const element = this.customData.watchScrollOnElement; | ||
if (element.scrollTop <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = 'top'; | ||
} | ||
else if ((element.scrollTop + this.customData.offsetBottom) >= element.scrollHeight - element.clientHeight) { | ||
this.el.dataset.scrollPositionY = 'bottom'; | ||
} | ||
else { | ||
this.el.dataset.scrollPositionY = 'scrolled'; | ||
} | ||
} | ||
}; | ||
}, | ||
routine(el, elementSelector = 'window') { | ||
// Remove old scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener('scroll', core_1.Utils.debounce.bind(this, this.customData.onScroll.bind(this))); | ||
} else { | ||
const element = this.customData.watchScrollOnElement; | ||
if (element.scrollTop <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = "top"; | ||
} else if ( | ||
element.scrollTop + this.customData.offsetBottom >= | ||
element.scrollHeight - element.clientHeight | ||
) { | ||
this.el.dataset.scrollPositionY = "bottom"; | ||
} else { | ||
this.el.dataset.scrollPositionY = "scrolled"; | ||
} | ||
// Set new element to watch for the scroll event | ||
if (elementSelector === 'window') { | ||
this.customData.watchScrollOnElement = window; | ||
} | ||
else if (elementSelector === 'this') { | ||
this.customData.watchScrollOnElement = this.el; | ||
} | ||
else { | ||
this.customData.watchScrollOnElement = document.querySelector(elementSelector); | ||
} | ||
// Watch new element for scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
// console.debug('addEventListener', this.customData.watchScrollOnElement); | ||
this.customData.watchScrollOnElement.addEventListener('scroll', core_1.Utils.debounce(this.customData.onScroll.bind(this)), { passive: true }); | ||
} | ||
this.customData.offsetTop = Number(this.el.dataset.offsetTop) || DEFAULT_OFFSET; | ||
this.customData.offsetBottom = Number(this.el.dataset.offsetBottom) || DEFAULT_OFFSET; | ||
this.customData.elementSelector = elementSelector; | ||
// inital scroll position | ||
this.customData.onScroll(); | ||
}, | ||
unbind() { | ||
// Remove old scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener('scroll', core_1.Utils.debounce(this.customData.onScroll.bind(this))); | ||
} | ||
}, | ||
} | ||
}; | ||
}, | ||
routine(el, elementSelector = "window") { | ||
// Remove old scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener( | ||
"scroll", | ||
core_1.Utils.debounce.bind(this, this.customData.onScroll.bind(this)) | ||
); | ||
} | ||
// Set new element to watch for the scroll event | ||
if (elementSelector === "window") { | ||
this.customData.watchScrollOnElement = window; | ||
} else if (elementSelector === "this") { | ||
this.customData.watchScrollOnElement = this.el; | ||
} else { | ||
this.customData.watchScrollOnElement = document.querySelector( | ||
elementSelector | ||
); | ||
} | ||
// Watch new element for scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
// console.debug('addEventListener', this.customData.watchScrollOnElement); | ||
this.customData.watchScrollOnElement.addEventListener( | ||
"scroll", | ||
core_1.Utils.debounce(this.customData.onScroll.bind(this)), | ||
{ passive: true } | ||
); | ||
} | ||
this.customData.offsetTop = | ||
Number(this.el.dataset.offsetTop) || DEFAULT_OFFSET; | ||
this.customData.offsetBottom = | ||
Number(this.el.dataset.offsetBottom) || DEFAULT_OFFSET; | ||
this.customData.elementSelector = elementSelector; | ||
// inital scroll position | ||
this.customData.onScroll(); | ||
}, | ||
unbind() { | ||
// Remove old scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener( | ||
"scroll", | ||
core_1.Utils.debounce(this.customData.onScroll.bind(this)) | ||
); | ||
} | ||
}, | ||
}; |
@@ -1,4 +0,4 @@ | ||
export { dataScrollPositionYBinder } from './data-scroll-position-y.binder'; | ||
export { touchEventsBinder } from './touch-events.binder'; | ||
export { autoscrollBinder } from './scrollbar-autoscroll.binder'; | ||
export { scrollbarDraggableBinder } from './scrollbar-draggable.binder'; | ||
export { dataScrollPositionYBinder } from "./data-scroll-position-y.binder"; | ||
export { touchEventsBinder } from "./touch-events.binder"; | ||
export { autoscrollBinder } from "./scrollbar-autoscroll.binder"; | ||
export { scrollbarDraggableBinder } from "./scrollbar-draggable.binder"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var data_scroll_position_y_binder_1 = require("./data-scroll-position-y.binder"); | ||
exports.dataScrollPositionYBinder = data_scroll_position_y_binder_1.dataScrollPositionYBinder; | ||
exports.dataScrollPositionYBinder = | ||
data_scroll_position_y_binder_1.dataScrollPositionYBinder; | ||
var touch_events_binder_1 = require("./touch-events.binder"); | ||
@@ -10,2 +11,3 @@ exports.touchEventsBinder = touch_events_binder_1.touchEventsBinder; | ||
var scrollbar_draggable_binder_1 = require("./scrollbar-draggable.binder"); | ||
exports.scrollbarDraggableBinder = scrollbar_draggable_binder_1.scrollbarDraggableBinder; | ||
exports.scrollbarDraggableBinder = | ||
scrollbar_draggable_binder_1.scrollbarDraggableBinder; |
@@ -1,2 +0,2 @@ | ||
import { Binder, eventHandlerFunction } from '@ribajs/core'; | ||
import { Binder, eventHandlerFunction } from "@ribajs/core"; | ||
/** | ||
@@ -3,0 +3,0 @@ * Binds an event handler on the element. |
@@ -8,40 +8,39 @@ "use strict"; | ||
exports.onEventBinder = { | ||
name: 'on-*', | ||
function: true, | ||
priority: 1000, | ||
bind(el) { | ||
if (!this.customData) { | ||
this.customData = { | ||
handler: null, | ||
}; | ||
} | ||
}, | ||
unbind(el) { | ||
if (this.customData.handler) { | ||
if (this.args === null) { | ||
throw new Error('args is null'); | ||
} | ||
const eventName = this.args[0]; | ||
jquery_module_1.JQuery(el).off(eventName, this.customData.handler); | ||
} | ||
}, | ||
routine(el, value) { | ||
if (this.args === null) { | ||
throw new Error('args is null'); | ||
} | ||
const eventName = this.args[0]; | ||
if (this.customData.handler) { | ||
jquery_module_1.JQuery(el).off(eventName, this.customData.handler); | ||
} | ||
this.customData.handler = this.eventHandler(value, el); | ||
try { | ||
jquery_module_1.JQuery(el).on(eventName, (this.customData.handler)); | ||
} | ||
catch (error) { | ||
console.warn(error); | ||
jquery_module_1.JQuery(el).on(eventName, (event) => { | ||
this.customData.handler(event); | ||
}); | ||
} | ||
}, | ||
name: "on-*", | ||
function: true, | ||
priority: 1000, | ||
bind(el) { | ||
if (!this.customData) { | ||
this.customData = { | ||
handler: null, | ||
}; | ||
} | ||
}, | ||
unbind(el) { | ||
if (this.customData.handler) { | ||
if (this.args === null) { | ||
throw new Error("args is null"); | ||
} | ||
const eventName = this.args[0]; | ||
jquery_module_1.JQuery(el).off(eventName, this.customData.handler); | ||
} | ||
}, | ||
routine(el, value) { | ||
if (this.args === null) { | ||
throw new Error("args is null"); | ||
} | ||
const eventName = this.args[0]; | ||
if (this.customData.handler) { | ||
jquery_module_1.JQuery(el).off(eventName, this.customData.handler); | ||
} | ||
this.customData.handler = this.eventHandler(value, el); | ||
try { | ||
jquery_module_1.JQuery(el).on(eventName, this.customData.handler); | ||
} catch (error) { | ||
console.warn(error); | ||
jquery_module_1.JQuery(el).on(eventName, (event) => { | ||
this.customData.handler(event); | ||
}); | ||
} | ||
}, | ||
}; |
@@ -6,50 +6,53 @@ "use strict"; | ||
const riba = new core_1.Riba(); | ||
riba.module.binder.regists([on_event_binder_1.onEventBinder, core_1.valueBinder]); | ||
describe('riba.binders', () => { | ||
let element; | ||
let fragment; | ||
let model = {}; | ||
const blurAll = () => { | ||
const tmp = document.createElement('input'); | ||
fragment.appendChild(tmp); | ||
tmp.focus(); | ||
fragment.removeChild(tmp); | ||
}; | ||
beforeEach(() => { | ||
fragment = document.createDocumentFragment(); | ||
element = document.createElement('input'); | ||
element.setAttribute('type', 'text'); | ||
fragment.appendChild(element); | ||
model = {}; | ||
riba.module.binder.regists([ | ||
on_event_binder_1.onEventBinder, | ||
core_1.valueBinder, | ||
]); | ||
describe("riba.binders", () => { | ||
let element; | ||
let fragment; | ||
let model = {}; | ||
const blurAll = () => { | ||
const tmp = document.createElement("input"); | ||
fragment.appendChild(tmp); | ||
tmp.focus(); | ||
fragment.removeChild(tmp); | ||
}; | ||
beforeEach(() => { | ||
fragment = document.createDocumentFragment(); | ||
element = document.createElement("input"); | ||
element.setAttribute("type", "text"); | ||
fragment.appendChild(element); | ||
model = {}; | ||
}); | ||
describe("on-*", () => { | ||
it("on-click: Watch's the click event", () => { | ||
element.className = "foobar remove-me"; | ||
model.onClick = jest.fn(); | ||
element.setAttribute("rv-on-click", "onClick"); | ||
riba.bind(fragment, model); | ||
// Simulates the click | ||
element.click(); | ||
expect(model.onClick).toHaveBeenCalled(); | ||
}); | ||
describe('on-*', () => { | ||
it('on-click: Watch\'s the click event', () => { | ||
element.className = 'foobar remove-me'; | ||
model.onClick = jest.fn(); | ||
element.setAttribute('rv-on-click', 'onClick'); | ||
riba.bind(fragment, model); | ||
// Simulates the click | ||
element.click(); | ||
expect(model.onClick).toHaveBeenCalled(); | ||
}); | ||
it('on-change: Watch\'s the change event', () => { | ||
element.className = 'foobar remove-me'; | ||
model.onChange = jest.fn(); | ||
model.onFocus = jest.fn(); | ||
model.onFocusout = jest.fn(); | ||
model.value = 'test'; | ||
element.setAttribute('rv-on-change', 'onChange'); | ||
element.setAttribute('rv-on-focus', 'onFocus'); | ||
element.setAttribute('rv-on-blur', 'onFocusout'); | ||
element.setAttribute('rv-value', 'value'); | ||
riba.bind(fragment, model); | ||
// Trigger the change event | ||
element.focus(); | ||
model.value = 'this should trigger the change event!'; | ||
blurAll(); // Focus out all focused elements | ||
expect(model.onChange).toHaveBeenCalled(); | ||
expect(model.onFocus).toHaveBeenCalled(); | ||
expect(model.onFocusout).toHaveBeenCalled(); | ||
}); | ||
it("on-change: Watch's the change event", () => { | ||
element.className = "foobar remove-me"; | ||
model.onChange = jest.fn(); | ||
model.onFocus = jest.fn(); | ||
model.onFocusout = jest.fn(); | ||
model.value = "test"; | ||
element.setAttribute("rv-on-change", "onChange"); | ||
element.setAttribute("rv-on-focus", "onFocus"); | ||
element.setAttribute("rv-on-blur", "onFocusout"); | ||
element.setAttribute("rv-value", "value"); | ||
riba.bind(fragment, model); | ||
// Trigger the change event | ||
element.focus(); | ||
model.value = "this should trigger the change event!"; | ||
blurAll(); // Focus out all focused elements | ||
expect(model.onChange).toHaveBeenCalled(); | ||
expect(model.onFocus).toHaveBeenCalled(); | ||
expect(model.onFocusout).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); |
@@ -1,3 +0,3 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { AutoscrollOptions } from '../services/autoscroll.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { AutoscrollOptions } from "../services/autoscroll.service"; | ||
/** | ||
@@ -4,0 +4,0 @@ * Slideout click event to toggle the slideout |
@@ -9,26 +9,28 @@ "use strict"; | ||
exports.autoscrollBinder = { | ||
name: 'autoscroll', | ||
routine(el, options) { | ||
this.customData = this.customData || {}; | ||
if (options && options.width && core_1.Utils.isString(options.width)) { | ||
if (options.width === '100vw') { | ||
el.style.width = options.width; | ||
} | ||
else { | ||
el.style.width = options.width; | ||
} | ||
} | ||
el.classList.add(`rv-autoscroll-${options.angle}`); | ||
setTimeout(() => { | ||
if (this.customData.autoscroll) { | ||
this.customData.autoscroll.removeEventListeners(); | ||
} | ||
this.customData.autoscroll = new autoscroll_service_1.Autoscroll(el, options); | ||
}, 1000); | ||
}, | ||
unbind() { | ||
if (this.customData.autoscroll) { | ||
this.customData.autoscroll.removeEventListeners(); | ||
} | ||
}, | ||
name: "autoscroll", | ||
routine(el, options) { | ||
this.customData = this.customData || {}; | ||
if (options && options.width && core_1.Utils.isString(options.width)) { | ||
if (options.width === "100vw") { | ||
el.style.width = options.width; | ||
} else { | ||
el.style.width = options.width; | ||
} | ||
} | ||
el.classList.add(`rv-autoscroll-${options.angle}`); | ||
setTimeout(() => { | ||
if (this.customData.autoscroll) { | ||
this.customData.autoscroll.removeEventListeners(); | ||
} | ||
this.customData.autoscroll = new autoscroll_service_1.Autoscroll( | ||
el, | ||
options | ||
); | ||
}, 1000); | ||
}, | ||
unbind() { | ||
if (this.customData.autoscroll) { | ||
this.customData.autoscroll.removeEventListeners(); | ||
} | ||
}, | ||
}; |
@@ -1,3 +0,3 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { DragscrollOptions } from '../services/dragscroll.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { DragscrollOptions } from "../services/dragscroll.service"; | ||
/** | ||
@@ -4,0 +4,0 @@ * dragscroll |
@@ -8,15 +8,18 @@ "use strict"; | ||
exports.scrollbarDraggableBinder = { | ||
name: 'scrollbar-draggable', | ||
routine(el, options) { | ||
this.customData = this.customData || {}; | ||
if (this.customData.dragscroll) { | ||
this.customData.dragscroll.removeEventListeners(); | ||
} | ||
this.customData.dragscroll = new dragscroll_service_1.Dragscroll(el, options); | ||
}, | ||
unbind() { | ||
if (this.customData.dragscroll) { | ||
this.customData.dragscroll.removeEventListeners(); | ||
} | ||
}, | ||
name: "scrollbar-draggable", | ||
routine(el, options) { | ||
this.customData = this.customData || {}; | ||
if (this.customData.dragscroll) { | ||
this.customData.dragscroll.removeEventListeners(); | ||
} | ||
this.customData.dragscroll = new dragscroll_service_1.Dragscroll( | ||
el, | ||
options | ||
); | ||
}, | ||
unbind() { | ||
if (this.customData.dragscroll) { | ||
this.customData.dragscroll.removeEventListeners(); | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { Binder } from "@ribajs/core"; | ||
export declare const touchEventsBinder: Binder<string>; |
@@ -5,35 +5,37 @@ "use strict"; | ||
exports.touchEventsBinder = { | ||
name: 'touch-events', | ||
bind(el) { | ||
if (!this.customData) { | ||
this.customData = {}; | ||
} | ||
this.customData.touchEventService = new touch_events_service_1.TouchEventService(el); | ||
el.addEventListener('tapstart', (event) => { | ||
console.debug('tapstart detail', event.detail); | ||
}); | ||
el.addEventListener('taphold', (event) => { | ||
console.debug('taphold detail', event.detail); | ||
}); | ||
el.addEventListener('doubletap', (event) => { | ||
console.debug('doubletap detail', event.detail); | ||
}); | ||
el.addEventListener('swipe', (event) => { | ||
console.debug('swipe detail', event.detail); | ||
}); | ||
el.addEventListener('touchstart', (event) => { | ||
console.debug('touchstart', event); | ||
}); | ||
el.addEventListener('touchmove', (event) => { | ||
console.debug('touchmove', event); | ||
}); | ||
}, | ||
unbind(el) { | ||
if (this.customData.touchEventService) { | ||
this.customData.touchEventService.removeEventListeners(); | ||
} | ||
}, | ||
routine(el, value) { | ||
// nothing | ||
}, | ||
name: "touch-events", | ||
bind(el) { | ||
if (!this.customData) { | ||
this.customData = {}; | ||
} | ||
this.customData.touchEventService = new touch_events_service_1.TouchEventService( | ||
el | ||
); | ||
el.addEventListener("tapstart", (event) => { | ||
console.debug("tapstart detail", event.detail); | ||
}); | ||
el.addEventListener("taphold", (event) => { | ||
console.debug("taphold detail", event.detail); | ||
}); | ||
el.addEventListener("doubletap", (event) => { | ||
console.debug("doubletap detail", event.detail); | ||
}); | ||
el.addEventListener("swipe", (event) => { | ||
console.debug("swipe detail", event.detail); | ||
}); | ||
el.addEventListener("touchstart", (event) => { | ||
console.debug("touchstart", event); | ||
}); | ||
el.addEventListener("touchmove", (event) => { | ||
console.debug("touchmove", event); | ||
}); | ||
}, | ||
unbind(el) { | ||
if (this.customData.touchEventService) { | ||
this.customData.touchEventService.removeEventListeners(); | ||
} | ||
}, | ||
routine(el, value) { | ||
// nothing | ||
}, | ||
}; |
@@ -5,22 +5,24 @@ "use strict"; | ||
const touch_events_binder_1 = require("./touch-events.binder"); | ||
describe('riba.binders', () => { | ||
let el; | ||
const riba = new core_1.Riba(); | ||
riba.module.binder.regist(touch_events_binder_1.TouchEventsBinder); | ||
beforeEach(() => { | ||
el = document.createElement('div'); | ||
document.body.appendChild(el); | ||
describe("riba.binders", () => { | ||
let el; | ||
const riba = new core_1.Riba(); | ||
riba.module.binder.regist(touch_events_binder_1.TouchEventsBinder); | ||
beforeEach(() => { | ||
el = document.createElement("div"); | ||
document.body.appendChild(el); | ||
}); | ||
afterEach(() => { | ||
if (!el.parentNode) { | ||
throw new Error("el.parentNode is not defined!"); | ||
} | ||
el.parentNode.removeChild(el); | ||
}); | ||
describe("TouchEvents", () => { | ||
it("sets the element's text content", () => { | ||
riba.binders["test-app-example"].routine(el, "<em>hello</em>"); | ||
expect(el.innerHTML).toEqual( | ||
"<em>hello</em> from test-app-example <strong>binder</strong>!" | ||
); | ||
}); | ||
afterEach(() => { | ||
if (!el.parentNode) { | ||
throw new Error('el.parentNode is not defined!'); | ||
} | ||
el.parentNode.removeChild(el); | ||
}); | ||
describe('TouchEvents', () => { | ||
it('sets the element\'s text content', () => { | ||
riba.binders['test-app-example'].routine(el, '<em>hello</em>'); | ||
expect(el.innerHTML).toEqual('<em>hello</em> from test-app-example <strong>binder</strong>!'); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
export * from './binders'; | ||
export * from './services'; | ||
import { RibaModule } from '@ribajs/core'; | ||
export * from "./binders"; | ||
export * from "./services"; | ||
import { RibaModule } from "@ribajs/core"; | ||
export declare const extrasModule: RibaModule; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
var __importStar = | ||
(this && this.__importStar) || | ||
function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
if (mod != null) | ||
for (var k in mod) | ||
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -23,6 +27,9 @@ __export(require("./binders")); | ||
exports.extrasModule = { | ||
formatters: {}, | ||
binders, | ||
services: { TouchEventService: services_1.TouchEventService, Autoscroll: services_1.Autoscroll }, | ||
components: {}, | ||
formatters: {}, | ||
binders, | ||
services: { | ||
TouchEventService: services_1.TouchEventService, | ||
Autoscroll: services_1.Autoscroll, | ||
}, | ||
components: {}, | ||
}; |
@@ -1,6 +0,6 @@ | ||
export * from './services'; | ||
export * from './binders'; | ||
import { extrasModule } from './extras.module'; | ||
export * from "./services"; | ||
export * from "./binders"; | ||
import { extrasModule } from "./extras.module"; | ||
export { extrasModule }; | ||
export default extrasModule; | ||
export * from './types'; | ||
export * from "./types"; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
@@ -5,0 +5,0 @@ Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,2 +0,2 @@ | ||
import { RibaModule } from '@ribajs/core'; | ||
import { RibaModule } from "@ribajs/core"; | ||
export declare const jqueryModule: RibaModule; |
"use strict"; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
var __importStar = | ||
(this && this.__importStar) || | ||
function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
if (mod != null) | ||
for (var k in mod) | ||
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -15,6 +19,6 @@ const binders = __importStar(require("./binders")); | ||
exports.jqueryModule = { | ||
formatters: {}, | ||
binders, | ||
services: {}, | ||
components: {}, | ||
formatters: {}, | ||
binders, | ||
services: {}, | ||
components: {}, | ||
}; |
export interface AutoscrollOptions { | ||
angle?: 'vertical' | 'horizontal'; | ||
direction?: 1 | -1; | ||
velocity?: number; | ||
width?: string; | ||
pauseOnHover?: boolean; | ||
angle?: "vertical" | "horizontal"; | ||
direction?: 1 | -1; | ||
velocity?: number; | ||
width?: string; | ||
pauseOnHover?: boolean; | ||
} | ||
export declare class Autoscroll { | ||
protected direction: number; | ||
protected limit: number; | ||
protected options: AutoscrollOptions; | ||
protected el: HTMLElement; | ||
protected pause: boolean; | ||
protected velocity: number; | ||
protected move: number; | ||
protected lastMove: number; | ||
protected position: number; | ||
protected angle: 'horizontal' | 'vertical'; | ||
protected pauseOnHover: boolean; | ||
constructor(el: HTMLElement, options?: AutoscrollOptions); | ||
removeEventListeners(): void; | ||
protected onMouseIn(): void; | ||
protected onMouseOut(): void; | ||
protected onResize(): void; | ||
protected onTouchEnd(): void; | ||
protected getPosition(): number; | ||
protected getLimit(el: HTMLElement, options: AutoscrollOptions): number; | ||
protected render(interp: number): void; | ||
protected update(delta: number): void; | ||
protected scroll(move: number): void; | ||
protected direction: number; | ||
protected limit: number; | ||
protected options: AutoscrollOptions; | ||
protected el: HTMLElement; | ||
protected pause: boolean; | ||
protected velocity: number; | ||
protected move: number; | ||
protected lastMove: number; | ||
protected position: number; | ||
protected angle: "horizontal" | "vertical"; | ||
protected pauseOnHover: boolean; | ||
constructor(el: HTMLElement, options?: AutoscrollOptions); | ||
removeEventListeners(): void; | ||
protected onMouseIn(): void; | ||
protected onMouseOut(): void; | ||
protected onResize(): void; | ||
protected onTouchEnd(): void; | ||
protected getPosition(): number; | ||
protected getLimit(el: HTMLElement, options: AutoscrollOptions): number; | ||
protected render(interp: number): void; | ||
protected update(delta: number): void; | ||
protected scroll(move: number): void; | ||
} |
@@ -6,100 +6,111 @@ "use strict"; | ||
class Autoscroll { | ||
constructor(el, options = {}) { | ||
this.direction = 1; | ||
this.pause = false; | ||
this.velocity = 0.008; | ||
this.move = 0; | ||
this.lastMove = 0; | ||
this.angle = 'horizontal'; | ||
this.pauseOnHover = true; | ||
this.el = el; | ||
this.options = options; | ||
this.direction = this.options.direction || this.direction; | ||
this.velocity = this.options.velocity || this.velocity; | ||
this.angle = this.options.angle || this.angle; | ||
this.pauseOnHover = typeof (this.options.pauseOnHover) === 'boolean' ? this.options.pauseOnHover : this.pauseOnHover; | ||
this.limit = this.getLimit(this.el, this.options); | ||
this.position = this.getPosition(); | ||
window.addEventListener('resize', this.onResize.bind(this)); | ||
if (this.direction === -1) { | ||
// start right | ||
this.el.scrollLeft = this.limit; | ||
} | ||
else { | ||
// start left | ||
this.el.scrollLeft = 0; | ||
} | ||
this.el.addEventListener('mouseenter', this.onMouseIn.bind(this)); | ||
this.el.addEventListener('mouseover', this.onMouseIn.bind(this)); | ||
this.el.addEventListener('mouseout', this.onMouseOut.bind(this)); | ||
this.el.addEventListener('mouseleave', this.onMouseOut.bind(this)); | ||
this.el.addEventListener('mouseup', this.onTouchEnd.bind(this)); | ||
this.el.addEventListener('touchend', this.onTouchEnd.bind(this)); | ||
gameloop_service_1.Gameloop.startLoop({ maxFPS: 60 }, this.render.bind(this), this.update.bind(this)); | ||
constructor(el, options = {}) { | ||
this.direction = 1; | ||
this.pause = false; | ||
this.velocity = 0.008; | ||
this.move = 0; | ||
this.lastMove = 0; | ||
this.angle = "horizontal"; | ||
this.pauseOnHover = true; | ||
this.el = el; | ||
this.options = options; | ||
this.direction = this.options.direction || this.direction; | ||
this.velocity = this.options.velocity || this.velocity; | ||
this.angle = this.options.angle || this.angle; | ||
this.pauseOnHover = | ||
typeof this.options.pauseOnHover === "boolean" | ||
? this.options.pauseOnHover | ||
: this.pauseOnHover; | ||
this.limit = this.getLimit(this.el, this.options); | ||
this.position = this.getPosition(); | ||
window.addEventListener("resize", this.onResize.bind(this)); | ||
if (this.direction === -1) { | ||
// start right | ||
this.el.scrollLeft = this.limit; | ||
} else { | ||
// start left | ||
this.el.scrollLeft = 0; | ||
} | ||
removeEventListeners() { | ||
window.removeEventListener('resize', this.onResize.bind(this)); | ||
this.el.removeEventListener('mouseenter', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('mouseover', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('mouseout', this.onMouseOut.bind(this)); | ||
this.el.removeEventListener('mouseleave', this.onMouseOut.bind(this)); | ||
this.el.removeEventListener('mouseup', this.onTouchEnd.bind(this)); | ||
this.el.removeEventListener('touchend', this.onTouchEnd.bind(this)); | ||
this.el.addEventListener("mouseenter", this.onMouseIn.bind(this)); | ||
this.el.addEventListener("mouseover", this.onMouseIn.bind(this)); | ||
this.el.addEventListener("mouseout", this.onMouseOut.bind(this)); | ||
this.el.addEventListener("mouseleave", this.onMouseOut.bind(this)); | ||
this.el.addEventListener("mouseup", this.onTouchEnd.bind(this)); | ||
this.el.addEventListener("touchend", this.onTouchEnd.bind(this)); | ||
gameloop_service_1.Gameloop.startLoop( | ||
{ maxFPS: 60 }, | ||
this.render.bind(this), | ||
this.update.bind(this) | ||
); | ||
} | ||
removeEventListeners() { | ||
window.removeEventListener("resize", this.onResize.bind(this)); | ||
this.el.removeEventListener("mouseenter", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("mouseover", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("mouseout", this.onMouseOut.bind(this)); | ||
this.el.removeEventListener("mouseleave", this.onMouseOut.bind(this)); | ||
this.el.removeEventListener("mouseup", this.onTouchEnd.bind(this)); | ||
this.el.removeEventListener("touchend", this.onTouchEnd.bind(this)); | ||
} | ||
onMouseIn() { | ||
if (this.pauseOnHover) { | ||
this.pause = true; | ||
} | ||
onMouseIn() { | ||
if (this.pauseOnHover) { | ||
this.pause = true; | ||
} | ||
} | ||
onMouseOut() { | ||
this.pause = false; | ||
} | ||
onResize() { | ||
this.limit = this.getLimit(this.el, this.options); | ||
this.pause = false; | ||
} | ||
onTouchEnd() { | ||
this.position = | ||
this.angle === "vertical" ? this.el.scrollTop : this.el.scrollLeft; | ||
} | ||
getPosition() { | ||
return ( | ||
(this.angle === "vertical" ? this.el.scrollTop : this.el.scrollLeft) || 0 | ||
); | ||
} | ||
getLimit(el, options) { | ||
return this.angle === "vertical" | ||
? utils_service_1.Utils.getScrollPosition(el).maxY | ||
: utils_service_1.Utils.getScrollPosition(el).maxX; | ||
} | ||
render(interp) { | ||
if (this.pause) { | ||
return; | ||
} | ||
onMouseOut() { | ||
this.pause = false; | ||
const move = this.lastMove + (this.move - this.lastMove) * interp; | ||
this.move = 0; | ||
this.scroll(move); | ||
} | ||
update(delta) { | ||
// console.debug('delta', delta); | ||
if (this.pause) { | ||
return; | ||
} | ||
onResize() { | ||
this.limit = this.getLimit(this.el, this.options); | ||
this.pause = false; | ||
this.lastMove = this.move; | ||
this.move += this.velocity * delta; | ||
// Switch directions if we go too far | ||
// `Math.floor()` rounds down, `Math.ceil()` rounds up, `Math.round()` rounds to the nearest integer | ||
if (Math.floor(this.position) <= 0 && this.direction !== 1) { | ||
this.direction = 1; | ||
} | ||
onTouchEnd() { | ||
this.position = this.angle === 'vertical' ? this.el.scrollTop : this.el.scrollLeft; | ||
if (Math.ceil(this.position) >= this.limit && this.direction !== -1) { | ||
this.direction = -1; | ||
} | ||
getPosition() { | ||
return (this.angle === 'vertical' ? this.el.scrollTop : this.el.scrollLeft) || 0; | ||
} | ||
scroll(move) { | ||
const newPosition = | ||
this.direction > 0 ? this.position + move : this.position - move; | ||
if (this.angle === "vertical") { | ||
this.el.scrollTop = Math.ceil(newPosition); | ||
} else { | ||
this.el.scrollLeft = Math.ceil(newPosition); | ||
} | ||
getLimit(el, options) { | ||
return this.angle === 'vertical' ? utils_service_1.Utils.getScrollPosition(el).maxY : utils_service_1.Utils.getScrollPosition(el).maxX; | ||
} | ||
render(interp) { | ||
if (this.pause) { | ||
return; | ||
} | ||
const move = (this.lastMove + (this.move - this.lastMove) * interp); | ||
this.move = 0; | ||
this.scroll(move); | ||
} | ||
update(delta) { | ||
// console.debug('delta', delta); | ||
if (this.pause) { | ||
return; | ||
} | ||
this.lastMove = this.move; | ||
this.move += (this.velocity * delta); | ||
// Switch directions if we go too far | ||
// `Math.floor()` rounds down, `Math.ceil()` rounds up, `Math.round()` rounds to the nearest integer | ||
if (Math.floor(this.position) <= 0 && this.direction !== 1) { | ||
this.direction = 1; | ||
} | ||
if (Math.ceil(this.position) >= this.limit && this.direction !== -1) { | ||
this.direction = -1; | ||
} | ||
} | ||
scroll(move) { | ||
const newPosition = this.direction > 0 ? this.position + move : this.position - move; | ||
if (this.angle === 'vertical') { | ||
this.el.scrollTop = Math.ceil(newPosition); | ||
} | ||
else { | ||
this.el.scrollLeft = Math.ceil(newPosition); | ||
} | ||
this.position = newPosition; | ||
} | ||
this.position = newPosition; | ||
} | ||
} | ||
exports.Autoscroll = Autoscroll; |
export interface DragscrollOptions { | ||
preventDefault?: boolean; | ||
detectGlobalMove?: boolean; | ||
preventDefault?: boolean; | ||
detectGlobalMove?: boolean; | ||
} | ||
@@ -10,13 +10,13 @@ /** | ||
export declare class Dragscroll { | ||
private options; | ||
private lastClientX; | ||
private lastClientY; | ||
private el; | ||
private pushed; | ||
constructor(el: HTMLElement, options?: DragscrollOptions); | ||
removeEventListeners(): void; | ||
protected checkDraggable(): void; | ||
protected onMouseDown<EventListener>(e: MouseEvent): void; | ||
protected onMouseUp<EventListener>(e: MouseEvent): void; | ||
protected onMouseMove<EventListener>(e: MouseEvent): void; | ||
private options; | ||
private lastClientX; | ||
private lastClientY; | ||
private el; | ||
private pushed; | ||
constructor(el: HTMLElement, options?: DragscrollOptions); | ||
removeEventListeners(): void; | ||
protected checkDraggable(): void; | ||
protected onMouseDown<EventListener>(e: MouseEvent): void; | ||
protected onMouseUp<EventListener>(e: MouseEvent): void; | ||
protected onMouseMove<EventListener>(e: MouseEvent): void; | ||
} |
@@ -9,78 +9,90 @@ "use strict"; | ||
class Dragscroll { | ||
constructor(el, options = { detectGlobalMove: true, preventDefault: true }) { | ||
this.lastClientX = 0; | ||
this.lastClientY = 0; | ||
this.pushed = false; | ||
this.el = el; | ||
this.options = options; | ||
el.removeEventListener('mousedown', this.onMouseDown.bind(this), false); | ||
el.addEventListener('mousedown', this.onMouseDown.bind(this), false); | ||
window.addEventListener('resize', this.checkDraggable.bind(this)); | ||
// Use global move if your element does not use the full width / height | ||
if (this.options.detectGlobalMove) { | ||
window.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
window.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
window.addEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
window.addEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
} | ||
else { | ||
el.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
el.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
el.addEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
el.addEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
} | ||
// initial | ||
this.checkDraggable(); | ||
constructor(el, options = { detectGlobalMove: true, preventDefault: true }) { | ||
this.lastClientX = 0; | ||
this.lastClientY = 0; | ||
this.pushed = false; | ||
this.el = el; | ||
this.options = options; | ||
el.removeEventListener("mousedown", this.onMouseDown.bind(this), false); | ||
el.addEventListener("mousedown", this.onMouseDown.bind(this), false); | ||
window.addEventListener("resize", this.checkDraggable.bind(this)); | ||
// Use global move if your element does not use the full width / height | ||
if (this.options.detectGlobalMove) { | ||
window.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
window.removeEventListener( | ||
"mousemove", | ||
this.onMouseMove.bind(this), | ||
false | ||
); | ||
window.addEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
window.addEventListener("mousemove", this.onMouseMove.bind(this), false); | ||
} else { | ||
el.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
el.removeEventListener("mousemove", this.onMouseMove.bind(this), false); | ||
el.addEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
el.addEventListener("mousemove", this.onMouseMove.bind(this), false); | ||
} | ||
removeEventListeners() { | ||
window.removeEventListener('resize', this.checkDraggable); | ||
this.el.removeEventListener('mousedown', this.onMouseDown.bind(this), false); | ||
this.el.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
this.el.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
// initial | ||
this.checkDraggable(); | ||
} | ||
removeEventListeners() { | ||
window.removeEventListener("resize", this.checkDraggable); | ||
this.el.removeEventListener( | ||
"mousedown", | ||
this.onMouseDown.bind(this), | ||
false | ||
); | ||
this.el.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
this.el.removeEventListener( | ||
"mousemove", | ||
this.onMouseMove.bind(this), | ||
false | ||
); | ||
} | ||
checkDraggable() { | ||
if (utils_service_1.Utils.isScrollable(this.el)) { | ||
this.el.classList.add("draggable"); | ||
} else { | ||
this.el.classList.remove("draggable"); | ||
} | ||
checkDraggable() { | ||
if (utils_service_1.Utils.isScrollable(this.el)) { | ||
this.el.classList.add('draggable'); | ||
} | ||
else { | ||
this.el.classList.remove('draggable'); | ||
} | ||
} | ||
// protected triggerScrollendEvent(originalEvent: Event) { | ||
// const extraParameters: any = Utils.getScrollPosition(originalEvent.target as HTMLElement); | ||
// extraParameters.originalEvent = originalEvent; | ||
// extraParameters.target = originalEvent.target; | ||
// const scrollendEvent = new CustomEvent('scrollend', { | ||
// detail: extraParameters, | ||
// }); | ||
// this.el.dispatchEvent(scrollendEvent); | ||
// } | ||
onMouseDown(e) { | ||
this.pushed = true; | ||
this.lastClientX = e.clientX; | ||
this.lastClientY = e.clientY; | ||
if (this.options.preventDefault) { | ||
e.preventDefault(); | ||
} | ||
// protected triggerScrollendEvent(originalEvent: Event) { | ||
// const extraParameters: any = Utils.getScrollPosition(originalEvent.target as HTMLElement); | ||
// extraParameters.originalEvent = originalEvent; | ||
// extraParameters.target = originalEvent.target; | ||
// const scrollendEvent = new CustomEvent('scrollend', { | ||
// detail: extraParameters, | ||
// }); | ||
// this.el.dispatchEvent(scrollendEvent); | ||
// } | ||
onMouseDown(e) { | ||
this.pushed = true; | ||
this.lastClientX = e.clientX; | ||
this.lastClientY = e.clientY; | ||
if (this.options.preventDefault) { | ||
e.preventDefault(); | ||
} | ||
onMouseUp(e) { | ||
this.pushed = false; | ||
// this.triggerScrollendEvent(e); | ||
} | ||
onMouseMove(e) { | ||
let newScrollX = 0; | ||
let newScrollY = 0; | ||
if (this.pushed) { | ||
this.el.scrollLeft -= newScrollX = | ||
-this.lastClientX + (this.lastClientX = e.clientX); | ||
this.el.scrollTop -= newScrollY = | ||
-this.lastClientY + (this.lastClientY = e.clientY); | ||
if (this.el === document.body) { | ||
if (document.documentElement) { | ||
this.el = document.documentElement; | ||
} | ||
this.el.scrollLeft -= newScrollX; | ||
this.el.scrollTop -= newScrollY; | ||
} | ||
} | ||
onMouseUp(e) { | ||
this.pushed = false; | ||
// this.triggerScrollendEvent(e); | ||
} | ||
onMouseMove(e) { | ||
let newScrollX = 0; | ||
let newScrollY = 0; | ||
if (this.pushed) { | ||
this.el.scrollLeft -= newScrollX = (-this.lastClientX + (this.lastClientX = e.clientX)); | ||
this.el.scrollTop -= newScrollY = (-this.lastClientY + (this.lastClientY = e.clientY)); | ||
if (this.el === document.body) { | ||
if (document.documentElement) { | ||
this.el = document.documentElement; | ||
} | ||
this.el.scrollLeft -= newScrollX; | ||
this.el.scrollTop -= newScrollY; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
exports.Dragscroll = Dragscroll; |
export declare type RenderCallback = (interp: number) => void; | ||
export declare type UpdateCallback = (delta: number) => void; | ||
export interface GameloopOptions { | ||
maxFPS?: number; | ||
maxFPS?: number; | ||
} | ||
@@ -11,26 +11,30 @@ /** | ||
export declare class Gameloop { | ||
static maxFPS: number; | ||
static startLoop(options?: GameloopOptions, renderCallback?: RenderCallback, updateCallback?: UpdateCallback): void; | ||
protected static renderCallbacks: RenderCallback[]; | ||
protected static updateCallbacks: UpdateCallback[]; | ||
protected static timestep: number; | ||
protected static loopStarted: boolean; | ||
protected static lastFrameTimeMs: number; | ||
protected static delta: number; | ||
protected static fps: number; | ||
protected static framesThisSecond: number; | ||
protected static lastFpsUpdate: number; | ||
protected static setOptions(options: GameloopOptions): void; | ||
/** | ||
* The main / game loop | ||
* @param timestamp | ||
*/ | ||
protected static loop(timestamp: number): void; | ||
protected static begin(timestamp: number, delta: number): void; | ||
protected static render(interp: number): void; | ||
protected static update(delta: number): void; | ||
protected static addRenderCallback(renderCallback: RenderCallback): void; | ||
protected static addUpdateCallback(updateCallback: UpdateCallback): void; | ||
protected static panic(): void; | ||
constructor(options?: GameloopOptions); | ||
static maxFPS: number; | ||
static startLoop( | ||
options?: GameloopOptions, | ||
renderCallback?: RenderCallback, | ||
updateCallback?: UpdateCallback | ||
): void; | ||
protected static renderCallbacks: RenderCallback[]; | ||
protected static updateCallbacks: UpdateCallback[]; | ||
protected static timestep: number; | ||
protected static loopStarted: boolean; | ||
protected static lastFrameTimeMs: number; | ||
protected static delta: number; | ||
protected static fps: number; | ||
protected static framesThisSecond: number; | ||
protected static lastFpsUpdate: number; | ||
protected static setOptions(options: GameloopOptions): void; | ||
/** | ||
* The main / game loop | ||
* @param timestamp | ||
*/ | ||
protected static loop(timestamp: number): void; | ||
protected static begin(timestamp: number, delta: number): void; | ||
protected static render(interp: number): void; | ||
protected static update(delta: number): void; | ||
protected static addRenderCallback(renderCallback: RenderCallback): void; | ||
protected static addUpdateCallback(updateCallback: UpdateCallback): void; | ||
protected static panic(): void; | ||
constructor(options?: GameloopOptions); | ||
} |
@@ -8,84 +8,85 @@ "use strict"; | ||
class Gameloop { | ||
constructor(options = {}) { | ||
Gameloop.setOptions(options); | ||
constructor(options = {}) { | ||
Gameloop.setOptions(options); | ||
} | ||
static startLoop(options = {}, renderCallback, updateCallback) { | ||
this.setOptions(options); | ||
if (renderCallback) { | ||
this.addRenderCallback(renderCallback); | ||
} | ||
static startLoop(options = {}, renderCallback, updateCallback) { | ||
this.setOptions(options); | ||
if (renderCallback) { | ||
this.addRenderCallback(renderCallback); | ||
} | ||
if (updateCallback) { | ||
this.addUpdateCallback(updateCallback); | ||
} | ||
if (!this.loopStarted) { | ||
this.loopStarted = true; | ||
window.requestAnimationFrame(this.loop.bind(this)); | ||
} | ||
if (updateCallback) { | ||
this.addUpdateCallback(updateCallback); | ||
} | ||
static setOptions(options) { | ||
this.maxFPS = typeof (options.maxFPS) === 'number' ? options.maxFPS : this.maxFPS; | ||
if (!this.loopStarted) { | ||
this.loopStarted = true; | ||
window.requestAnimationFrame(this.loop.bind(this)); | ||
} | ||
/** | ||
* The main / game loop | ||
* @param timestamp | ||
*/ | ||
static loop(timestamp) { | ||
// Throttle the frame rate. | ||
if (timestamp < this.lastFrameTimeMs + (1000 / this.maxFPS)) { | ||
requestAnimationFrame(this.loop.bind(this)); | ||
return; | ||
} | ||
const progress = timestamp - this.lastFrameTimeMs; | ||
this.delta += progress; | ||
this.lastFrameTimeMs = timestamp; | ||
this.begin(timestamp, this.delta); | ||
if (timestamp > this.lastFpsUpdate + 1000) { | ||
this.fps = 0.25 * this.framesThisSecond + 0.75 * this.fps; | ||
this.lastFpsUpdate = timestamp; | ||
this.framesThisSecond = 0; | ||
} | ||
this.framesThisSecond++; | ||
let numUpdateSteps = 0; | ||
while (this.delta >= this.timestep) { | ||
this.update(this.timestep); | ||
this.delta -= this.timestep; | ||
if (++numUpdateSteps >= 240) { | ||
this.panic(); | ||
break; | ||
} | ||
} | ||
this.render(this.delta / this.timestep); | ||
window.requestAnimationFrame(this.loop.bind(this)); | ||
} | ||
static setOptions(options) { | ||
this.maxFPS = | ||
typeof options.maxFPS === "number" ? options.maxFPS : this.maxFPS; | ||
} | ||
/** | ||
* The main / game loop | ||
* @param timestamp | ||
*/ | ||
static loop(timestamp) { | ||
// Throttle the frame rate. | ||
if (timestamp < this.lastFrameTimeMs + 1000 / this.maxFPS) { | ||
requestAnimationFrame(this.loop.bind(this)); | ||
return; | ||
} | ||
static begin(timestamp, delta) { | ||
// | ||
const progress = timestamp - this.lastFrameTimeMs; | ||
this.delta += progress; | ||
this.lastFrameTimeMs = timestamp; | ||
this.begin(timestamp, this.delta); | ||
if (timestamp > this.lastFpsUpdate + 1000) { | ||
this.fps = 0.25 * this.framesThisSecond + 0.75 * this.fps; | ||
this.lastFpsUpdate = timestamp; | ||
this.framesThisSecond = 0; | ||
} | ||
static render(interp) { | ||
for (const renderCallback of this.renderCallbacks) { | ||
if (typeof (renderCallback) === 'function') { | ||
renderCallback(interp); | ||
} | ||
} | ||
this.framesThisSecond++; | ||
let numUpdateSteps = 0; | ||
while (this.delta >= this.timestep) { | ||
this.update(this.timestep); | ||
this.delta -= this.timestep; | ||
if (++numUpdateSteps >= 240) { | ||
this.panic(); | ||
break; | ||
} | ||
} | ||
static update(delta) { | ||
for (const updateCallback of this.updateCallbacks) { | ||
if (typeof (updateCallback) === 'function') { | ||
updateCallback(delta); | ||
} | ||
} | ||
this.render(this.delta / this.timestep); | ||
window.requestAnimationFrame(this.loop.bind(this)); | ||
} | ||
static begin(timestamp, delta) { | ||
// | ||
} | ||
static render(interp) { | ||
for (const renderCallback of this.renderCallbacks) { | ||
if (typeof renderCallback === "function") { | ||
renderCallback(interp); | ||
} | ||
} | ||
static addRenderCallback(renderCallback) { | ||
this.renderCallbacks.push(renderCallback); | ||
} | ||
static update(delta) { | ||
for (const updateCallback of this.updateCallbacks) { | ||
if (typeof updateCallback === "function") { | ||
updateCallback(delta); | ||
} | ||
} | ||
static addUpdateCallback(updateCallback) { | ||
this.updateCallbacks.push(updateCallback); | ||
} | ||
static panic() { | ||
this.delta = 0; // discard the unsimulated time | ||
} | ||
} | ||
static addRenderCallback(renderCallback) { | ||
this.renderCallbacks.push(renderCallback); | ||
} | ||
static addUpdateCallback(updateCallback) { | ||
this.updateCallbacks.push(updateCallback); | ||
} | ||
static panic() { | ||
this.delta = 0; // discard the unsimulated time | ||
} | ||
} | ||
exports.Gameloop = Gameloop; | ||
Gameloop.maxFPS = 60; | ||
Gameloop.renderCallbacks = new Array(); | ||
Gameloop.updateCallbacks = new Array(); | ||
Gameloop.renderCallbacks = []; | ||
Gameloop.updateCallbacks = []; | ||
// We want to simulate 1000 ms / 60 FPS = 16.667 ms per frame every time we run scroll() | ||
@@ -92,0 +93,0 @@ Gameloop.timestep = 1000 / 60; |
@@ -1,6 +0,6 @@ | ||
export * from './autoscroll.service'; | ||
export * from './dragscroll.service'; | ||
export * from './gameloop.service'; | ||
export * from './touch-events/scroll-events.service'; | ||
export * from './touch-events/touch-events.service'; | ||
export * from './utils.service'; | ||
export * from "./autoscroll.service"; | ||
export * from "./dragscroll.service"; | ||
export * from "./gameloop.service"; | ||
export * from "./touch-events/scroll-events.service"; | ||
export * from "./touch-events/touch-events.service"; | ||
export * from "./utils.service"; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
@@ -5,0 +5,0 @@ Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,2 +0,2 @@ | ||
import { Position } from '../types'; | ||
import { Position } from "../types"; | ||
/** | ||
@@ -29,130 +29,152 @@ * Vanilla version of jQuery Mobile Events | ||
export interface Settings { | ||
tapPixelRange: number; | ||
swipeHThreshold: number; | ||
swipeVThreshold: number; | ||
tapholdThreshold: number; | ||
doubletapInterval: number; | ||
shakeThreshold: number; | ||
touchCapable: boolean; | ||
startevent: Array<'touchstart' | 'mousedown'>; | ||
endevent: Array<'touchend' | 'touchcancel' | 'mouseup'>; | ||
moveevent: Array<'touchmove' | 'mousemove'>; | ||
tapevent: Array<'tap' | 'click'>; | ||
scrollevent: Array<'touchmove' | 'scroll'>; | ||
tapPixelRange: number; | ||
swipeHThreshold: number; | ||
swipeVThreshold: number; | ||
tapholdThreshold: number; | ||
doubletapInterval: number; | ||
shakeThreshold: number; | ||
touchCapable: boolean; | ||
startevent: Array<"touchstart" | "mousedown">; | ||
endevent: Array<"touchend" | "touchcancel" | "mouseup">; | ||
moveevent: Array<"touchmove" | "mousemove">; | ||
tapevent: Array<"tap" | "click">; | ||
scrollevent: Array<"touchmove" | "scroll">; | ||
} | ||
export interface Offset { | ||
x: number; | ||
y: number; | ||
x: number; | ||
y: number; | ||
} | ||
export interface TouchData { | ||
position: Position; | ||
offset: Offset; | ||
time: number; | ||
index?: number; | ||
position: Position; | ||
offset: Offset; | ||
time: number; | ||
index?: number; | ||
} | ||
export declare enum TouchType { | ||
DEFAULT = 0, | ||
TARGET = 1, | ||
CHANGED = 2 | ||
DEFAULT = 0, | ||
TARGET = 1, | ||
CHANGED = 2, | ||
} | ||
export declare class TouchEventService { | ||
get isTouchCapable(): boolean; | ||
get startEvent(): ("mousedown" | "touchstart")[]; | ||
get endEvent(): ("mouseup" | "touchcancel" | "touchend")[]; | ||
get moveEvent(): ("mousemove" | "touchmove")[]; | ||
get tapEvent(): ("click" | "tap")[]; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold: number); | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold: number); | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval: number); | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold: number); | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range: number); | ||
protected el: HTMLElement; | ||
/** Used internally for `taphold` */ | ||
protected startPosition: Position; | ||
/** Used internally for `taphold` */ | ||
protected endPosition: Position; | ||
/** Used internally for `swipe` */ | ||
protected originalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected finalCoord: Position; | ||
/** Used internally for `scrollstart` and `scrollend` */ | ||
protected scrollPosition: Position | null; | ||
/** Used internally for `swipe` */ | ||
protected startEvnt: TouchData | null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
protected tapheld: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected firstTap: TouchData | null; | ||
/** Used internally for `doubletap` */ | ||
protected cooling: boolean; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
protected doubletapped: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected lastTouch: number; | ||
/** Used internally for `swipe` */ | ||
protected hasSwiped: boolean; | ||
/** Used internally for `tap` */ | ||
protected tapStarted: boolean; | ||
/** Used internally for `swipe` */ | ||
protected swipeStarted: boolean; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
protected startTime: number; | ||
protected holdTimer: number; | ||
protected tapTimer: number; | ||
/** Used internally for `doubletap` */ | ||
protected actionTimer: number; | ||
protected scrollTimer: number; | ||
protected settings: Settings; | ||
constructor(el: HTMLElement, settings?: Settings); | ||
removeEventListeners(): void; | ||
protected triggerCustomEvent(eventName: string, originalEvent: Event, extraParameters?: any): void; | ||
protected getSwipeDir(startPosition: Position, endPosition: Position, hThreshold?: number, vThreshold?: number): string; | ||
protected getPostion(event: TouchEvent | MouseEvent, type?: TouchType, index?: number): Position; | ||
protected getOffset(event: TouchEvent | MouseEvent, type?: TouchType, index?: number): Offset; | ||
protected getTouchData(event: TouchEvent | MouseEvent, withIndex?: boolean, positionType?: TouchType, offsetType?: TouchType): TouchData; | ||
protected addEventListeners(): void; | ||
protected onStartEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onEndEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onMoveEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onScrollEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** tapstart Event */ | ||
protected tapstart(event: TouchEvent | MouseEvent): boolean; | ||
/** tapmove Event */ | ||
protected tapmove(event: TouchEvent | MouseEvent): boolean; | ||
/** tapend Event */ | ||
protected tapend(event: TouchEvent | MouseEvent): boolean; | ||
/** taphold Event */ | ||
protected taphold(event: TouchEvent | MouseEvent): boolean; | ||
/** doubletap Event */ | ||
protected doubletap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
protected singletap(event: TouchEvent | MouseEvent): void; | ||
/** tap Event */ | ||
protected tap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
protected swipe(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
protected swipeend(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollend`) | ||
*/ | ||
protected scrollstart(event: TouchEvent | MouseEvent): false | undefined; | ||
get isTouchCapable(): boolean; | ||
get startEvent(): ("mousedown" | "touchstart")[]; | ||
get endEvent(): ("mouseup" | "touchcancel" | "touchend")[]; | ||
get moveEvent(): ("mousemove" | "touchmove")[]; | ||
get tapEvent(): ("click" | "tap")[]; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold: number); | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold: number); | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval: number); | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold: number); | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range: number); | ||
protected el: HTMLElement; | ||
/** Used internally for `taphold` */ | ||
protected startPosition: Position; | ||
/** Used internally for `taphold` */ | ||
protected endPosition: Position; | ||
/** Used internally for `swipe` */ | ||
protected originalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected finalCoord: Position; | ||
/** Used internally for `scrollstart` and `scrollend` */ | ||
protected scrollPosition: Position | null; | ||
/** Used internally for `swipe` */ | ||
protected startEvnt: TouchData | null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
protected tapheld: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected firstTap: TouchData | null; | ||
/** Used internally for `doubletap` */ | ||
protected cooling: boolean; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
protected doubletapped: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected lastTouch: number; | ||
/** Used internally for `swipe` */ | ||
protected hasSwiped: boolean; | ||
/** Used internally for `tap` */ | ||
protected tapStarted: boolean; | ||
/** Used internally for `swipe` */ | ||
protected swipeStarted: boolean; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
protected startTime: number; | ||
protected holdTimer: number; | ||
protected tapTimer: number; | ||
/** Used internally for `doubletap` */ | ||
protected actionTimer: number; | ||
protected scrollTimer: number; | ||
protected settings: Settings; | ||
constructor(el: HTMLElement, settings?: Settings); | ||
removeEventListeners(): void; | ||
protected triggerCustomEvent( | ||
eventName: string, | ||
originalEvent: Event, | ||
extraParameters?: any | ||
): void; | ||
protected getSwipeDir( | ||
startPosition: Position, | ||
endPosition: Position, | ||
hThreshold?: number, | ||
vThreshold?: number | ||
): string; | ||
protected getPostion( | ||
event: TouchEvent | MouseEvent, | ||
type?: TouchType, | ||
index?: number | ||
): Position; | ||
protected getOffset( | ||
event: TouchEvent | MouseEvent, | ||
type?: TouchType, | ||
index?: number | ||
): Offset; | ||
protected getTouchData( | ||
event: TouchEvent | MouseEvent, | ||
withIndex?: boolean, | ||
positionType?: TouchType, | ||
offsetType?: TouchType | ||
): TouchData; | ||
protected addEventListeners(): void; | ||
protected onStartEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onEndEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onMoveEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onScrollEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** tapstart Event */ | ||
protected tapstart(event: TouchEvent | MouseEvent): boolean; | ||
/** tapmove Event */ | ||
protected tapmove(event: TouchEvent | MouseEvent): boolean; | ||
/** tapend Event */ | ||
protected tapend(event: TouchEvent | MouseEvent): boolean; | ||
/** taphold Event */ | ||
protected taphold(event: TouchEvent | MouseEvent): boolean; | ||
/** doubletap Event */ | ||
protected doubletap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
protected singletap(event: TouchEvent | MouseEvent): void; | ||
/** tap Event */ | ||
protected tap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
protected swipe(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
protected swipeend(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollend`) | ||
*/ | ||
protected scrollstart(event: TouchEvent | MouseEvent): false | undefined; | ||
} |
@@ -7,548 +7,665 @@ "use strict"; | ||
(function (TouchType) { | ||
TouchType[TouchType["DEFAULT"] = 0] = "DEFAULT"; | ||
TouchType[TouchType["TARGET"] = 1] = "TARGET"; | ||
TouchType[TouchType["CHANGED"] = 2] = "CHANGED"; | ||
})(TouchType = exports.TouchType || (exports.TouchType = {})); | ||
TouchType[(TouchType["DEFAULT"] = 0)] = "DEFAULT"; | ||
TouchType[(TouchType["TARGET"] = 1)] = "TARGET"; | ||
TouchType[(TouchType["CHANGED"] = 2)] = "CHANGED"; | ||
})((TouchType = exports.TouchType || (exports.TouchType = {}))); | ||
class TouchEventService { | ||
constructor(el, settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: ('ontouchstart' in window), | ||
startevent: ['touchstart'], | ||
endevent: ['touchend'], | ||
moveevent: ['touchmove'], | ||
tapevent: ['tap'], | ||
scrollevent: ['touchmove'], | ||
}) { | ||
/** Used internally for `taphold` */ | ||
this.startPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `taphold` */ | ||
this.endPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.originalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.finalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `scrollstart` and `scrollend` */ | ||
this.scrollPosition = null; | ||
/** Used internally for `swipe` */ | ||
this.startEvnt = null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
this.tapheld = false; | ||
/** Used internally for `doubletap` */ | ||
this.firstTap = null; | ||
/** Used internally for `doubletap` */ | ||
this.cooling = false; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
this.doubletapped = false; | ||
/** Used internally for `doubletap` */ | ||
this.lastTouch = 0; | ||
/** Used internally for `swipe` */ | ||
this.hasSwiped = false; | ||
/** Used internally for `tap` */ | ||
this.tapStarted = false; | ||
/** Used internally for `swipe` */ | ||
this.swipeStarted = false; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
this.startTime = 0; | ||
// TIMERS: | ||
this.holdTimer = -1; | ||
this.tapTimer = -1; | ||
/** Used internally for `doubletap` */ | ||
this.actionTimer = -1; | ||
this.scrollTimer = -1; | ||
this.el = el; | ||
// Set settings by device type (if device is touch capable) | ||
settings.startevent = settings.touchCapable ? ['touchstart'] : ['mousedown']; | ||
settings.endevent = settings.touchCapable ? ['touchend'] : ['mouseup']; | ||
settings.moveevent = settings.touchCapable ? ['touchmove'] : ['mousemove']; | ||
settings.tapevent = settings.touchCapable ? ['tap'] : ['click']; | ||
settings.scrollevent = settings.touchCapable ? ['touchmove'] : ['scroll']; | ||
this.settings = settings; | ||
this.addEventListeners(); | ||
constructor( | ||
el, | ||
settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: "ontouchstart" in window, | ||
startevent: ["touchstart"], | ||
endevent: ["touchend"], | ||
moveevent: ["touchmove"], | ||
tapevent: ["tap"], | ||
scrollevent: ["touchmove"], | ||
} | ||
// GETTERS: | ||
get isTouchCapable() { | ||
return this.settings.touchCapable; | ||
) { | ||
/** Used internally for `taphold` */ | ||
this.startPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `taphold` */ | ||
this.endPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.originalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.finalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `scrollstart` and `scrollend` */ | ||
this.scrollPosition = null; | ||
/** Used internally for `swipe` */ | ||
this.startEvnt = null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
this.tapheld = false; | ||
/** Used internally for `doubletap` */ | ||
this.firstTap = null; | ||
/** Used internally for `doubletap` */ | ||
this.cooling = false; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
this.doubletapped = false; | ||
/** Used internally for `doubletap` */ | ||
this.lastTouch = 0; | ||
/** Used internally for `swipe` */ | ||
this.hasSwiped = false; | ||
/** Used internally for `tap` */ | ||
this.tapStarted = false; | ||
/** Used internally for `swipe` */ | ||
this.swipeStarted = false; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
this.startTime = 0; | ||
// TIMERS: | ||
this.holdTimer = -1; | ||
this.tapTimer = -1; | ||
/** Used internally for `doubletap` */ | ||
this.actionTimer = -1; | ||
this.scrollTimer = -1; | ||
this.el = el; | ||
// Set settings by device type (if device is touch capable) | ||
settings.startevent = settings.touchCapable | ||
? ["touchstart"] | ||
: ["mousedown"]; | ||
settings.endevent = settings.touchCapable ? ["touchend"] : ["mouseup"]; | ||
settings.moveevent = settings.touchCapable ? ["touchmove"] : ["mousemove"]; | ||
settings.tapevent = settings.touchCapable ? ["tap"] : ["click"]; | ||
settings.scrollevent = settings.touchCapable ? ["touchmove"] : ["scroll"]; | ||
this.settings = settings; | ||
this.addEventListeners(); | ||
} | ||
// GETTERS: | ||
get isTouchCapable() { | ||
return this.settings.touchCapable; | ||
} | ||
get startEvent() { | ||
return this.settings.startevent; | ||
} | ||
get endEvent() { | ||
return this.settings.endevent; | ||
} | ||
get moveEvent() { | ||
return this.settings.moveevent; | ||
} | ||
get tapEvent() { | ||
return this.settings.tapevent; | ||
} | ||
get scrollEvent() { | ||
return this.settings.scrollevent; | ||
} | ||
// SETTERS: | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get startEvent() { | ||
return this.settings.startevent; | ||
this.settings.swipeHThreshold = threshold; | ||
} | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get endEvent() { | ||
return this.settings.endevent; | ||
this.settings.swipeVThreshold = threshold; | ||
} | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval) { | ||
if (typeof interval !== "number") { | ||
throw new Error("Interval parameter must be a type of number"); | ||
} | ||
get moveEvent() { | ||
return this.settings.moveevent; | ||
this.settings.doubletapInterval = interval; | ||
} | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get tapEvent() { | ||
return this.settings.tapevent; | ||
this.settings.tapholdThreshold = threshold; | ||
} | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range) { | ||
if (typeof range !== "number") { | ||
throw new Error("Ranger parameter must be a type of number"); | ||
} | ||
get scrollEvent() { | ||
return this.settings.scrollevent; | ||
this.settings.tapPixelRange = range; | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.removeEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
// SETTERS: | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.swipeHThreshold = threshold; | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.removeEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.swipeVThreshold = threshold; | ||
for (const eventName of this.settings.endevent) { | ||
this.el.removeEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval) { | ||
if (typeof interval !== 'number') { | ||
throw new Error('Interval parameter must be a type of number'); | ||
} | ||
this.settings.doubletapInterval = interval; | ||
for (const eventName of this.settings.scrollevent) { | ||
this.el.removeEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.tapholdThreshold = threshold; | ||
} | ||
// HELPER METHODS: | ||
triggerCustomEvent(eventName, originalEvent, extraParameters = {}) { | ||
extraParameters.originalEvent = originalEvent; | ||
extraParameters.target = originalEvent.target; | ||
// create and dispatch the event | ||
const event = new CustomEvent(eventName, { | ||
detail: extraParameters, | ||
}); | ||
this.el.dispatchEvent(event); | ||
} | ||
getSwipeDir( | ||
startPosition, | ||
endPosition, | ||
hThreshold = this.settings.swipeHThreshold, | ||
vThreshold = this.settings.swipeVThreshold | ||
) { | ||
let swipeDir = ""; | ||
if ( | ||
startPosition.y > endPosition.y && | ||
startPosition.y - endPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipeup"; | ||
} | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range) { | ||
if (typeof range !== 'number') { | ||
throw new Error('Ranger parameter must be a type of number'); | ||
} | ||
this. | ||
settings.tapPixelRange = range; | ||
if ( | ||
startPosition.x < endPosition.x && | ||
endPosition.x - startPosition.x > hThreshold | ||
) { | ||
swipeDir = "swiperight"; | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.removeEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.removeEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.endevent) { | ||
this.el.removeEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.scrollevent) { | ||
this.el.removeEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
if ( | ||
startPosition.y < endPosition.y && | ||
endPosition.y - startPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipedown"; | ||
} | ||
// HELPER METHODS: | ||
triggerCustomEvent(eventName, originalEvent, extraParameters = {}) { | ||
extraParameters.originalEvent = originalEvent; | ||
extraParameters.target = originalEvent.target; | ||
// create and dispatch the event | ||
const event = new CustomEvent(eventName, { | ||
detail: extraParameters, | ||
}); | ||
this.el.dispatchEvent(event); | ||
if ( | ||
startPosition.x > endPosition.x && | ||
startPosition.x - endPosition.x > hThreshold | ||
) { | ||
swipeDir = "swipeleft"; | ||
} | ||
getSwipeDir(startPosition, endPosition, hThreshold = this.settings.swipeHThreshold, vThreshold = this.settings.swipeVThreshold) { | ||
let swipeDir = ''; | ||
if (startPosition.y > endPosition.y && (startPosition.y - endPosition.y > vThreshold)) { | ||
swipeDir = 'swipeup'; | ||
} | ||
if (startPosition.x < endPosition.x && (endPosition.x - startPosition.x > hThreshold)) { | ||
swipeDir = 'swiperight'; | ||
} | ||
if (startPosition.y < endPosition.y && (endPosition.y - startPosition.y > vThreshold)) { | ||
swipeDir = 'swipedown'; | ||
} | ||
if (startPosition.x > endPosition.x && (startPosition.x - endPosition.x > hThreshold)) { | ||
swipeDir = 'swipeleft'; | ||
} | ||
return swipeDir; | ||
return swipeDir; | ||
} | ||
getPostion(event, type = TouchType.DEFAULT, index = 0) { | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
getPostion(event, type = TouchType.DEFAULT, index = 0) { | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
const position = { | ||
x: (this.settings.touchCapable) ? touchesTypes[index].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? touchesTypes[index].pageY : event.pageY, | ||
}; | ||
return position; | ||
const position = { | ||
x: this.settings.touchCapable ? touchesTypes[index].pageX : event.pageX, | ||
y: this.settings.touchCapable ? touchesTypes[index].pageY : event.pageY, | ||
}; | ||
return position; | ||
} | ||
getOffset(event, type = TouchType.DEFAULT, index = 0) { | ||
const boundingClientRect = this.el.getBoundingClientRect(); | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
getOffset(event, type = TouchType.DEFAULT, index = 0) { | ||
const boundingClientRect = this.el.getBoundingClientRect(); | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
const offset = { | ||
x: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageX - (boundingClientRect ? boundingClientRect.left : 0)) : Math.round(event.pageX - (boundingClientRect ? boundingClientRect.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageY - (boundingClientRect ? boundingClientRect.top : 0)) : Math.round(event.pageY - (boundingClientRect ? boundingClientRect.top : 0)), | ||
}; | ||
return offset; | ||
const offset = { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageX - | ||
(boundingClientRect ? boundingClientRect.left : 0) | ||
) | ||
: Math.round( | ||
event.pageX - (boundingClientRect ? boundingClientRect.left : 0) | ||
), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageY - | ||
(boundingClientRect ? boundingClientRect.top : 0) | ||
) | ||
: Math.round( | ||
event.pageY - (boundingClientRect ? boundingClientRect.top : 0) | ||
), | ||
}; | ||
return offset; | ||
} | ||
getTouchData( | ||
event, | ||
withIndex = false, | ||
positionType = TouchType.DEFAULT, | ||
offsetType = TouchType.CHANGED | ||
) { | ||
const touchData = { | ||
position: this.getPostion(event, positionType), | ||
offset: this.getOffset(event, offsetType), | ||
time: Date.now(), | ||
}; | ||
if (withIndex) { | ||
touchData.index = utils_service_1.Utils.getElementIndex(event.target); | ||
} | ||
getTouchData(event, withIndex = false, positionType = TouchType.DEFAULT, offsetType = TouchType.CHANGED) { | ||
const touchData = { | ||
position: this.getPostion(event, positionType), | ||
offset: this.getOffset(event, offsetType), | ||
time: Date.now(), | ||
}; | ||
if (withIndex) { | ||
touchData.index = utils_service_1.Utils.getElementIndex(event.target); | ||
} | ||
return touchData; | ||
return touchData; | ||
} | ||
addEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.addEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
addEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.addEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.addEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.endevent) { | ||
this.el.addEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.scrollevent) { | ||
this.el.addEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.addEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
// EVENT HANDLERS: | ||
onStartEvent(event) { | ||
if (event.which && event.which !== 1) { | ||
return false; | ||
} | ||
this.startPosition = this.getPostion(event, TouchType.TARGET); | ||
this.endPosition = { | ||
x: this.startPosition.x, | ||
y: this.startPosition.y, | ||
}; | ||
this.startTime = Date.now(); | ||
// For `doubletap` | ||
this.doubletapped = false; | ||
if (!this.firstTap) { | ||
this.firstTap = this.getTouchData(event, true, TouchType.DEFAULT, TouchType.CHANGED); | ||
} | ||
// For `tap`, `swipe` | ||
this.tapStarted = true; | ||
this.swipeStarted = true; | ||
// For `swipe` | ||
this.originalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.startEvnt = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
this.tapstart(event); | ||
this.taphold(event); | ||
return true; | ||
for (const eventName of this.settings.endevent) { | ||
this.el.addEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
onEndEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.CHANGED); | ||
this.tapheld = false; | ||
window.clearTimeout(this.holdTimer); | ||
this.tapend(event); | ||
this.swipeend(event); | ||
this.tap(event); | ||
this.doubletap(event); | ||
this.singletap(event); | ||
this.tapStarted = false; | ||
this.swipeStarted = false; | ||
this.hasSwiped = false; | ||
return true; | ||
for (const eventName of this.settings.scrollevent) { | ||
this.el.addEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
onMoveEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.tapmove(event); | ||
this.swipe(event); | ||
return true; | ||
} | ||
// EVENT HANDLERS: | ||
onStartEvent(event) { | ||
if (event.which && event.which !== 1) { | ||
return false; | ||
} | ||
onScrollEvent(event) { | ||
this.scrollstart(event); | ||
return true; | ||
this.startPosition = this.getPostion(event, TouchType.TARGET); | ||
this.endPosition = { | ||
x: this.startPosition.x, | ||
y: this.startPosition.y, | ||
}; | ||
this.startTime = Date.now(); | ||
// For `doubletap` | ||
this.doubletapped = false; | ||
if (!this.firstTap) { | ||
this.firstTap = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
} | ||
// CUSTOM EVENT METHODS: | ||
/** tapstart Event */ | ||
tapstart(event) { | ||
this.triggerCustomEvent('tapstart', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
return true; | ||
// For `tap`, `swipe` | ||
this.tapStarted = true; | ||
this.swipeStarted = true; | ||
// For `swipe` | ||
this.originalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.startEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
this.tapstart(event); | ||
this.taphold(event); | ||
return true; | ||
} | ||
onEndEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.CHANGED); | ||
this.tapheld = false; | ||
window.clearTimeout(this.holdTimer); | ||
this.tapend(event); | ||
this.swipeend(event); | ||
this.tap(event); | ||
this.doubletap(event); | ||
this.singletap(event); | ||
this.tapStarted = false; | ||
this.swipeStarted = false; | ||
this.hasSwiped = false; | ||
return true; | ||
} | ||
onMoveEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.tapmove(event); | ||
this.swipe(event); | ||
return true; | ||
} | ||
onScrollEvent(event) { | ||
this.scrollstart(event); | ||
return true; | ||
} | ||
// CUSTOM EVENT METHODS: | ||
/** tapstart Event */ | ||
tapstart(event) { | ||
this.triggerCustomEvent( | ||
"tapstart", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** tapmove Event */ | ||
tapmove(event) { | ||
this.triggerCustomEvent( | ||
"tapmove", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** tapend Event */ | ||
tapend(event) { | ||
this.triggerCustomEvent( | ||
"tapend", | ||
event, | ||
this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** taphold Event */ | ||
taphold(event) { | ||
this.holdTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
// helded? | ||
if ( | ||
(this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange) | ||
) { | ||
this.tapheld = true; | ||
const endTime = Date.now(); | ||
const duration = endTime - this.startTime; | ||
const touchesLength = event.targetTouches | ||
? event.targetTouches.length | ||
: 1; | ||
const touches = []; | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: this.settings.touchCapable | ||
? event.changedTouches[i].pageX | ||
: event.pageX, | ||
y: this.settings.touchCapable | ||
? event.changedTouches[i].pageY | ||
: event.pageY, | ||
}, | ||
offset: { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageX - | ||
(elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageY - | ||
(elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const eventName = | ||
touchesLength > 1 ? "taphold" + touchesLength : "taphold"; | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
duration, | ||
}; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
}, this.settings.tapholdThreshold); | ||
return true; | ||
} | ||
/** doubletap Event */ | ||
doubletap(event) { | ||
const now = Date.now(); | ||
const lastTouch = Number(this.lastTouch) || now + 1; | ||
const delta = now - lastTouch; | ||
if (this.actionTimer !== -1) { | ||
window.clearTimeout(this.actionTimer); | ||
} | ||
/** tapmove Event */ | ||
tapmove(event) { | ||
this.triggerCustomEvent('tapmove', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
return true; | ||
if ( | ||
delta < this.settings.doubletapInterval && | ||
delta > 100 && | ||
this.firstTap && | ||
utils_service_1.Utils.getElementIndex(event.target) === | ||
this.firstTap.index | ||
) { | ||
this.doubletapped = true; | ||
window.clearTimeout(this.tapTimer); | ||
const lastTap = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
const touchData = { | ||
firstTap: this.firstTap, | ||
secondTap: lastTap, | ||
interval: lastTap.time - this.firstTap.time, | ||
}; | ||
if (!this.cooling) { | ||
this.triggerCustomEvent("doubletap", event, touchData); | ||
this.firstTap = null; | ||
} | ||
this.cooling = true; | ||
window.setTimeout(() => { | ||
this.cooling = false; | ||
}, this.settings.doubletapInterval); | ||
} else { | ||
this.actionTimer = window.setTimeout( | ||
() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, | ||
this.settings.doubletapInterval, | ||
[event] | ||
); | ||
} | ||
/** tapend Event */ | ||
tapend(event) { | ||
this.triggerCustomEvent('tapend', event, this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED)); | ||
return true; | ||
} | ||
/** taphold Event */ | ||
taphold(event) { | ||
this.holdTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
// helded? | ||
if ((this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange)) { | ||
this.tapheld = true; | ||
const endTime = Date.now(); | ||
const duration = endTime - this.startTime; | ||
const touchesLength = (event.targetTouches) ? event.targetTouches.length : 1; | ||
const touches = new Array(); | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: (this.settings.touchCapable) ? event.changedTouches[i].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? event.changedTouches[i].pageY : event.pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const eventName = (touchesLength > 1) ? 'taphold' + touchesLength : 'taphold'; | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
duration, | ||
}; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
}, this.settings.tapholdThreshold); | ||
return true; | ||
} | ||
/** doubletap Event */ | ||
doubletap(event) { | ||
const now = Date.now(); | ||
const lastTouch = Number(this.lastTouch) || now + 1; | ||
const delta = now - lastTouch; | ||
if (this.actionTimer !== -1) { | ||
window.clearTimeout(this.actionTimer); | ||
this.lastTouch = now; | ||
} | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
singletap(event) { | ||
this.tapTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if ( | ||
!this.doubletapped && | ||
!this.tapheld && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchData = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
// Was it a taphold? | ||
if (touchData.time - this.startTime < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent("singletap", event, touchData); | ||
} | ||
if (delta < this.settings.doubletapInterval | ||
&& | ||
delta > 100 | ||
&& | ||
(this.firstTap | ||
&& | ||
utils_service_1.Utils.getElementIndex(event.target) === this.firstTap.index)) { | ||
this.doubletapped = true; | ||
window.clearTimeout(this.tapTimer); | ||
const lastTap = this.getTouchData(event, true, TouchType.CHANGED, TouchType.CHANGED); | ||
const touchData = { | ||
firstTap: this.firstTap, | ||
secondTap: lastTap, | ||
interval: lastTap.time - this.firstTap.time, | ||
}; | ||
if (!this.cooling) { | ||
this.triggerCustomEvent('doubletap', event, touchData); | ||
this.firstTap = null; | ||
} | ||
this.cooling = true; | ||
window.setTimeout(() => { | ||
this.cooling = false; | ||
}, this.settings.doubletapInterval); | ||
} | ||
else { | ||
this.actionTimer = window.setTimeout(() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, this.settings.doubletapInterval, [event]); | ||
} | ||
this.lastTouch = now; | ||
} | ||
}, this.settings.doubletapInterval); | ||
} | ||
/** tap Event */ | ||
tap(event) { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if ( | ||
this.tapStarted && | ||
Date.now() - this.startTime < this.settings.tapholdThreshold && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchesLength = event.targetTouches | ||
? event.targetTouches.length | ||
: 1; | ||
const touches = []; | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: this.settings.touchCapable | ||
? event.changedTouches[i].pageX | ||
: event.pageX, | ||
y: this.settings.touchCapable | ||
? event.changedTouches[i].pageY | ||
: event.pageY, | ||
}, | ||
offset: { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
}; | ||
const eventName = touchesLength > 1 ? "tap" + touchesLength : "tap"; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
singletap(event) { | ||
this.tapTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if (!this.doubletapped | ||
&& | ||
!this.tapheld | ||
&& | ||
(((this.startPosition.x === this.endPosition.x) | ||
&& | ||
(this.startPosition.y === this.endPosition.y)) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange))) { | ||
const touchData = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
// Was it a taphold? | ||
if ((touchData.time - this.startTime) < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent('singletap', event, touchData); | ||
} | ||
} | ||
}, this.settings.doubletapInterval); | ||
} | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
swipe(event) { | ||
const swipeDir = this.getSwipeDir(this.originalCoord, this.finalCoord); | ||
if (swipeDir && this.swipeStarted && this.startEvnt) { | ||
this.originalCoord.x = 0; | ||
this.originalCoord.y = 0; | ||
this.finalCoord.x = 0; | ||
this.finalCoord.y = 0; | ||
this.swipeStarted = false; | ||
const endEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.hasSwiped = true; | ||
this.triggerCustomEvent("swipe", event, touchData); | ||
this.triggerCustomEvent(swipeDir, event, touchData); | ||
} | ||
/** tap Event */ | ||
tap(event) { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if (this.tapStarted | ||
&& | ||
((Date.now() - this.startTime) < this.settings.tapholdThreshold) | ||
&& | ||
((this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange))) { | ||
const touchesLength = (event.targetTouches) ? event.targetTouches.length : 1; | ||
const touches = new Array(); | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: (this.settings.touchCapable) ? event.changedTouches[i].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? event.changedTouches[i].pageY : event.pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
}; | ||
const eventName = (touchesLength > 1) ? 'tap' + touchesLength : 'tap'; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
} | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
swipeend(event) { | ||
const endEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
if (this.hasSwiped && this.startEvnt) { | ||
const swipeDir = this.getSwipeDir( | ||
this.startEvnt.position, | ||
endEvnt.position | ||
); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.triggerCustomEvent("swipeend", event, touchData); | ||
} | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
swipe(event) { | ||
const swipeDir = this.getSwipeDir(this.originalCoord, this.finalCoord); | ||
if (swipeDir && this.swipeStarted && this.startEvnt) { | ||
this.originalCoord.x = 0; | ||
this.originalCoord.y = 0; | ||
this.finalCoord.x = 0; | ||
this.finalCoord.y = 0; | ||
this.swipeStarted = false; | ||
const endEvnt = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.hasSwiped = true; | ||
this.triggerCustomEvent('swipe', event, touchData); | ||
this.triggerCustomEvent(swipeDir, event, touchData); | ||
} | ||
} | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollend`) | ||
*/ | ||
scrollstart(event) { | ||
if (!event.target) { | ||
return false; | ||
} | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
swipeend(event) { | ||
const endEvnt = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
if (this.hasSwiped && this.startEvnt) { | ||
const swipeDir = this.getSwipeDir(this.startEvnt.position, endEvnt.position); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.triggerCustomEvent('swipeend', event, touchData); | ||
} | ||
if (this.scrollPosition === null) { | ||
this.scrollPosition = utils_service_1.Utils.getScrollPosition( | ||
event.target | ||
); | ||
this.triggerCustomEvent("scrollstart", event, this.scrollPosition); | ||
} | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollend`) | ||
*/ | ||
scrollstart(event) { | ||
if (!event.target) { | ||
return false; | ||
} | ||
if (this.scrollPosition === null) { | ||
this.scrollPosition = utils_service_1.Utils.getScrollPosition(event.target); | ||
this.triggerCustomEvent('scrollstart', event, this.scrollPosition); | ||
} | ||
if (this.scrollTimer !== -1) { | ||
window.clearTimeout(this.scrollTimer); | ||
} | ||
this.scrollTimer = window.setTimeout(() => { | ||
core_1.Utils.debounce(this.triggerCustomEvent.bind(this, 'scrollend', event, event.target ? utils_service_1.Utils.getScrollPosition(event.target) : {})); | ||
this.scrollPosition = null; | ||
}, 50); | ||
if (this.scrollTimer !== -1) { | ||
window.clearTimeout(this.scrollTimer); | ||
} | ||
this.scrollTimer = window.setTimeout(() => { | ||
core_1.Utils.debounce( | ||
this.triggerCustomEvent.bind( | ||
this, | ||
"scrollend", | ||
event, | ||
event.target | ||
? utils_service_1.Utils.getScrollPosition(event.target) | ||
: {} | ||
) | ||
); | ||
this.scrollPosition = null; | ||
}, 50); | ||
} | ||
} | ||
exports.TouchEventService = TouchEventService; |
export declare abstract class BaseTouchEventService { | ||
protected touchCapable: boolean; | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
get isTouchCapable(): boolean; | ||
constructor(el: HTMLElement); | ||
protected triggerCustomEvent(eventName: string, originalEvent: Event, extraParameters?: any): void; | ||
protected touchCapable: boolean; | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
get isTouchCapable(): boolean; | ||
constructor(el: HTMLElement); | ||
protected triggerCustomEvent( | ||
eventName: string, | ||
originalEvent: Event, | ||
extraParameters?: any | ||
): void; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class BaseTouchEventService { | ||
constructor(el) { | ||
this.el = el; | ||
this.touchCapable = ('ontouchstart' in window); | ||
} | ||
get isTouchCapable() { | ||
return this.touchCapable; | ||
} | ||
triggerCustomEvent(eventName, originalEvent, extraParameters = {}) { | ||
extraParameters.originalEvent = originalEvent; | ||
extraParameters.target = originalEvent.target; | ||
// create and dispatch the event | ||
const event = new CustomEvent(eventName, { | ||
detail: extraParameters, | ||
}); | ||
this.el.dispatchEvent(event); | ||
} | ||
constructor(el) { | ||
this.el = el; | ||
this.touchCapable = "ontouchstart" in window; | ||
} | ||
get isTouchCapable() { | ||
return this.touchCapable; | ||
} | ||
triggerCustomEvent(eventName, originalEvent, extraParameters = {}) { | ||
extraParameters.originalEvent = originalEvent; | ||
extraParameters.target = originalEvent.target; | ||
// create and dispatch the event | ||
const event = new CustomEvent(eventName, { | ||
detail: extraParameters, | ||
}); | ||
this.el.dispatchEvent(event); | ||
} | ||
} | ||
exports.BaseTouchEventService = BaseTouchEventService; |
@@ -1,18 +0,18 @@ | ||
import { BaseTouchEventService } from './base-touch-events.service'; | ||
import { BaseTouchEventService } from "./base-touch-events.service"; | ||
export declare class ScrollEventsService extends BaseTouchEventService { | ||
isScrolling: boolean; | ||
protected _scrollEvent: Array<'touchmove' | 'scroll'>; | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
protected scrollTimer: number | null; | ||
constructor(el: HTMLElement); | ||
removeEventListeners(): void; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
protected addEventListeners(): void; | ||
protected onScrollEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollEnd`) | ||
*/ | ||
protected scrollstart(event: TouchEvent | MouseEvent): false | undefined; | ||
isScrolling: boolean; | ||
protected _scrollEvent: Array<"touchmove" | "scroll">; | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
protected scrollTimer: number | null; | ||
constructor(el: HTMLElement); | ||
removeEventListeners(): void; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
protected addEventListeners(): void; | ||
protected onScrollEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollEnd`) | ||
*/ | ||
protected scrollstart(event: TouchEvent | MouseEvent): false | undefined; | ||
} |
@@ -5,50 +5,50 @@ "use strict"; | ||
class ScrollEventsService extends base_touch_events_service_1.BaseTouchEventService { | ||
constructor(el) { | ||
super(el); | ||
this.isScrolling = false; | ||
this.scrollTimer = null; | ||
this.el = el; | ||
this._scrollEvent = this.touchCapable ? ['touchmove'] : ['scroll']; | ||
this.addEventListeners(); | ||
constructor(el) { | ||
super(el); | ||
this.isScrolling = false; | ||
this.scrollTimer = null; | ||
this.el = el; | ||
this._scrollEvent = this.touchCapable ? ["touchmove"] : ["scroll"]; | ||
this.addEventListeners(); | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this._scrollEvent) { | ||
this.el.removeEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this._scrollEvent) { | ||
this.el.removeEventListener(eventName, this.onScrollEvent.bind(this)); | ||
} | ||
} | ||
get scrollEvent() { | ||
return this._scrollEvent; | ||
} | ||
addEventListeners() { | ||
for (const eventName of this._scrollEvent) { | ||
this.el.addEventListener(eventName, this.onScrollEvent.bind(this), false); | ||
} | ||
get scrollEvent() { | ||
return this._scrollEvent; | ||
} | ||
onScrollEvent(event) { | ||
this.scrollstart(event); | ||
return true; | ||
} | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollEnd`) | ||
*/ | ||
scrollstart(event) { | ||
if (!event.target) { | ||
return false; | ||
} | ||
addEventListeners() { | ||
for (const eventName of this._scrollEvent) { | ||
this.el.addEventListener(eventName, this.onScrollEvent.bind(this), false); | ||
} | ||
if (!this.isScrolling) { | ||
this.isScrolling = true; | ||
this.triggerCustomEvent("scrollStart", event, {}); | ||
} | ||
onScrollEvent(event) { | ||
this.scrollstart(event); | ||
return true; | ||
// console.debug('scroll timer is ', this.scrollTimer); | ||
if (this.scrollTimer !== null) { | ||
clearTimeout(this.scrollTimer); | ||
this.scrollTimer = null; | ||
} | ||
/** | ||
* scrollstart Event | ||
* (also handles `scrollEnd`) | ||
*/ | ||
scrollstart(event) { | ||
if (!event.target) { | ||
return false; | ||
} | ||
if (!this.isScrolling) { | ||
this.isScrolling = true; | ||
this.triggerCustomEvent('scrollStart', event, {}); | ||
} | ||
// console.debug('scroll timer is ', this.scrollTimer); | ||
if (this.scrollTimer !== null) { | ||
clearTimeout(this.scrollTimer); | ||
this.scrollTimer = null; | ||
} | ||
this.scrollTimer = window.setTimeout(() => { | ||
this.triggerCustomEvent('scrollEnd', event, {}); | ||
this.isScrolling = false; | ||
}, 100); | ||
} | ||
this.scrollTimer = window.setTimeout(() => { | ||
this.triggerCustomEvent("scrollEnd", event, {}); | ||
this.isScrolling = false; | ||
}, 100); | ||
} | ||
} | ||
exports.ScrollEventsService = ScrollEventsService; |
@@ -1,4 +0,4 @@ | ||
import { Position } from '../../types'; | ||
import { ScrollEventsService } from './scroll-events.service'; | ||
import { BaseTouchEventService } from './base-touch-events.service'; | ||
import { Position } from "../../types"; | ||
import { ScrollEventsService } from "./scroll-events.service"; | ||
import { BaseTouchEventService } from "./base-touch-events.service"; | ||
/** | ||
@@ -31,121 +31,139 @@ * Vanilla version of jQuery Mobile Events | ||
export interface Settings { | ||
tapPixelRange: number; | ||
swipeHThreshold: number; | ||
swipeVThreshold: number; | ||
tapholdThreshold: number; | ||
doubletapInterval: number; | ||
shakeThreshold: number; | ||
touchCapable: boolean; | ||
startevent: Array<'touchstart' | 'mousedown'>; | ||
endevent: Array<'touchend' | 'touchcancel' | 'mouseup'>; | ||
moveevent: Array<'touchmove' | 'mousemove'>; | ||
tapevent: Array<'tap' | 'click'>; | ||
tapPixelRange: number; | ||
swipeHThreshold: number; | ||
swipeVThreshold: number; | ||
tapholdThreshold: number; | ||
doubletapInterval: number; | ||
shakeThreshold: number; | ||
touchCapable: boolean; | ||
startevent: Array<"touchstart" | "mousedown">; | ||
endevent: Array<"touchend" | "touchcancel" | "mouseup">; | ||
moveevent: Array<"touchmove" | "mousemove">; | ||
tapevent: Array<"tap" | "click">; | ||
} | ||
export interface Offset { | ||
x: number; | ||
y: number; | ||
x: number; | ||
y: number; | ||
} | ||
export interface TouchData { | ||
position: Position; | ||
offset: Offset; | ||
time: number; | ||
index?: number; | ||
position: Position; | ||
offset: Offset; | ||
time: number; | ||
index?: number; | ||
} | ||
export declare enum TouchType { | ||
DEFAULT = 0, | ||
TARGET = 1, | ||
CHANGED = 2 | ||
DEFAULT = 0, | ||
TARGET = 1, | ||
CHANGED = 2, | ||
} | ||
export declare class TouchEventService extends BaseTouchEventService { | ||
get isTouchCapable(): boolean; | ||
get startEvent(): ("mousedown" | "touchstart")[]; | ||
get endEvent(): ("mouseup" | "touchcancel" | "touchend")[]; | ||
get moveEvent(): ("mousemove" | "touchmove")[]; | ||
get tapEvent(): ("click" | "tap")[]; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold: number); | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold: number); | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval: number); | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold: number); | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range: number); | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
/** Used internally for `taphold` */ | ||
protected startPosition: Position; | ||
/** Used internally for `taphold` */ | ||
protected endPosition: Position; | ||
/** Used internally for `swipe` */ | ||
protected originalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected finalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected startEvnt: TouchData | null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
protected tapheld: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected firstTap: TouchData | null; | ||
/** Used internally for `doubletap` */ | ||
protected cooling: boolean; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
protected doubletapped: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected lastTouch: number; | ||
/** Used internally for `swipe` */ | ||
protected hasSwiped: boolean; | ||
/** Used internally for `tap` */ | ||
protected tapStarted: boolean; | ||
/** Used internally for `swipe` */ | ||
protected swipeStarted: boolean; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
protected startTime: number; | ||
protected holdTimer: number; | ||
protected tapTimer: number; | ||
/** Used internally for `doubletap` */ | ||
protected actionTimer: number; | ||
protected settings: Settings; | ||
protected scrollEvents: ScrollEventsService; | ||
constructor(el: HTMLElement, settings?: Settings); | ||
removeEventListeners(): void; | ||
protected getSwipeDir(startPosition: Position, endPosition: Position, hThreshold?: number, vThreshold?: number): string; | ||
protected getPostion(event: TouchEvent | MouseEvent, type?: TouchType, index?: number): Position; | ||
protected getOffset(event: TouchEvent | MouseEvent, type?: TouchType, index?: number): Offset; | ||
protected getTouchData(event: TouchEvent | MouseEvent, withIndex?: boolean, positionType?: TouchType, offsetType?: TouchType): TouchData; | ||
protected addEventListeners(): void; | ||
protected onStartEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onEndEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onMoveEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** tapstart Event */ | ||
protected tapstart(event: TouchEvent | MouseEvent): boolean; | ||
/** tapmove Event */ | ||
protected tapmove(event: TouchEvent | MouseEvent): boolean; | ||
/** tapend Event */ | ||
protected tapend(event: TouchEvent | MouseEvent): boolean; | ||
/** taphold Event */ | ||
protected taphold(event: TouchEvent | MouseEvent): boolean; | ||
/** doubletap Event */ | ||
protected doubletap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
protected singletap(event: TouchEvent | MouseEvent): void; | ||
/** tap Event */ | ||
protected tap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
protected swipe(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
protected swipeend(event: TouchEvent | MouseEvent): void; | ||
get isTouchCapable(): boolean; | ||
get startEvent(): ("mousedown" | "touchstart")[]; | ||
get endEvent(): ("mouseup" | "touchcancel" | "touchend")[]; | ||
get moveEvent(): ("mousemove" | "touchmove")[]; | ||
get tapEvent(): ("click" | "tap")[]; | ||
get scrollEvent(): ("scroll" | "touchmove")[]; | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold: number); | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold: number); | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval: number); | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold: number); | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range: number); | ||
/** The element to trigger the events on */ | ||
protected el: HTMLElement; | ||
/** Used internally for `taphold` */ | ||
protected startPosition: Position; | ||
/** Used internally for `taphold` */ | ||
protected endPosition: Position; | ||
/** Used internally for `swipe` */ | ||
protected originalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected finalCoord: Position; | ||
/** Used internally for `swipe` */ | ||
protected startEvnt: TouchData | null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
protected tapheld: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected firstTap: TouchData | null; | ||
/** Used internally for `doubletap` */ | ||
protected cooling: boolean; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
protected doubletapped: boolean; | ||
/** Used internally for `doubletap` */ | ||
protected lastTouch: number; | ||
/** Used internally for `swipe` */ | ||
protected hasSwiped: boolean; | ||
/** Used internally for `tap` */ | ||
protected tapStarted: boolean; | ||
/** Used internally for `swipe` */ | ||
protected swipeStarted: boolean; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
protected startTime: number; | ||
protected holdTimer: number; | ||
protected tapTimer: number; | ||
/** Used internally for `doubletap` */ | ||
protected actionTimer: number; | ||
protected settings: Settings; | ||
protected scrollEvents: ScrollEventsService; | ||
constructor(el: HTMLElement, settings?: Settings); | ||
removeEventListeners(): void; | ||
protected getSwipeDir( | ||
startPosition: Position, | ||
endPosition: Position, | ||
hThreshold?: number, | ||
vThreshold?: number | ||
): string; | ||
protected getPostion( | ||
event: TouchEvent | MouseEvent, | ||
type?: TouchType, | ||
index?: number | ||
): Position; | ||
protected getOffset( | ||
event: TouchEvent | MouseEvent, | ||
type?: TouchType, | ||
index?: number | ||
): Offset; | ||
protected getTouchData( | ||
event: TouchEvent | MouseEvent, | ||
withIndex?: boolean, | ||
positionType?: TouchType, | ||
offsetType?: TouchType | ||
): TouchData; | ||
protected addEventListeners(): void; | ||
protected onStartEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onEndEvent(event: TouchEvent | MouseEvent): boolean; | ||
protected onMoveEvent(event: TouchEvent | MouseEvent): boolean; | ||
/** tapstart Event */ | ||
protected tapstart(event: TouchEvent | MouseEvent): boolean; | ||
/** tapmove Event */ | ||
protected tapmove(event: TouchEvent | MouseEvent): boolean; | ||
/** tapend Event */ | ||
protected tapend(event: TouchEvent | MouseEvent): boolean; | ||
/** taphold Event */ | ||
protected taphold(event: TouchEvent | MouseEvent): boolean; | ||
/** doubletap Event */ | ||
protected doubletap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
protected singletap(event: TouchEvent | MouseEvent): void; | ||
/** tap Event */ | ||
protected tap(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
protected swipe(event: TouchEvent | MouseEvent): void; | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
protected swipeend(event: TouchEvent | MouseEvent): void; | ||
} |
@@ -8,507 +8,615 @@ "use strict"; | ||
(function (TouchType) { | ||
TouchType[TouchType["DEFAULT"] = 0] = "DEFAULT"; | ||
TouchType[TouchType["TARGET"] = 1] = "TARGET"; | ||
TouchType[TouchType["CHANGED"] = 2] = "CHANGED"; | ||
})(TouchType = exports.TouchType || (exports.TouchType = {})); | ||
TouchType[(TouchType["DEFAULT"] = 0)] = "DEFAULT"; | ||
TouchType[(TouchType["TARGET"] = 1)] = "TARGET"; | ||
TouchType[(TouchType["CHANGED"] = 2)] = "CHANGED"; | ||
})((TouchType = exports.TouchType || (exports.TouchType = {}))); | ||
class TouchEventService extends base_touch_events_service_1.BaseTouchEventService { | ||
constructor(el, settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: ('ontouchstart' in window), | ||
startevent: ['touchstart'], | ||
endevent: ['touchend'], | ||
moveevent: ['touchmove'], | ||
tapevent: ['tap'], | ||
}) { | ||
super(el); | ||
/** Used internally for `taphold` */ | ||
this.startPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `taphold` */ | ||
this.endPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.originalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.finalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.startEvnt = null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
this.tapheld = false; | ||
/** Used internally for `doubletap` */ | ||
this.firstTap = null; | ||
/** Used internally for `doubletap` */ | ||
this.cooling = false; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
this.doubletapped = false; | ||
/** Used internally for `doubletap` */ | ||
this.lastTouch = 0; | ||
/** Used internally for `swipe` */ | ||
this.hasSwiped = false; | ||
/** Used internally for `tap` */ | ||
this.tapStarted = false; | ||
/** Used internally for `swipe` */ | ||
this.swipeStarted = false; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
this.startTime = 0; | ||
// TIMERS: | ||
this.holdTimer = -1; | ||
this.tapTimer = -1; | ||
/** Used internally for `doubletap` */ | ||
this.actionTimer = -1; | ||
this.el = el; | ||
// Set settings by device type (if device is touch capable) | ||
settings.startevent = settings.touchCapable ? ['touchstart'] : ['mousedown']; | ||
settings.endevent = settings.touchCapable ? ['touchend'] : ['mouseup']; | ||
settings.moveevent = settings.touchCapable ? ['touchmove'] : ['mousemove']; | ||
settings.tapevent = settings.touchCapable ? ['tap'] : ['click']; | ||
this.settings = settings; | ||
this.scrollEvents = new scroll_events_service_1.ScrollEventsService(this.el); | ||
this.addEventListeners(); | ||
constructor( | ||
el, | ||
settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: "ontouchstart" in window, | ||
startevent: ["touchstart"], | ||
endevent: ["touchend"], | ||
moveevent: ["touchmove"], | ||
tapevent: ["tap"], | ||
} | ||
// GETTERS: | ||
get isTouchCapable() { | ||
return this.settings.touchCapable; | ||
) { | ||
super(el); | ||
/** Used internally for `taphold` */ | ||
this.startPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `taphold` */ | ||
this.endPosition = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.originalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.finalCoord = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
/** Used internally for `swipe` */ | ||
this.startEvnt = null; | ||
/** Used internally for `taphold` and `singletap` */ | ||
this.tapheld = false; | ||
/** Used internally for `doubletap` */ | ||
this.firstTap = null; | ||
/** Used internally for `doubletap` */ | ||
this.cooling = false; | ||
/** Used internally for `doubletap` and `singletap` */ | ||
this.doubletapped = false; | ||
/** Used internally for `doubletap` */ | ||
this.lastTouch = 0; | ||
/** Used internally for `swipe` */ | ||
this.hasSwiped = false; | ||
/** Used internally for `tap` */ | ||
this.tapStarted = false; | ||
/** Used internally for `swipe` */ | ||
this.swipeStarted = false; | ||
/** Used internally for `tap`, `taphold` and `singletap` */ | ||
this.startTime = 0; | ||
// TIMERS: | ||
this.holdTimer = -1; | ||
this.tapTimer = -1; | ||
/** Used internally for `doubletap` */ | ||
this.actionTimer = -1; | ||
this.el = el; | ||
// Set settings by device type (if device is touch capable) | ||
settings.startevent = settings.touchCapable | ||
? ["touchstart"] | ||
: ["mousedown"]; | ||
settings.endevent = settings.touchCapable ? ["touchend"] : ["mouseup"]; | ||
settings.moveevent = settings.touchCapable ? ["touchmove"] : ["mousemove"]; | ||
settings.tapevent = settings.touchCapable ? ["tap"] : ["click"]; | ||
this.settings = settings; | ||
this.scrollEvents = new scroll_events_service_1.ScrollEventsService( | ||
this.el | ||
); | ||
this.addEventListeners(); | ||
} | ||
// GETTERS: | ||
get isTouchCapable() { | ||
return this.settings.touchCapable; | ||
} | ||
get startEvent() { | ||
return this.settings.startevent; | ||
} | ||
get endEvent() { | ||
return this.settings.endevent; | ||
} | ||
get moveEvent() { | ||
return this.settings.moveevent; | ||
} | ||
get tapEvent() { | ||
return this.settings.tapevent; | ||
} | ||
get scrollEvent() { | ||
return this.scrollEvents.scrollEvent; | ||
} | ||
// SETTERS: | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get startEvent() { | ||
return this.settings.startevent; | ||
this.settings.swipeHThreshold = threshold; | ||
} | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get endEvent() { | ||
return this.settings.endevent; | ||
this.settings.swipeVThreshold = threshold; | ||
} | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval) { | ||
if (typeof interval !== "number") { | ||
throw new Error("Interval parameter must be a type of number"); | ||
} | ||
get moveEvent() { | ||
return this.settings.moveevent; | ||
this.settings.doubletapInterval = interval; | ||
} | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
get tapEvent() { | ||
return this.settings.tapevent; | ||
this.settings.tapholdThreshold = threshold; | ||
} | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range) { | ||
if (typeof range !== "number") { | ||
throw new Error("Ranger parameter must be a type of number"); | ||
} | ||
get scrollEvent() { | ||
return this.scrollEvents.scrollEvent; | ||
this.settings.tapPixelRange = range; | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.removeEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
// SETTERS: | ||
/** Set the X threshold of swipe events */ | ||
set swipeThresholdX(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.swipeHThreshold = threshold; | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.removeEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
/** Set the Y threshold of swipe events */ | ||
set swipeThresholdY(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.swipeVThreshold = threshold; | ||
for (const eventName of this.settings.endevent) { | ||
this.el.removeEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
/** Set the double tap interval */ | ||
set doubleTapInt(interval) { | ||
if (typeof interval !== 'number') { | ||
throw new Error('Interval parameter must be a type of number'); | ||
} | ||
this.settings.doubletapInterval = interval; | ||
this.scrollEvents.removeEventListeners(); | ||
} | ||
// HELPER METHODS: | ||
getSwipeDir( | ||
startPosition, | ||
endPosition, | ||
hThreshold = this.settings.swipeHThreshold, | ||
vThreshold = this.settings.swipeVThreshold | ||
) { | ||
let swipeDir = ""; | ||
if ( | ||
startPosition.y > endPosition.y && | ||
startPosition.y - endPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipeup"; | ||
} | ||
/** Set the taphold threshold */ | ||
set tapHoldThreshold(threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
this.settings.tapholdThreshold = threshold; | ||
if ( | ||
startPosition.x < endPosition.x && | ||
endPosition.x - startPosition.x > hThreshold | ||
) { | ||
swipeDir = "swiperight"; | ||
} | ||
/** Set the pixel range for tapas */ | ||
set tapRange(range) { | ||
if (typeof range !== 'number') { | ||
throw new Error('Ranger parameter must be a type of number'); | ||
} | ||
this. | ||
settings.tapPixelRange = range; | ||
if ( | ||
startPosition.y < endPosition.y && | ||
endPosition.y - startPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipedown"; | ||
} | ||
removeEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.removeEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.removeEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.endevent) { | ||
this.el.removeEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
this.scrollEvents.removeEventListeners(); | ||
if ( | ||
startPosition.x > endPosition.x && | ||
startPosition.x - endPosition.x > hThreshold | ||
) { | ||
swipeDir = "swipeleft"; | ||
} | ||
// HELPER METHODS: | ||
getSwipeDir(startPosition, endPosition, hThreshold = this.settings.swipeHThreshold, vThreshold = this.settings.swipeVThreshold) { | ||
let swipeDir = ''; | ||
if (startPosition.y > endPosition.y && (startPosition.y - endPosition.y > vThreshold)) { | ||
swipeDir = 'swipeup'; | ||
} | ||
if (startPosition.x < endPosition.x && (endPosition.x - startPosition.x > hThreshold)) { | ||
swipeDir = 'swiperight'; | ||
} | ||
if (startPosition.y < endPosition.y && (endPosition.y - startPosition.y > vThreshold)) { | ||
swipeDir = 'swipedown'; | ||
} | ||
if (startPosition.x > endPosition.x && (startPosition.x - endPosition.x > hThreshold)) { | ||
swipeDir = 'swipeleft'; | ||
} | ||
return swipeDir; | ||
return swipeDir; | ||
} | ||
getPostion(event, type = TouchType.DEFAULT, index = 0) { | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
getPostion(event, type = TouchType.DEFAULT, index = 0) { | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
const position = { | ||
x: (this.settings.touchCapable) ? touchesTypes[index].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? touchesTypes[index].pageY : event.pageY, | ||
}; | ||
return position; | ||
const position = { | ||
x: this.settings.touchCapable ? touchesTypes[index].pageX : event.pageX, | ||
y: this.settings.touchCapable ? touchesTypes[index].pageY : event.pageY, | ||
}; | ||
return position; | ||
} | ||
getOffset(event, type = TouchType.DEFAULT, index = 0) { | ||
const boundingClientRect = this.el.getBoundingClientRect(); | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
getOffset(event, type = TouchType.DEFAULT, index = 0) { | ||
const boundingClientRect = this.el.getBoundingClientRect(); | ||
let touchesTypes; | ||
switch (type) { | ||
case TouchType.CHANGED: | ||
touchesTypes = event.changedTouches; | ||
break; | ||
case TouchType.TARGET: | ||
touchesTypes = event.targetTouches; | ||
break; | ||
default: | ||
touchesTypes = event.touches; | ||
break; | ||
} | ||
const offset = { | ||
x: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageX - (boundingClientRect ? boundingClientRect.left : 0)) : Math.round(event.pageX - (boundingClientRect ? boundingClientRect.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageY - (boundingClientRect ? boundingClientRect.top : 0)) : Math.round(event.pageY - (boundingClientRect ? boundingClientRect.top : 0)), | ||
}; | ||
return offset; | ||
const offset = { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageX - | ||
(boundingClientRect ? boundingClientRect.left : 0) | ||
) | ||
: Math.round( | ||
event.pageX - (boundingClientRect ? boundingClientRect.left : 0) | ||
), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageY - | ||
(boundingClientRect ? boundingClientRect.top : 0) | ||
) | ||
: Math.round( | ||
event.pageY - (boundingClientRect ? boundingClientRect.top : 0) | ||
), | ||
}; | ||
return offset; | ||
} | ||
getTouchData( | ||
event, | ||
withIndex = false, | ||
positionType = TouchType.DEFAULT, | ||
offsetType = TouchType.CHANGED | ||
) { | ||
const touchData = { | ||
position: this.getPostion(event, positionType), | ||
offset: this.getOffset(event, offsetType), | ||
time: Date.now(), | ||
}; | ||
if (withIndex) { | ||
touchData.index = utils_service_1.Utils.getElementIndex(event.target); | ||
} | ||
getTouchData(event, withIndex = false, positionType = TouchType.DEFAULT, offsetType = TouchType.CHANGED) { | ||
const touchData = { | ||
position: this.getPostion(event, positionType), | ||
offset: this.getOffset(event, offsetType), | ||
time: Date.now(), | ||
}; | ||
if (withIndex) { | ||
touchData.index = utils_service_1.Utils.getElementIndex(event.target); | ||
} | ||
return touchData; | ||
return touchData; | ||
} | ||
addEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.addEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
addEventListeners() { | ||
for (const eventName of this.settings.startevent) { | ||
this.el.addEventListener(eventName, this.onStartEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.addEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.endevent) { | ||
this.el.addEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.addEventListener(eventName, this.onMoveEvent.bind(this)); | ||
} | ||
// EVENT HANDLERS: | ||
onStartEvent(event) { | ||
if (event.which && event.which !== 1) { | ||
return false; | ||
} | ||
this.startPosition = this.getPostion(event, TouchType.TARGET); | ||
this.endPosition = { | ||
x: this.startPosition.x, | ||
y: this.startPosition.y, | ||
}; | ||
this.startTime = Date.now(); | ||
// For `doubletap` | ||
this.doubletapped = false; | ||
if (!this.firstTap) { | ||
this.firstTap = this.getTouchData(event, true, TouchType.DEFAULT, TouchType.CHANGED); | ||
} | ||
// For `tap`, `swipe` | ||
this.tapStarted = true; | ||
this.swipeStarted = true; | ||
// For `swipe` | ||
this.originalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.startEvnt = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
this.tapstart(event); | ||
this.taphold(event); | ||
return true; | ||
for (const eventName of this.settings.endevent) { | ||
this.el.addEventListener(eventName, this.onEndEvent.bind(this)); | ||
} | ||
onEndEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.CHANGED); | ||
this.tapheld = false; | ||
window.clearTimeout(this.holdTimer); | ||
this.tapend(event); | ||
this.swipeend(event); | ||
this.tap(event); | ||
this.doubletap(event); | ||
this.singletap(event); | ||
this.tapStarted = false; | ||
this.swipeStarted = false; | ||
this.hasSwiped = false; | ||
return true; | ||
} | ||
// EVENT HANDLERS: | ||
onStartEvent(event) { | ||
if (event.which && event.which !== 1) { | ||
return false; | ||
} | ||
onMoveEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.tapmove(event); | ||
this.swipe(event); | ||
return true; | ||
this.startPosition = this.getPostion(event, TouchType.TARGET); | ||
this.endPosition = { | ||
x: this.startPosition.x, | ||
y: this.startPosition.y, | ||
}; | ||
this.startTime = Date.now(); | ||
// For `doubletap` | ||
this.doubletapped = false; | ||
if (!this.firstTap) { | ||
this.firstTap = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
} | ||
// CUSTOM EVENT METHODS: | ||
/** tapstart Event */ | ||
tapstart(event) { | ||
this.triggerCustomEvent('tapstart', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
return true; | ||
// For `tap`, `swipe` | ||
this.tapStarted = true; | ||
this.swipeStarted = true; | ||
// For `swipe` | ||
this.originalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.startEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
this.tapstart(event); | ||
this.taphold(event); | ||
return true; | ||
} | ||
onEndEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.CHANGED); | ||
this.tapheld = false; | ||
window.clearTimeout(this.holdTimer); | ||
this.tapend(event); | ||
this.swipeend(event); | ||
this.tap(event); | ||
this.doubletap(event); | ||
this.singletap(event); | ||
this.tapStarted = false; | ||
this.swipeStarted = false; | ||
this.hasSwiped = false; | ||
return true; | ||
} | ||
onMoveEvent(event) { | ||
this.endPosition = this.getPostion(event, TouchType.TARGET); | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.tapmove(event); | ||
this.swipe(event); | ||
return true; | ||
} | ||
// CUSTOM EVENT METHODS: | ||
/** tapstart Event */ | ||
tapstart(event) { | ||
this.triggerCustomEvent( | ||
"tapstart", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** tapmove Event */ | ||
tapmove(event) { | ||
this.triggerCustomEvent( | ||
"tapmove", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** tapend Event */ | ||
tapend(event) { | ||
this.triggerCustomEvent( | ||
"tapend", | ||
event, | ||
this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED) | ||
); | ||
return true; | ||
} | ||
/** taphold Event */ | ||
taphold(event) { | ||
this.holdTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
// helded? | ||
if ( | ||
(this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange) | ||
) { | ||
this.tapheld = true; | ||
const endTime = Date.now(); | ||
const duration = endTime - this.startTime; | ||
const touchesLength = event.targetTouches | ||
? event.targetTouches.length | ||
: 1; | ||
const touches = []; | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: this.settings.touchCapable | ||
? event.changedTouches[i].pageX | ||
: event.pageX, | ||
y: this.settings.touchCapable | ||
? event.changedTouches[i].pageY | ||
: event.pageY, | ||
}, | ||
offset: { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageX - | ||
(elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageY - | ||
(elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const eventName = | ||
touchesLength > 1 ? "taphold" + touchesLength : "taphold"; | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
duration, | ||
}; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
}, this.settings.tapholdThreshold); | ||
return true; | ||
} | ||
/** doubletap Event */ | ||
doubletap(event) { | ||
const now = Date.now(); | ||
const lastTouch = Number(this.lastTouch) || now + 1; | ||
const delta = now - lastTouch; | ||
if (this.actionTimer !== -1) { | ||
window.clearTimeout(this.actionTimer); | ||
} | ||
/** tapmove Event */ | ||
tapmove(event) { | ||
this.triggerCustomEvent('tapmove', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
return true; | ||
if ( | ||
delta < this.settings.doubletapInterval && | ||
delta > 100 && | ||
this.firstTap && | ||
utils_service_1.Utils.getElementIndex(event.target) === | ||
this.firstTap.index | ||
) { | ||
this.doubletapped = true; | ||
window.clearTimeout(this.tapTimer); | ||
const lastTap = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
const touchData = { | ||
firstTap: this.firstTap, | ||
secondTap: lastTap, | ||
interval: lastTap.time - this.firstTap.time, | ||
}; | ||
if (!this.cooling) { | ||
this.triggerCustomEvent("doubletap", event, touchData); | ||
this.firstTap = null; | ||
} | ||
this.cooling = true; | ||
window.setTimeout(() => { | ||
this.cooling = false; | ||
}, this.settings.doubletapInterval); | ||
} else { | ||
this.actionTimer = window.setTimeout( | ||
() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, | ||
this.settings.doubletapInterval, | ||
[event] | ||
); | ||
} | ||
/** tapend Event */ | ||
tapend(event) { | ||
this.triggerCustomEvent('tapend', event, this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED)); | ||
return true; | ||
} | ||
/** taphold Event */ | ||
taphold(event) { | ||
this.holdTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
// helded? | ||
if ((this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange)) { | ||
this.tapheld = true; | ||
const endTime = Date.now(); | ||
const duration = endTime - this.startTime; | ||
const touchesLength = (event.targetTouches) ? event.targetTouches.length : 1; | ||
const touches = new Array(); | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: (this.settings.touchCapable) ? event.changedTouches[i].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? event.changedTouches[i].pageY : event.pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const eventName = (touchesLength > 1) ? 'taphold' + touchesLength : 'taphold'; | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
duration, | ||
}; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
}, this.settings.tapholdThreshold); | ||
return true; | ||
} | ||
/** doubletap Event */ | ||
doubletap(event) { | ||
const now = Date.now(); | ||
const lastTouch = Number(this.lastTouch) || now + 1; | ||
const delta = now - lastTouch; | ||
if (this.actionTimer !== -1) { | ||
window.clearTimeout(this.actionTimer); | ||
this.lastTouch = now; | ||
} | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
singletap(event) { | ||
this.tapTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if ( | ||
!this.doubletapped && | ||
!this.tapheld && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchData = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
// Was it a taphold? | ||
if (touchData.time - this.startTime < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent("singletap", event, touchData); | ||
} | ||
if (delta < this.settings.doubletapInterval | ||
&& | ||
delta > 100 | ||
&& | ||
(this.firstTap | ||
&& | ||
utils_service_1.Utils.getElementIndex(event.target) === this.firstTap.index)) { | ||
this.doubletapped = true; | ||
window.clearTimeout(this.tapTimer); | ||
const lastTap = this.getTouchData(event, true, TouchType.CHANGED, TouchType.CHANGED); | ||
const touchData = { | ||
firstTap: this.firstTap, | ||
secondTap: lastTap, | ||
interval: lastTap.time - this.firstTap.time, | ||
}; | ||
if (!this.cooling) { | ||
this.triggerCustomEvent('doubletap', event, touchData); | ||
this.firstTap = null; | ||
} | ||
this.cooling = true; | ||
window.setTimeout(() => { | ||
this.cooling = false; | ||
}, this.settings.doubletapInterval); | ||
} | ||
else { | ||
this.actionTimer = window.setTimeout(() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, this.settings.doubletapInterval, [event]); | ||
} | ||
this.lastTouch = now; | ||
} | ||
/** | ||
* singletap Event | ||
* This is used in conjuction with doubletap when both events are needed on the same element | ||
*/ | ||
singletap(event) { | ||
this.tapTimer = window.setTimeout(() => { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if (!this.doubletapped | ||
&& | ||
!this.tapheld | ||
&& | ||
(((this.startPosition.x === this.endPosition.x) | ||
&& | ||
(this.startPosition.y === this.endPosition.y)) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange))) { | ||
const touchData = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
// Was it a taphold? | ||
if ((touchData.time - this.startTime) < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent('singletap', event, touchData); | ||
} | ||
} | ||
}, this.settings.doubletapInterval); | ||
} | ||
/** tap Event */ | ||
tap(event) { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
} | ||
}, this.settings.doubletapInterval); | ||
} | ||
/** tap Event */ | ||
tap(event) { | ||
const diffPosition = { | ||
x: this.startPosition.x - this.endPosition.x, | ||
y: this.startPosition.y - this.endPosition.y, | ||
}; | ||
if ( | ||
this.tapStarted && | ||
Date.now() - this.startTime < this.settings.tapholdThreshold && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchesLength = event.targetTouches | ||
? event.targetTouches.length | ||
: 1; | ||
const touches = []; | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: this.settings.touchCapable | ||
? event.changedTouches[i].pageX | ||
: event.pageX, | ||
y: this.settings.touchCapable | ||
? event.changedTouches[i].pageY | ||
: event.pageY, | ||
}, | ||
offset: { | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
if (this.tapStarted | ||
&& | ||
((Date.now() - this.startTime) < this.settings.tapholdThreshold) | ||
&& | ||
((this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y) | ||
|| | ||
(diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange))) { | ||
const touchesLength = (event.targetTouches) ? event.targetTouches.length : 1; | ||
const touches = new Array(); | ||
for (let i = 0; i < touchesLength; i++) { | ||
const elOffset = this.el.getBoundingClientRect(); | ||
const touch = { | ||
position: { | ||
x: (this.settings.touchCapable) ? event.changedTouches[i].pageX : event.pageX, | ||
y: (this.settings.touchCapable) ? event.changedTouches[i].pageY : event.pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round(event.pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(event.changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round(event.pageY - (elOffset ? elOffset.top : 0)), | ||
}, | ||
}; | ||
touches.push(touch); | ||
} | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
}; | ||
const eventName = (touchesLength > 1) ? 'tap' + touchesLength : 'tap'; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
touches.push(touch); | ||
} | ||
const touchData = { | ||
touches, | ||
time: Date.now(), | ||
}; | ||
const eventName = touchesLength > 1 ? "tap" + touchesLength : "tap"; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
} | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
swipe(event) { | ||
const swipeDir = this.getSwipeDir(this.originalCoord, this.finalCoord); | ||
if (swipeDir && this.swipeStarted && this.startEvnt) { | ||
this.originalCoord.x = 0; | ||
this.originalCoord.y = 0; | ||
this.finalCoord.x = 0; | ||
this.finalCoord.y = 0; | ||
this.swipeStarted = false; | ||
const endEvnt = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.hasSwiped = true; | ||
this.triggerCustomEvent('swipe', event, touchData); | ||
this.triggerCustomEvent(swipeDir, event, touchData); | ||
} | ||
} | ||
/** | ||
* swipe Event | ||
* (also handles swipeup, swiperight, swipedown and swipeleft) | ||
* | ||
* (similar to `touchMove` method in jquery touch events) | ||
*/ | ||
swipe(event) { | ||
const swipeDir = this.getSwipeDir(this.originalCoord, this.finalCoord); | ||
if (swipeDir && this.swipeStarted && this.startEvnt) { | ||
this.originalCoord.x = 0; | ||
this.originalCoord.y = 0; | ||
this.finalCoord.x = 0; | ||
this.finalCoord.y = 0; | ||
this.swipeStarted = false; | ||
const endEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.hasSwiped = true; | ||
this.triggerCustomEvent("swipe", event, touchData); | ||
this.triggerCustomEvent(swipeDir, event, touchData); | ||
} | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
swipeend(event) { | ||
const endEvnt = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
if (this.hasSwiped && this.startEvnt) { | ||
const swipeDir = this.getSwipeDir(this.startEvnt.position, endEvnt.position); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.triggerCustomEvent('swipeend', event, touchData); | ||
} | ||
} | ||
/** | ||
* swipeend Event | ||
* (similar `touchEnd` method in jquery touch events) | ||
*/ | ||
swipeend(event) { | ||
const endEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
if (this.hasSwiped && this.startEvnt) { | ||
const swipeDir = this.getSwipeDir( | ||
this.startEvnt.position, | ||
endEvnt.position | ||
); | ||
// Calculate the swipe amount (normalized): | ||
const xAmount = Math.abs(this.startEvnt.position.x - endEvnt.position.x); | ||
const yAmount = Math.abs(this.startEvnt.position.y - endEvnt.position.y); | ||
const touchData = { | ||
startEvnt: this.startEvnt, | ||
endEvnt, | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
yAmount, | ||
duration: endEvnt.time - this.startEvnt.time, | ||
}; | ||
this.triggerCustomEvent("swipeend", event, touchData); | ||
} | ||
} | ||
} | ||
exports.TouchEventService = TouchEventService; |
@@ -1,23 +0,23 @@ | ||
import { ScrollPosition } from '../types/scroll-position'; | ||
import { ScrollPosition } from "../types/scroll-position"; | ||
export declare class Utils { | ||
static linear(t: number): number; | ||
static easeInQuad(t: number): number; | ||
static easeOutQuad(t: number): number; | ||
static easeInOutQuad(t: number): number; | ||
static easeInCubic(t: number): number; | ||
static easeOutCubic(t: number): number; | ||
static easeInOutCubic(t: number): number; | ||
static easeInQuart(t: number): number; | ||
static easeOutQuart(t: number): number; | ||
static easeInOutQuart(t: number): number; | ||
static easeInQuint(t: number): number; | ||
static easeOutQuint(t: number): number; | ||
static easeInOutQuint(t: number): number; | ||
static getScrollPosition(element: Element): ScrollPosition; | ||
static isScrollable(element: Element): boolean; | ||
/** | ||
* Similar to JQuerys `$(el).index();` | ||
* @param el | ||
*/ | ||
static getElementIndex(el: Element | null): number; | ||
static linear(t: number): number; | ||
static easeInQuad(t: number): number; | ||
static easeOutQuad(t: number): number; | ||
static easeInOutQuad(t: number): number; | ||
static easeInCubic(t: number): number; | ||
static easeOutCubic(t: number): number; | ||
static easeInOutCubic(t: number): number; | ||
static easeInQuart(t: number): number; | ||
static easeOutQuart(t: number): number; | ||
static easeInOutQuart(t: number): number; | ||
static easeInQuint(t: number): number; | ||
static easeOutQuint(t: number): number; | ||
static easeInOutQuint(t: number): number; | ||
static getScrollPosition(element: Element): ScrollPosition; | ||
static isScrollable(element: Element): boolean; | ||
/** | ||
* Similar to JQuerys `$(el).index();` | ||
* @param el | ||
*/ | ||
static getElementIndex(el: Element | null): number; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class Utils { | ||
// easings methods, see https://pawelgrzybek.com/page-scroll-in-vanilla-javascript/ | ||
static linear(t) { | ||
return t; | ||
// easings methods, see https://pawelgrzybek.com/page-scroll-in-vanilla-javascript/ | ||
static linear(t) { | ||
return t; | ||
} | ||
static easeInQuad(t) { | ||
return t * t; | ||
} | ||
static easeOutQuad(t) { | ||
return t * (2 - t); | ||
} | ||
static easeInOutQuad(t) { | ||
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; | ||
} | ||
static easeInCubic(t) { | ||
return t * t * t; | ||
} | ||
static easeOutCubic(t) { | ||
return --t * t * t + 1; | ||
} | ||
static easeInOutCubic(t) { | ||
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; | ||
} | ||
static easeInQuart(t) { | ||
return t * t * t * t; | ||
} | ||
static easeOutQuart(t) { | ||
return 1 - --t * t * t * t; | ||
} | ||
static easeInOutQuart(t) { | ||
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; | ||
} | ||
static easeInQuint(t) { | ||
return t * t * t * t * t; | ||
} | ||
static easeOutQuint(t) { | ||
return 1 + --t * t * t * t * t; | ||
} | ||
static easeInOutQuint(t) { | ||
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t; | ||
} | ||
static getScrollPosition(element) { | ||
const scrollPosition = { | ||
/** horizontal: left / right / width */ | ||
x: element.scrollTop, | ||
/** vertical: top / bottom / height */ | ||
y: element.scrollLeft, | ||
/** horizontal: left / right / width */ | ||
maxX: element.scrollWidth - element.clientWidth, | ||
/** vertical: top / bottom / height */ | ||
maxY: element.scrollHeight - element.clientHeight, | ||
}; | ||
return scrollPosition; | ||
} | ||
static isScrollable(element) { | ||
const scrollPosition = this.getScrollPosition(element); | ||
return scrollPosition.maxX > 0 || scrollPosition.maxY > 0; | ||
} | ||
/** | ||
* Similar to JQuerys `$(el).index();` | ||
* @param el | ||
*/ | ||
static getElementIndex(el) { | ||
if (!el) { | ||
return -1; | ||
} | ||
static easeInQuad(t) { | ||
return t * t; | ||
} | ||
static easeOutQuad(t) { | ||
return t * (2 - t); | ||
} | ||
static easeInOutQuad(t) { | ||
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; | ||
} | ||
static easeInCubic(t) { | ||
return t * t * t; | ||
} | ||
static easeOutCubic(t) { | ||
return (--t) * t * t + 1; | ||
} | ||
static easeInOutCubic(t) { | ||
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; | ||
} | ||
static easeInQuart(t) { | ||
return t * t * t * t; | ||
} | ||
static easeOutQuart(t) { | ||
return 1 - (--t) * t * t * t; | ||
} | ||
static easeInOutQuart(t) { | ||
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t; | ||
} | ||
static easeInQuint(t) { | ||
return t * t * t * t * t; | ||
} | ||
static easeOutQuint(t) { | ||
return 1 + (--t) * t * t * t * t; | ||
} | ||
static easeInOutQuint(t) { | ||
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; | ||
} | ||
static getScrollPosition(element) { | ||
const scrollPosition = { | ||
/** horizontal: left / right / width */ | ||
x: element.scrollTop, | ||
/** vertical: top / bottom / height */ | ||
y: element.scrollLeft, | ||
/** horizontal: left / right / width */ | ||
maxX: element.scrollWidth - element.clientWidth, | ||
/** vertical: top / bottom / height */ | ||
maxY: element.scrollHeight - element.clientHeight, | ||
}; | ||
return scrollPosition; | ||
} | ||
static isScrollable(element) { | ||
const scrollPosition = this.getScrollPosition(element); | ||
return scrollPosition.maxX > 0 || scrollPosition.maxY > 0; | ||
} | ||
/** | ||
* Similar to JQuerys `$(el).index();` | ||
* @param el | ||
*/ | ||
static getElementIndex(el) { | ||
if (!el) { | ||
return -1; | ||
} | ||
let i = 0; | ||
do { | ||
i++; | ||
el = el.previousElementSibling; | ||
} while (el); | ||
return i; | ||
} | ||
let i = 0; | ||
do { | ||
i++; | ||
el = el.previousElementSibling; | ||
} while (el); | ||
return i; | ||
} | ||
} | ||
exports.Utils = Utils; |
@@ -1,2 +0,2 @@ | ||
export * from './position'; | ||
export * from './scroll-position'; | ||
export * from "./position"; | ||
export * from "./scroll-position"; |
export interface Position { | ||
x: number; | ||
y: number; | ||
x: number; | ||
y: number; | ||
} |
@@ -1,7 +0,7 @@ | ||
import { Position } from './position'; | ||
import { Position } from "./position"; | ||
export interface ScrollPosition extends Position { | ||
/** horizontal: left / right / width */ | ||
maxX: number; | ||
/** vertical: top / bottom / height */ | ||
maxY: number; | ||
/** horizontal: left / right / width */ | ||
maxX: number; | ||
/** vertical: top / bottom / height */ | ||
maxY: number; | ||
} |
@@ -33,694 +33,1119 @@ "use strict"; | ||
exports.default = ($) => { | ||
if (!$) { | ||
console.error('JQuery is required for touch events!'); | ||
return; | ||
if (!$) { | ||
console.error("JQuery is required for touch events!"); | ||
return; | ||
} | ||
("use strict"); | ||
$.attrFn = $.attrFn || {}; | ||
let touchCapable = "ontouchstart" in window, | ||
settings = { | ||
tap_pixel_range: 5, | ||
swipe_h_threshold: 50, | ||
swipe_v_threshold: 50, | ||
taphold_threshold: 750, | ||
doubletap_int: 500, | ||
shake_threshold: 15, | ||
touch_capable: touchCapable, | ||
orientation_support: | ||
"orientation" in window && "onorientationchange" in window, | ||
startevent: touchCapable ? "touchstart" : "mousedown", | ||
endevent: touchCapable ? "touchend" : "mouseup", | ||
moveevent: touchCapable ? "touchmove" : "mousemove", | ||
tapevent: touchCapable ? "tap" : "click", | ||
scrollevent: touchCapable ? "touchmove" : "scroll", | ||
hold_timer: undefined, | ||
tap_timer: undefined, | ||
}; | ||
// Declare touch namespace: | ||
$.touch = {}; | ||
// Convenience functions: | ||
$.isTouchCapable = function () { | ||
return settings.touch_capable; | ||
}; | ||
$.getStartEvent = function () { | ||
return settings.startevent; | ||
}; | ||
$.getEndEvent = function () { | ||
return settings.endevent; | ||
}; | ||
$.getMoveEvent = function () { | ||
return settings.moveevent; | ||
}; | ||
$.getTapEvent = function () { | ||
return settings.tapevent; | ||
}; | ||
$.getScrollEvent = function () { | ||
return settings.scrollevent; | ||
}; | ||
// SETTERS: | ||
// Set the X threshold of swipe events: | ||
$.touch.setSwipeThresholdX = function (threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
'use strict'; | ||
$.attrFn = $.attrFn || {}; | ||
let touchCapable = ('ontouchstart' in window), settings = { | ||
tap_pixel_range: 5, | ||
swipe_h_threshold: 50, | ||
swipe_v_threshold: 50, | ||
taphold_threshold: 750, | ||
doubletap_int: 500, | ||
shake_threshold: 15, | ||
touch_capable: touchCapable, | ||
orientation_support: ('orientation' in window && 'onorientationchange' in window), | ||
startevent: (touchCapable) ? 'touchstart' : 'mousedown', | ||
endevent: (touchCapable) ? 'touchend' : 'mouseup', | ||
moveevent: (touchCapable) ? 'touchmove' : 'mousemove', | ||
tapevent: (touchCapable) ? 'tap' : 'click', | ||
scrollevent: (touchCapable) ? 'touchmove' : 'scroll', | ||
hold_timer: undefined, | ||
tap_timer: undefined, | ||
}; | ||
// Declare touch namespace: | ||
$.touch = {}; | ||
// Convenience functions: | ||
$.isTouchCapable = function () { return settings.touch_capable; }; | ||
$.getStartEvent = function () { return settings.startevent; }; | ||
$.getEndEvent = function () { return settings.endevent; }; | ||
$.getMoveEvent = function () { return settings.moveevent; }; | ||
$.getTapEvent = function () { return settings.tapevent; }; | ||
$.getScrollEvent = function () { return settings.scrollevent; }; | ||
// SETTERS: | ||
// Set the X threshold of swipe events: | ||
$.touch.setSwipeThresholdX = function (threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
settings.swipe_h_threshold = threshold; | ||
}; | ||
// Set the Y threshold of swipe events: | ||
$.touch.setSwipeThresholdY = function (threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
settings.swipe_v_threshold = threshold; | ||
}; | ||
// Set the double tap interval: | ||
$.touch.setDoubleTapInt = function (interval) { | ||
if (typeof interval !== "number") { | ||
throw new Error("Interval parameter must be a type of number"); | ||
} | ||
settings.doubletap_int = interval; | ||
}; | ||
// Set the taphold threshold: | ||
$.touch.setTapHoldThreshold = function (threshold) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
settings.taphold_threshold = threshold; | ||
}; | ||
// Set the pixel range for tapas: | ||
$.touch.setTapRange = function (range) { | ||
if (typeof range !== "number") { | ||
throw new Error("Ranger parameter must be a type of number"); | ||
} | ||
settings.tap_pixel_range = range; | ||
}; | ||
// Add Event shortcuts: | ||
$.each( | ||
[ | ||
"tapstart", | ||
"tapend", | ||
"tapmove", | ||
"tap", | ||
"singletap", | ||
"doubletap", | ||
"taphold", | ||
"swipe", | ||
"swipeup", | ||
"swiperight", | ||
"swipedown", | ||
"swipeleft", | ||
"swipeend", | ||
"scrollstart", | ||
"scrollend", | ||
"orientationchange", | ||
"tap2", | ||
"taphold2", | ||
], | ||
function (i, name) { | ||
$.fn[name] = function (fn) { | ||
return fn ? this.on(name, fn) : this.trigger(name); | ||
}; | ||
$.attrFn[name] = true; | ||
} | ||
); | ||
// tapstart Event: | ||
$.event.special.tapstart = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject); | ||
$this.on(settings.startevent, function tapStartFunc(e) { | ||
$this.data("callee", tapStartFunc); | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
settings.swipe_h_threshold = threshold; | ||
}; | ||
// Set the Y threshold of swipe events: | ||
$.touch.setSwipeThresholdY = function (threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
settings.swipe_v_threshold = threshold; | ||
}; | ||
// Set the double tap interval: | ||
$.touch.setDoubleTapInt = function (interval) { | ||
if (typeof interval !== 'number') { | ||
throw new Error('Interval parameter must be a type of number'); | ||
} | ||
settings.doubletap_int = interval; | ||
}; | ||
// Set the taphold threshold: | ||
$.touch.setTapHoldThreshold = function (threshold) { | ||
if (typeof threshold !== 'number') { | ||
throw new Error('Threshold parameter must be a type of number'); | ||
} | ||
settings.taphold_threshold = threshold; | ||
}; | ||
// Set the pixel range for tapas: | ||
$.touch.setTapRange = function (range) { | ||
if (typeof range !== 'number') { | ||
throw new Error('Ranger parameter must be a type of number'); | ||
} | ||
settings.tap_pixel_range = range; | ||
}; | ||
// Add Event shortcuts: | ||
$.each(['tapstart', 'tapend', 'tapmove', 'tap', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange', 'tap2', 'taphold2'], function (i, name) { | ||
$.fn[name] = function (fn) { | ||
return fn ? this.on(name, fn) : this.trigger(name); | ||
var origEvent = e.originalEvent, | ||
touchData = { | ||
position: { | ||
x: settings.touch_capable ? origEvent.touches[0].pageX : e.pageX, | ||
y: settings.touch_capable ? origEvent.touches[0].pageY : e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
triggerCustomEvent(thisObject, "tapstart", e, touchData); | ||
return true; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee); | ||
}, | ||
}; | ||
// tapmove Event: | ||
$.event.special.tapmove = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject); | ||
$this.on(settings.moveevent, function tapMoveFunc(e) { | ||
$this.data("callee", tapMoveFunc); | ||
var origEvent = e.originalEvent, | ||
touchData = { | ||
position: { | ||
x: settings.touch_capable ? origEvent.touches[0].pageX : e.pageX, | ||
y: settings.touch_capable ? origEvent.touches[0].pageY : e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
triggerCustomEvent(thisObject, "tapmove", e, touchData); | ||
return true; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.moveevent, $(this).data.callee); | ||
}, | ||
}; | ||
// tapend Event: | ||
$.event.special.tapend = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject); | ||
$this.on(settings.endevent, function tapEndFunc(e) { | ||
// Touch event data: | ||
$this.data("callee", tapEndFunc); | ||
var origEvent = e.originalEvent; | ||
var touchData = { | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.changedTouches[0].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
$.attrFn[name] = true; | ||
}); | ||
// tapstart Event: | ||
$.event.special.tapstart = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject); | ||
$this.on(settings.startevent, function tapStartFunc(e) { | ||
$this.data('callee', tapStartFunc); | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
var origEvent = e.originalEvent, touchData = { | ||
'position': { | ||
'x': ((settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX), | ||
'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
triggerCustomEvent(thisObject, 'tapstart', e, touchData); | ||
return true; | ||
}); | ||
triggerCustomEvent(thisObject, "tapend", e, touchData); | ||
return true; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.endevent, $(this).data.callee); | ||
}, | ||
}; | ||
// taphold Event: | ||
$.event.special.taphold = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
origTarget, | ||
start_pos = { | ||
x: 0, | ||
y: 0, | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee); | ||
} | ||
}; | ||
// tapmove Event: | ||
$.event.special.tapmove = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject); | ||
$this.on(settings.moveevent, function tapMoveFunc(e) { | ||
$this.data('callee', tapMoveFunc); | ||
var origEvent = e.originalEvent, touchData = { | ||
'position': { | ||
'x': ((settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX), | ||
'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY | ||
end_x = 0, | ||
end_y = 0; | ||
$this | ||
.on(settings.startevent, function tapHoldFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} else { | ||
$this.data("tapheld", false); | ||
origTarget = e.target; | ||
var origEvent = e.originalEvent; | ||
var start_time = Date.now(); | ||
start_pos.x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
start_pos.y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
end_x = start_pos.x; | ||
end_y = start_pos.y; | ||
// Get the element's threshold: | ||
var ele_threshold = $this.parent().data("threshold") | ||
? $this.parent().data("threshold") | ||
: $this.data("threshold"), | ||
threshold = | ||
typeof ele_threshold !== "undefined" && | ||
ele_threshold !== false && | ||
parseInt(ele_threshold) | ||
? parseInt(ele_threshold) | ||
: settings.taphold_threshold; | ||
settings.hold_timer = window.setTimeout(function () { | ||
var diff_x = start_pos.x - end_x, | ||
diff_y = start_pos.y - end_y; | ||
if ( | ||
e.target == origTarget && | ||
((start_pos.x == end_x && start_pos.y == end_y) || | ||
(diff_x >= -settings.tap_pixel_range && | ||
diff_x <= settings.tap_pixel_range && | ||
diff_y >= -settings.tap_pixel_range && | ||
diff_y <= settings.tap_pixel_range)) | ||
) { | ||
$this.data("tapheld", true); | ||
var end_time = Date.now(); | ||
var duration = end_time - start_time, | ||
touches = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches | ||
: [e], | ||
touchData = []; | ||
for (var i = 0; i < touches.length; i++) { | ||
var touch = { | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.changedTouches[i].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.changedTouches[i].pageY | ||
: e.pageY, | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[i].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[i].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
triggerCustomEvent(thisObject, 'tapmove', e, touchData); | ||
return true; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.moveevent, $(this).data.callee); | ||
} | ||
}; | ||
// tapend Event: | ||
$.event.special.tapend = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject); | ||
$this.on(settings.endevent, function tapEndFunc(e) { | ||
// Touch event data: | ||
$this.data('callee', tapEndFunc); | ||
time: Date.now(), | ||
target: e.target, | ||
duration: duration, | ||
}; | ||
touchData.push(touch); | ||
} | ||
var evt_name = touches.length == 2 ? "taphold2" : "taphold"; | ||
$this.data("callee1", tapHoldFunc1); | ||
triggerCustomEvent(thisObject, evt_name, e, touchData); | ||
} | ||
}, threshold); | ||
return true; | ||
} | ||
}) | ||
.on(settings.endevent, function tapHoldFunc2() { | ||
$this.data("callee2", tapHoldFunc2); | ||
$this.data("tapheld", false); | ||
window.clearTimeout(settings.hold_timer); | ||
}) | ||
.on(settings.moveevent, function tapHoldFunc3(e) { | ||
$this.data("callee3", tapHoldFunc3); | ||
end_x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
end_y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this) | ||
.off(settings.startevent, $(this).data.callee1) | ||
.off(settings.endevent, $(this).data.callee2) | ||
.off(settings.moveevent, $(this).data.callee3); | ||
}, | ||
}; | ||
// doubletap Event: | ||
$.event.special.doubletap = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
action, | ||
firstTap = null, | ||
origEvent, | ||
cooling = false; | ||
$this | ||
.on(settings.startevent, function doubleTapFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
$this.data("doubletapped", false); | ||
$this.data("callee1", doubleTapFunc1); | ||
origEvent = e.originalEvent; | ||
if (!firstTap) { | ||
firstTap = { | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.touches[0].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.touches[0].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
element: e.originalEvent.srcElement, | ||
index: $(e.target).index(), | ||
}; | ||
} | ||
return true; | ||
}) | ||
.on(settings.endevent, function doubleTapFunc2(e) { | ||
var now = Date.now(); | ||
var lastTouch = $this.data("lastTouch") || now + 1; | ||
var delta = now - lastTouch; | ||
window.clearTimeout(action); | ||
$this.data("callee2", doubleTapFunc2); | ||
if ( | ||
delta < settings.doubletap_int && | ||
$(e.target).index() == firstTap.index && | ||
delta > 100 | ||
) { | ||
$this.data("doubletapped", true); | ||
window.clearTimeout(settings.tap_timer); | ||
// Now get the current event: | ||
var lastTap = { | ||
position: { | ||
x: settings.touch_capable | ||
? e.originalEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? e.originalEvent.changedTouches[0].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
element: e.originalEvent.srcElement, | ||
index: $(e.target).index(), | ||
}; | ||
var touchData = { | ||
firstTap: firstTap, | ||
secondTap: lastTap, | ||
interval: lastTap.time - firstTap.time, | ||
}; | ||
if (!cooling) { | ||
triggerCustomEvent(thisObject, "doubletap", e, touchData); | ||
firstTap = null; | ||
} | ||
cooling = true; | ||
} else { | ||
$this.data("lastTouch", now); | ||
action = window.setTimeout( | ||
function () { | ||
firstTap = null; | ||
window.clearTimeout(action); | ||
}, | ||
settings.doubletap_int, | ||
[e] | ||
); | ||
} | ||
$this.data("lastTouch", now); | ||
}); | ||
}, | ||
remove: function () { | ||
$(this) | ||
.off(settings.startevent, $(this).data.callee1) | ||
.off(settings.endevent, $(this).data.callee2); | ||
}, | ||
}; | ||
// singletap Event: | ||
// This is used in conjuction with doubletap when both events are needed on the same element | ||
$.event.special.singletap = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
origTarget = null, | ||
startTime = null, | ||
start_pos = { | ||
x: 0, | ||
y: 0, | ||
}; | ||
$this | ||
.on(settings.startevent, function singleTapFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} else { | ||
startTime = Date.now(); | ||
origTarget = e.target; | ||
$this.data("callee1", singleTapFunc1); | ||
// Get the start x and y position: | ||
start_pos.x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
start_pos.y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
return true; | ||
} | ||
}) | ||
.on(settings.endevent, function singleTapFunc2(e) { | ||
$this.data("callee2", singleTapFunc2); | ||
if (e.target === origTarget) { | ||
// Get the end point: | ||
var end_pos_x = e.originalEvent.changedTouches | ||
? e.originalEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
end_pos_y = e.originalEvent.changedTouches | ||
? e.originalEvent.changedTouches[0].pageY | ||
: e.pageY; | ||
// We need to check if it was a taphold: | ||
settings.tap_timer = window.setTimeout(function () { | ||
var diff_x = start_pos.x - end_pos_x, | ||
diff_y = start_pos.y - end_pos_y; | ||
if ( | ||
!$this.data("doubletapped") && | ||
!$this.data("tapheld") && | ||
((start_pos.x == end_pos_x && start_pos.y == end_pos_y) || | ||
(diff_x >= -settings.tap_pixel_range && | ||
diff_x <= settings.tap_pixel_range && | ||
diff_y >= -settings.tap_pixel_range && | ||
diff_y <= settings.tap_pixel_range)) | ||
) { | ||
var origEvent = e.originalEvent; | ||
var touchData = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.changedTouches[0].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
triggerCustomEvent(thisObject, 'tapend', e, touchData); | ||
return true; | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.endevent, $(this).data.callee); | ||
} | ||
}; | ||
// taphold Event: | ||
$.event.special.taphold = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), origTarget, start_pos = { | ||
x: 0, | ||
y: 0 | ||
}, end_x = 0, end_y = 0; | ||
$this.on(settings.startevent, function tapHoldFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
// Was it a taphold? | ||
if (touchData.time - startTime < settings.taphold_threshold) { | ||
triggerCustomEvent(thisObject, "singletap", e, touchData); | ||
} | ||
else { | ||
$this.data('tapheld', false); | ||
origTarget = e.target; | ||
var origEvent = e.originalEvent; | ||
var start_time = Date.now(); | ||
start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
end_x = start_pos.x; | ||
end_y = start_pos.y; | ||
// Get the element's threshold: | ||
var ele_threshold = ($this.parent().data('threshold')) ? $this.parent().data('threshold') : $this.data('threshold'), threshold = (typeof ele_threshold !== 'undefined' && ele_threshold !== false && parseInt(ele_threshold)) ? parseInt(ele_threshold) : settings.taphold_threshold; | ||
settings.hold_timer = window.setTimeout(function () { | ||
var diff_x = (start_pos.x - end_x), diff_y = (start_pos.y - end_y); | ||
if (e.target == origTarget && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { | ||
$this.data('tapheld', true); | ||
var end_time = Date.now(); | ||
var duration = end_time - start_time, touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [e], touchData = []; | ||
for (var i = 0; i < touches.length; i++) { | ||
var touch = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target, | ||
'duration': duration | ||
}; | ||
touchData.push(touch); | ||
} | ||
var evt_name = (touches.length == 2) ? 'taphold2' : 'taphold'; | ||
$this.data('callee1', tapHoldFunc1); | ||
triggerCustomEvent(thisObject, evt_name, e, touchData); | ||
} | ||
}, threshold); | ||
return true; | ||
} | ||
}).on(settings.endevent, function tapHoldFunc2() { | ||
$this.data('callee2', tapHoldFunc2); | ||
$this.data('tapheld', false); | ||
window.clearTimeout(settings.hold_timer); | ||
}) | ||
.on(settings.moveevent, function tapHoldFunc3(e) { | ||
$this.data('callee3', tapHoldFunc3); | ||
end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
}); | ||
} | ||
}, settings.doubletap_int); | ||
} | ||
}); | ||
}, | ||
remove: function () { | ||
$(this) | ||
.off(settings.startevent, $(this).data.callee1) | ||
.off(settings.endevent, $(this).data.callee2); | ||
}, | ||
}; | ||
// tap Event: | ||
$.event.special.tap = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
started = false, | ||
origTarget = null, | ||
start_time, | ||
start_pos = { | ||
x: 0, | ||
y: 0, | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2).off(settings.moveevent, $(this).data.callee3); | ||
} | ||
}; | ||
// doubletap Event: | ||
$.event.special.doubletap = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), action, firstTap = null, origEvent, cooling = false; | ||
$this.on(settings.startevent, function doubleTapFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
$this.data('doubletapped', false); | ||
$this.data('callee1', doubleTapFunc1); | ||
origEvent = e.originalEvent; | ||
if (!firstTap) { | ||
firstTap = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target, | ||
'element': e.originalEvent.srcElement, | ||
'index': $(e.target).index() | ||
}; | ||
} | ||
return true; | ||
}).on(settings.endevent, function doubleTapFunc2(e) { | ||
var now = Date.now(); | ||
var lastTouch = $this.data('lastTouch') || now + 1; | ||
var delta = now - lastTouch; | ||
window.clearTimeout(action); | ||
$this.data('callee2', doubleTapFunc2); | ||
if (delta < settings.doubletap_int && ($(e.target).index() == firstTap.index) && delta > 100) { | ||
$this.data('doubletapped', true); | ||
window.clearTimeout(settings.tap_timer); | ||
// Now get the current event: | ||
var lastTap = { | ||
'position': { | ||
'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target, | ||
'element': e.originalEvent.srcElement, | ||
'index': $(e.target).index() | ||
}; | ||
var touchData = { | ||
'firstTap': firstTap, | ||
'secondTap': lastTap, | ||
'interval': lastTap.time - firstTap.time | ||
}; | ||
if (!cooling) { | ||
triggerCustomEvent(thisObject, 'doubletap', e, touchData); | ||
firstTap = null; | ||
} | ||
cooling = true; | ||
} | ||
else { | ||
$this.data('lastTouch', now); | ||
action = window.setTimeout(function () { | ||
firstTap = null; | ||
window.clearTimeout(action); | ||
}, settings.doubletap_int, [e]); | ||
} | ||
$this.data('lastTouch', now); | ||
}); | ||
touches; | ||
$this | ||
.on(settings.startevent, function tapFunc1(e) { | ||
$this.data("callee1", tapFunc1); | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} else { | ||
started = true; | ||
start_pos.x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
start_pos.y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
start_time = Date.now(); | ||
origTarget = e.target; | ||
touches = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches | ||
: [e]; | ||
return true; | ||
} | ||
}) | ||
.on(settings.endevent, function tapFunc2(e) { | ||
$this.data("callee2", tapFunc2); | ||
// Only trigger if they've started, and the target matches: | ||
var end_x = e.originalEvent.targetTouches | ||
? e.originalEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
end_y = e.originalEvent.targetTouches | ||
? e.originalEvent.changedTouches[0].pageY | ||
: e.pageY, | ||
diff_x = start_pos.x - end_x, | ||
diff_y = start_pos.y - end_y; | ||
if ( | ||
origTarget == e.target && | ||
started && | ||
Date.now() - start_time < settings.taphold_threshold && | ||
((start_pos.x == end_x && start_pos.y == end_y) || | ||
(diff_x >= -settings.tap_pixel_range && | ||
diff_x <= settings.tap_pixel_range && | ||
diff_y >= -settings.tap_pixel_range && | ||
diff_y <= settings.tap_pixel_range)) | ||
) { | ||
var origEvent = e.originalEvent; | ||
var touchData = []; | ||
for (var i = 0; i < touches.length; i++) { | ||
var touch = { | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.changedTouches[i].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.changedTouches[i].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[i].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[i].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
touchData.push(touch); | ||
} | ||
var evt_name = touches.length == 2 ? "tap2" : "tap"; | ||
triggerCustomEvent(thisObject, evt_name, e, touchData); | ||
} | ||
}); | ||
}, | ||
remove: function () { | ||
$(this) | ||
.off(settings.startevent, $(this).data.callee1) | ||
.off(settings.endevent, $(this).data.callee2); | ||
}, | ||
}; | ||
// swipe Event (also handles swipeup, swiperight, swipedown and swipeleft): | ||
$.event.special.swipe = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
started = false, | ||
hasSwiped = false, | ||
originalCoord = { | ||
x: 0, | ||
y: 0, | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); | ||
} | ||
}; | ||
// singletap Event: | ||
// This is used in conjuction with doubletap when both events are needed on the same element | ||
$.event.special.singletap = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), origTarget = null, startTime = null, start_pos = { | ||
x: 0, | ||
y: 0 | ||
}; | ||
$this.on(settings.startevent, function singleTapFunc1(e) { | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
else { | ||
startTime = Date.now(); | ||
origTarget = e.target; | ||
$this.data('callee1', singleTapFunc1); | ||
// Get the start x and y position: | ||
start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
return true; | ||
} | ||
}).on(settings.endevent, function singleTapFunc2(e) { | ||
$this.data('callee2', singleTapFunc2); | ||
if (e.target === origTarget) { | ||
// Get the end point: | ||
var end_pos_x = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX, end_pos_y = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY; | ||
// We need to check if it was a taphold: | ||
settings.tap_timer = window.setTimeout(function () { | ||
var diff_x = (start_pos.x - end_pos_x), diff_y = (start_pos.y - end_pos_y); | ||
if (!$this.data('doubletapped') && !$this.data('tapheld') && (((start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { | ||
var origEvent = e.originalEvent; | ||
var touchData = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
// Was it a taphold? | ||
if ((touchData.time - startTime) < settings.taphold_threshold) { | ||
triggerCustomEvent(thisObject, 'singletap', e, touchData); | ||
} | ||
} | ||
}, settings.doubletap_int); | ||
} | ||
}); | ||
finalCoord = { | ||
x: 0, | ||
y: 0, | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); | ||
startEvnt; | ||
// Screen touched, store the original coordinate | ||
function touchStart(e) { | ||
$this = $(e.currentTarget); | ||
$this.data("callee1", touchStart); | ||
originalCoord.x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
originalCoord.y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
finalCoord.x = originalCoord.x; | ||
finalCoord.y = originalCoord.y; | ||
started = true; | ||
var origEvent = e.originalEvent; | ||
// Read event data into our startEvt: | ||
startEvnt = { | ||
position: { | ||
x: settings.touch_capable ? origEvent.touches[0].pageX : e.pageX, | ||
y: settings.touch_capable ? origEvent.touches[0].pageY : e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
} | ||
// Store coordinates as finger is swiping | ||
function touchMove(e) { | ||
$this = $(e.currentTarget); | ||
$this.data("callee2", touchMove); | ||
finalCoord.x = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageX | ||
: e.pageX; | ||
finalCoord.y = e.originalEvent.targetTouches | ||
? e.originalEvent.targetTouches[0].pageY | ||
: e.pageY; | ||
var swipedir; | ||
// We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: | ||
var ele_x_threshold = $this.parent().data("xthreshold") | ||
? $this.parent().data("xthreshold") | ||
: $this.data("xthreshold"), | ||
ele_y_threshold = $this.parent().data("ythreshold") | ||
? $this.parent().data("ythreshold") | ||
: $this.data("ythreshold"), | ||
h_threshold = | ||
typeof ele_x_threshold !== "undefined" && | ||
ele_x_threshold !== false && | ||
parseInt(ele_x_threshold) | ||
? parseInt(ele_x_threshold) | ||
: settings.swipe_h_threshold, | ||
v_threshold = | ||
typeof ele_y_threshold !== "undefined" && | ||
ele_y_threshold !== false && | ||
parseInt(ele_y_threshold) | ||
? parseInt(ele_y_threshold) | ||
: settings.swipe_v_threshold; | ||
if ( | ||
originalCoord.y > finalCoord.y && | ||
originalCoord.y - finalCoord.y > v_threshold | ||
) { | ||
swipedir = "swipeup"; | ||
} | ||
}; | ||
// tap Event: | ||
$.event.special.tap = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), started = false, origTarget = null, start_time, start_pos = { | ||
x: 0, | ||
y: 0 | ||
}, touches; | ||
$this.on(settings.startevent, function tapFunc1(e) { | ||
$this.data('callee1', tapFunc1); | ||
if (e.which && e.which !== 1) { | ||
return false; | ||
} | ||
else { | ||
started = true; | ||
start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
start_time = Date.now(); | ||
origTarget = e.target; | ||
touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [e]; | ||
return true; | ||
} | ||
}).on(settings.endevent, function tapFunc2(e) { | ||
$this.data('callee2', tapFunc2); | ||
// Only trigger if they've started, and the target matches: | ||
var end_x = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX, end_y = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY, diff_x = (start_pos.x - end_x), diff_y = (start_pos.y - end_y); | ||
if (origTarget == e.target && started && ((Date.now() - start_time) < settings.taphold_threshold) && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { | ||
var origEvent = e.originalEvent; | ||
var touchData = []; | ||
for (var i = 0; i < touches.length; i++) { | ||
var touch = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
touchData.push(touch); | ||
} | ||
var evt_name = (touches.length == 2) ? 'tap2' : 'tap'; | ||
triggerCustomEvent(thisObject, evt_name, e, touchData); | ||
} | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); | ||
if ( | ||
originalCoord.x < finalCoord.x && | ||
finalCoord.x - originalCoord.x > h_threshold | ||
) { | ||
swipedir = "swiperight"; | ||
} | ||
}; | ||
// swipe Event (also handles swipeup, swiperight, swipedown and swipeleft): | ||
$.event.special.swipe = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), started = false, hasSwiped = false, originalCoord = { | ||
x: 0, | ||
y: 0 | ||
}, finalCoord = { | ||
x: 0, | ||
y: 0 | ||
}, startEvnt; | ||
// Screen touched, store the original coordinate | ||
function touchStart(e) { | ||
$this = $(e.currentTarget); | ||
$this.data('callee1', touchStart); | ||
originalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
originalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
finalCoord.x = originalCoord.x; | ||
finalCoord.y = originalCoord.y; | ||
started = true; | ||
var origEvent = e.originalEvent; | ||
// Read event data into our startEvt: | ||
startEvnt = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
} | ||
// Store coordinates as finger is swiping | ||
function touchMove(e) { | ||
$this = $(e.currentTarget); | ||
$this.data('callee2', touchMove); | ||
finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; | ||
finalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; | ||
var swipedir; | ||
// We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: | ||
var ele_x_threshold = ($this.parent().data('xthreshold')) ? $this.parent().data('xthreshold') : $this.data('xthreshold'), ele_y_threshold = ($this.parent().data('ythreshold')) ? $this.parent().data('ythreshold') : $this.data('ythreshold'), h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold, v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; | ||
if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) { | ||
swipedir = 'swipeup'; | ||
} | ||
if (originalCoord.x < finalCoord.x && (finalCoord.x - originalCoord.x > h_threshold)) { | ||
swipedir = 'swiperight'; | ||
} | ||
if (originalCoord.y < finalCoord.y && (finalCoord.y - originalCoord.y > v_threshold)) { | ||
swipedir = 'swipedown'; | ||
} | ||
if (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { | ||
swipedir = 'swipeleft'; | ||
} | ||
if (swipedir != undefined && started) { | ||
originalCoord.x = 0; | ||
originalCoord.y = 0; | ||
finalCoord.x = 0; | ||
finalCoord.y = 0; | ||
started = false; | ||
// Read event data into our endEvnt: | ||
var origEvent = e.originalEvent; | ||
var endEvnt = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
// Calculate the swipe amount (normalized): | ||
var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); | ||
var touchData = { | ||
'startEvnt': startEvnt, | ||
'endEvnt': endEvnt, | ||
'direction': swipedir.replace('swipe', ''), | ||
'xAmount': xAmount, | ||
'yAmount': yAmount, | ||
'duration': endEvnt.time - startEvnt.time | ||
}; | ||
hasSwiped = true; | ||
$this.trigger('swipe', touchData).trigger(swipedir, touchData); | ||
} | ||
} | ||
function touchEnd(e) { | ||
$this = $(e.currentTarget); | ||
var swipedir = ""; | ||
$this.data('callee3', touchEnd); | ||
if (hasSwiped) { | ||
// We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: | ||
var ele_x_threshold = $this.data('xthreshold'), ele_y_threshold = $this.data('ythreshold'), h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold, v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; | ||
var origEvent = e.originalEvent; | ||
var endEvnt = { | ||
'position': { | ||
'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, | ||
'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY | ||
}, | ||
'offset': { | ||
'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), | ||
'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) | ||
}, | ||
'time': Date.now(), | ||
'target': e.target | ||
}; | ||
// Read event data into our endEvnt: | ||
if (startEvnt.position.y > endEvnt.position.y && (startEvnt.position.y - endEvnt.position.y > v_threshold)) { | ||
swipedir = 'swipeup'; | ||
} | ||
if (startEvnt.position.x < endEvnt.position.x && (endEvnt.position.x - startEvnt.position.x > h_threshold)) { | ||
swipedir = 'swiperight'; | ||
} | ||
if (startEvnt.position.y < endEvnt.position.y && (endEvnt.position.y - startEvnt.position.y > v_threshold)) { | ||
swipedir = 'swipedown'; | ||
} | ||
if (startEvnt.position.x > endEvnt.position.x && (startEvnt.position.x - endEvnt.position.x > h_threshold)) { | ||
swipedir = 'swipeleft'; | ||
} | ||
// Calculate the swipe amount (normalized): | ||
var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); | ||
var touchData = { | ||
'startEvnt': startEvnt, | ||
'endEvnt': endEvnt, | ||
'direction': swipedir.replace('swipe', ''), | ||
'xAmount': xAmount, | ||
'yAmount': yAmount, | ||
'duration': endEvnt.time - startEvnt.time | ||
}; | ||
$this.trigger('swipeend', touchData); | ||
} | ||
started = false; | ||
hasSwiped = false; | ||
} | ||
$this.on(settings.startevent, touchStart); | ||
$this.on(settings.moveevent, touchMove); | ||
$this.on(settings.endevent, touchEnd); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.startevent, $(this).data.callee1).off(settings.moveevent, $(this).data.callee2).off(settings.endevent, $(this).data.callee3); | ||
if ( | ||
originalCoord.y < finalCoord.y && | ||
finalCoord.y - originalCoord.y > v_threshold | ||
) { | ||
swipedir = "swipedown"; | ||
} | ||
}; | ||
// scrollstart Event (also handles scrollend): | ||
$.event.special.scrollstart = { | ||
setup: function () { | ||
var thisObject = this, $this = $(thisObject), scrolling, timer; | ||
function trigger(event, state) { | ||
scrolling = state; | ||
triggerCustomEvent(thisObject, scrolling ? 'scrollstart' : 'scrollend', event); | ||
} | ||
// iPhone triggers scroll after a small delay; use touchmove instead | ||
$this.on(settings.scrollevent, function scrollFunc(event) { | ||
$this.data('callee', scrollFunc); | ||
if (!scrolling) { | ||
trigger(event, true); | ||
} | ||
clearTimeout(timer); | ||
timer = setTimeout(function () { | ||
trigger(event, false); | ||
}, 50); | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.scrollevent, $(this).data.callee); | ||
if ( | ||
originalCoord.x > finalCoord.x && | ||
originalCoord.x - finalCoord.x > h_threshold | ||
) { | ||
swipedir = "swipeleft"; | ||
} | ||
}; | ||
// This is the orientation change (largely borrowed from jQuery Mobile): | ||
var win = $(window), get_orientation, last_orientation, initial_orientation_is_landscape, initial_orientation_is_default, portrait_map = { | ||
'0': true, | ||
'180': true | ||
}; | ||
if (settings.orientation_support) { | ||
var ww = window.innerWidth || win.width(), wh = window.innerHeight || win.height(), landscape_threshold = 50; | ||
initial_orientation_is_landscape = ww > wh && (ww - wh) > landscape_threshold; | ||
initial_orientation_is_default = portrait_map[window.orientation]; | ||
if ((initial_orientation_is_landscape && initial_orientation_is_default) || (!initial_orientation_is_landscape && !initial_orientation_is_default)) { | ||
portrait_map = { | ||
'-90': true, | ||
'90': true | ||
}; | ||
if (swipedir != undefined && started) { | ||
originalCoord.x = 0; | ||
originalCoord.y = 0; | ||
finalCoord.x = 0; | ||
finalCoord.y = 0; | ||
started = false; | ||
// Read event data into our endEvnt: | ||
var origEvent = e.originalEvent; | ||
var endEvnt = { | ||
position: { | ||
x: settings.touch_capable ? origEvent.touches[0].pageX : e.pageX, | ||
y: settings.touch_capable ? origEvent.touches[0].pageY : e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
// Calculate the swipe amount (normalized): | ||
var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), | ||
yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); | ||
var touchData = { | ||
startEvnt: startEvnt, | ||
endEvnt: endEvnt, | ||
direction: swipedir.replace("swipe", ""), | ||
xAmount: xAmount, | ||
yAmount: yAmount, | ||
duration: endEvnt.time - startEvnt.time, | ||
}; | ||
hasSwiped = true; | ||
$this.trigger("swipe", touchData).trigger(swipedir, touchData); | ||
} | ||
} | ||
$.event.special.orientationchange = { | ||
setup: function () { | ||
// If the event is supported natively, return false so that jQuery | ||
// will on to the event using DOM methods. | ||
if (settings.orientation_support) { | ||
return false; | ||
} | ||
// Get the current orientation to avoid initial double-triggering. | ||
last_orientation = get_orientation(); | ||
win.on('throttledresize', handler); | ||
return true; | ||
}, | ||
teardown: function () { | ||
if (settings.orientation_support) { | ||
return false; | ||
} | ||
win.off('throttledresize', handler); | ||
return true; | ||
}, | ||
add: function (handleObj) { | ||
// Save a reference to the bound event handler. | ||
var old_handler = handleObj.handler; | ||
handleObj.handler = function (event) { | ||
event.orientation = get_orientation(); | ||
return old_handler.apply(this, arguments); | ||
}; | ||
} | ||
function touchEnd(e) { | ||
$this = $(e.currentTarget); | ||
var swipedir = ""; | ||
$this.data("callee3", touchEnd); | ||
if (hasSwiped) { | ||
// We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: | ||
var ele_x_threshold = $this.data("xthreshold"), | ||
ele_y_threshold = $this.data("ythreshold"), | ||
h_threshold = | ||
typeof ele_x_threshold !== "undefined" && | ||
ele_x_threshold !== false && | ||
parseInt(ele_x_threshold) | ||
? parseInt(ele_x_threshold) | ||
: settings.swipe_h_threshold, | ||
v_threshold = | ||
typeof ele_y_threshold !== "undefined" && | ||
ele_y_threshold !== false && | ||
parseInt(ele_y_threshold) | ||
? parseInt(ele_y_threshold) | ||
: settings.swipe_v_threshold; | ||
var origEvent = e.originalEvent; | ||
var endEvnt = { | ||
position: { | ||
x: settings.touch_capable | ||
? origEvent.changedTouches[0].pageX | ||
: e.pageX, | ||
y: settings.touch_capable | ||
? origEvent.changedTouches[0].pageY | ||
: e.pageY, | ||
}, | ||
offset: { | ||
x: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageX - | ||
($this.offset() ? $this.offset().left : 0) | ||
) | ||
: Math.round( | ||
e.pageX - ($this.offset() ? $this.offset().left : 0) | ||
), | ||
y: settings.touch_capable | ||
? Math.round( | ||
origEvent.changedTouches[0].pageY - | ||
($this.offset() ? $this.offset().top : 0) | ||
) | ||
: Math.round( | ||
e.pageY - ($this.offset() ? $this.offset().top : 0) | ||
), | ||
}, | ||
time: Date.now(), | ||
target: e.target, | ||
}; | ||
// Read event data into our endEvnt: | ||
if ( | ||
startEvnt.position.y > endEvnt.position.y && | ||
startEvnt.position.y - endEvnt.position.y > v_threshold | ||
) { | ||
swipedir = "swipeup"; | ||
} | ||
if ( | ||
startEvnt.position.x < endEvnt.position.x && | ||
endEvnt.position.x - startEvnt.position.x > h_threshold | ||
) { | ||
swipedir = "swiperight"; | ||
} | ||
if ( | ||
startEvnt.position.y < endEvnt.position.y && | ||
endEvnt.position.y - startEvnt.position.y > v_threshold | ||
) { | ||
swipedir = "swipedown"; | ||
} | ||
if ( | ||
startEvnt.position.x > endEvnt.position.x && | ||
startEvnt.position.x - endEvnt.position.x > h_threshold | ||
) { | ||
swipedir = "swipeleft"; | ||
} | ||
// Calculate the swipe amount (normalized): | ||
var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), | ||
yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); | ||
var touchData = { | ||
startEvnt: startEvnt, | ||
endEvnt: endEvnt, | ||
direction: swipedir.replace("swipe", ""), | ||
xAmount: xAmount, | ||
yAmount: yAmount, | ||
duration: endEvnt.time - startEvnt.time, | ||
}; | ||
$this.trigger("swipeend", touchData); | ||
} | ||
started = false; | ||
hasSwiped = false; | ||
} | ||
$this.on(settings.startevent, touchStart); | ||
$this.on(settings.moveevent, touchMove); | ||
$this.on(settings.endevent, touchEnd); | ||
}, | ||
remove: function () { | ||
$(this) | ||
.off(settings.startevent, $(this).data.callee1) | ||
.off(settings.moveevent, $(this).data.callee2) | ||
.off(settings.endevent, $(this).data.callee3); | ||
}, | ||
}; | ||
// scrollstart Event (also handles scrollend): | ||
$.event.special.scrollstart = { | ||
setup: function () { | ||
var thisObject = this, | ||
$this = $(thisObject), | ||
scrolling, | ||
timer; | ||
function trigger(event, state) { | ||
scrolling = state; | ||
triggerCustomEvent( | ||
thisObject, | ||
scrolling ? "scrollstart" : "scrollend", | ||
event | ||
); | ||
} | ||
// iPhone triggers scroll after a small delay; use touchmove instead | ||
$this.on(settings.scrollevent, function scrollFunc(event) { | ||
$this.data("callee", scrollFunc); | ||
if (!scrolling) { | ||
trigger(event, true); | ||
} | ||
clearTimeout(timer); | ||
timer = setTimeout(function () { | ||
trigger(event, false); | ||
}, 50); | ||
}); | ||
}, | ||
remove: function () { | ||
$(this).off(settings.scrollevent, $(this).data.callee); | ||
}, | ||
}; | ||
// This is the orientation change (largely borrowed from jQuery Mobile): | ||
var win = $(window), | ||
get_orientation, | ||
last_orientation, | ||
initial_orientation_is_landscape, | ||
initial_orientation_is_default, | ||
portrait_map = { | ||
"0": true, | ||
"180": true, | ||
}; | ||
// If the event is not supported natively, this handler will be bound to | ||
// the window resize event to simulate the orientationchange event. | ||
function handler() { | ||
// Get the current orientation. | ||
var orientation = get_orientation(); | ||
if (orientation !== last_orientation) { | ||
// The orientation has changed, so trigger the orientationchange event. | ||
last_orientation = orientation; | ||
win.trigger("orientationchange"); | ||
} | ||
if (settings.orientation_support) { | ||
var ww = window.innerWidth || win.width(), | ||
wh = window.innerHeight || win.height(), | ||
landscape_threshold = 50; | ||
initial_orientation_is_landscape = ww > wh && ww - wh > landscape_threshold; | ||
initial_orientation_is_default = portrait_map[window.orientation]; | ||
if ( | ||
(initial_orientation_is_landscape && initial_orientation_is_default) || | ||
(!initial_orientation_is_landscape && !initial_orientation_is_default) | ||
) { | ||
portrait_map = { | ||
"-90": true, | ||
"90": true, | ||
}; | ||
} | ||
$.event.special.orientationchange.orientation = get_orientation = function () { | ||
var isPortrait = true, elem = document.documentElement; | ||
if (settings.orientation_support) { | ||
isPortrait = portrait_map[window.orientation]; | ||
} | ||
$.event.special.orientationchange = { | ||
setup: function () { | ||
// If the event is supported natively, return false so that jQuery | ||
// will on to the event using DOM methods. | ||
if (settings.orientation_support) { | ||
return false; | ||
} | ||
// Get the current orientation to avoid initial double-triggering. | ||
last_orientation = get_orientation(); | ||
win.on("throttledresize", handler); | ||
return true; | ||
}, | ||
teardown: function () { | ||
if (settings.orientation_support) { | ||
return false; | ||
} | ||
win.off("throttledresize", handler); | ||
return true; | ||
}, | ||
add: function (handleObj) { | ||
// Save a reference to the bound event handler. | ||
var old_handler = handleObj.handler; | ||
handleObj.handler = function (event) { | ||
event.orientation = get_orientation(); | ||
return old_handler.apply(this, arguments); | ||
}; | ||
}, | ||
}; | ||
// If the event is not supported natively, this handler will be bound to | ||
// the window resize event to simulate the orientationchange event. | ||
function handler() { | ||
// Get the current orientation. | ||
var orientation = get_orientation(); | ||
if (orientation !== last_orientation) { | ||
// The orientation has changed, so trigger the orientationchange event. | ||
last_orientation = orientation; | ||
win.trigger("orientationchange"); | ||
} | ||
} | ||
$.event.special.orientationchange.orientation = get_orientation = function () { | ||
var isPortrait = true, | ||
elem = document.documentElement; | ||
if (settings.orientation_support) { | ||
isPortrait = portrait_map[window.orientation]; | ||
} else { | ||
isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1; | ||
} | ||
return isPortrait ? "portrait" : "landscape"; | ||
}; | ||
// throttle Handler: | ||
$.event.special.throttledresize = { | ||
setup: function () { | ||
$(this).on("resize", throttle_handler); | ||
}, | ||
teardown: function () { | ||
$(this).off("resize", throttle_handler); | ||
}, | ||
}; | ||
var throttle = 250, | ||
throttle_handler = function () { | ||
curr = Date.now(); | ||
diff = curr - lastCall; | ||
if (diff >= throttle) { | ||
lastCall = curr; | ||
$(this).trigger("throttledresize"); | ||
} else { | ||
if (heldCall) { | ||
window.clearTimeout(heldCall); | ||
} | ||
else { | ||
isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1; | ||
} | ||
return isPortrait ? 'portrait' : 'landscape'; | ||
}; | ||
// throttle Handler: | ||
$.event.special.throttledresize = { | ||
// Promise a held call will still execute | ||
heldCall = window.setTimeout(handler, throttle - diff); | ||
} | ||
}, | ||
lastCall = 0, | ||
heldCall, | ||
curr, | ||
diff; | ||
// Trigger a custom event: | ||
function triggerCustomEvent(obj, eventType, event, touchData) { | ||
var originalType = event.type; | ||
event.type = eventType; | ||
$.event.dispatch.call(obj, event, touchData); | ||
event.type = originalType; | ||
} | ||
// Correctly on anything we've overloaded: | ||
$.each( | ||
{ | ||
scrollend: "scrollstart", | ||
swipeup: "swipe", | ||
swiperight: "swipe", | ||
swipedown: "swipe", | ||
swipeleft: "swipe", | ||
swipeend: "swipe", | ||
tap2: "tap", | ||
taphold2: "taphold", | ||
}, | ||
function (e, srcE) { | ||
$.event.special[e] = { | ||
setup: function () { | ||
$(this).on('resize', throttle_handler); | ||
$(this).on(srcE, $.noop); | ||
}, | ||
teardown: function () { | ||
$(this).off('resize', throttle_handler); | ||
} | ||
}; | ||
var throttle = 250, throttle_handler = function () { | ||
curr = Date.now(); | ||
diff = curr - lastCall; | ||
if (diff >= throttle) { | ||
lastCall = curr; | ||
$(this).trigger('throttledresize'); | ||
} | ||
else { | ||
if (heldCall) { | ||
window.clearTimeout(heldCall); | ||
} | ||
// Promise a held call will still execute | ||
heldCall = window.setTimeout(handler, throttle - diff); | ||
} | ||
}, lastCall = 0, heldCall, curr, diff; | ||
// Trigger a custom event: | ||
function triggerCustomEvent(obj, eventType, event, touchData) { | ||
var originalType = event.type; | ||
event.type = eventType; | ||
$.event.dispatch.call(obj, event, touchData); | ||
event.type = originalType; | ||
}; | ||
} | ||
// Correctly on anything we've overloaded: | ||
$.each({ | ||
scrollend: 'scrollstart', | ||
swipeup: 'swipe', | ||
swiperight: 'swipe', | ||
swipedown: 'swipe', | ||
swipeleft: 'swipe', | ||
swipeend: 'swipe', | ||
tap2: 'tap', | ||
taphold2: 'taphold' | ||
}, function (e, srcE) { | ||
$.event.special[e] = { | ||
setup: function () { | ||
$(this).on(srcE, $.noop); | ||
} | ||
}; | ||
}); | ||
return $; | ||
); | ||
return $; | ||
}; |
@@ -1,1 +0,1 @@ | ||
export * from './jquery.module'; | ||
export * from "./jquery.module"; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./jquery.module")); |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var __importDefault = | ||
(this && this.__importDefault) || | ||
function (mod) { | ||
return mod && mod.__esModule ? mod : { default: mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -10,3 +12,5 @@ const jquery_1 = __importDefault(require("jquery")); | ||
*/ | ||
const _jquery_touch_events_1 = __importDefault(require("./_jquery-touch-events")); | ||
const _jquery_touch_events_1 = __importDefault( | ||
require("./_jquery-touch-events") | ||
); | ||
// tslint:disable-next-line:variable-name | ||
@@ -13,0 +17,0 @@ const JQuery = _jquery_touch_events_1.default(jquery_1.default); |
{ | ||
"name": "@ribajs/extras", | ||
"description": "Extras module for Riba.js", | ||
"version": "1.9.0-alpha.0", | ||
"version": "1.9.0-alpha.1", | ||
"author": "Pascal Garber <pascal@artandcode.studio>", | ||
@@ -31,28 +31,32 @@ "contributors": [], | ||
"devDependencies": { | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.9.0", | ||
"@babel/plugin-proposal-class-properties": "^7.8.3", | ||
"@babel/plugin-proposal-export-default-from": "^7.8.3", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.9.5", | ||
"@babel/cli": "^7.10.4", | ||
"@babel/core": "^7.10.4", | ||
"@babel/plugin-proposal-class-properties": "^7.10.4", | ||
"@babel/plugin-proposal-export-default-from": "^7.10.4", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.10.4", | ||
"@babel/plugin-syntax-dynamic-import": "^7.8.3", | ||
"@babel/preset-env": "^7.9.5", | ||
"@babel/preset-typescript": "^7.9.0", | ||
"@babel/runtime-corejs3": "^7.9.2", | ||
"@types/jest": "^25.2.1", | ||
"@typescript-eslint/eslint-plugin": "^2.29.0", | ||
"@typescript-eslint/parser": "^2.29.0", | ||
"@babel/preset-env": "^7.10.4", | ||
"@babel/preset-typescript": "^7.10.4", | ||
"@babel/runtime-corejs3": "^7.10.4", | ||
"@ribajs/eslint-config": "1.9.0-alpha.1", | ||
"@types/jest": "^26.0.4", | ||
"@typescript-eslint/eslint-plugin": "^3.6.0", | ||
"@typescript-eslint/parser": "^3.6.0", | ||
"babel-loader": "^8.1.0", | ||
"babel-plugin-array-includes": "^2.0.3", | ||
"core-js": "^3.6.5", | ||
"eslint": "^6.8.0", | ||
"jest": "^25.4.0", | ||
"eslint": "^7.4.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"jest": "^26.1.0", | ||
"jest-extended": "^0.11.5", | ||
"ts-jest": "^25.4.0", | ||
"typescript": "^3.8.3", | ||
"webpack": "^5.0.0-beta.15", | ||
"webpack-cli": "^3.3.11" | ||
"prettier": "^2.0.5", | ||
"ts-jest": "^26.1.1", | ||
"typescript": "^3.9.6", | ||
"webpack": "^5.0.0-beta.22", | ||
"webpack-cli": "^3.3.12" | ||
}, | ||
"dependencies": { | ||
"@ribajs/core": "1.9.0-alpha.0", | ||
"@ribajs/utils": "1.9.0-alpha.0" | ||
"@ribajs/core": "1.9.0-alpha.1", | ||
"@ribajs/utils": "1.9.0-alpha.1" | ||
}, | ||
@@ -59,0 +63,0 @@ "bugs": { |
@@ -1,3 +0,3 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { debounce } from '@ribajs/utils/src/control'; | ||
import { Binder } from "@ribajs/core"; | ||
import { debounce } from "@ribajs/utils/src/control"; | ||
@@ -18,3 +18,3 @@ const DEFAULT_OFFSET = 10; | ||
export const dataScrollPositionYBinder: Binder<string> = { | ||
name: 'data-scroll-position-y', | ||
name: "data-scroll-position-y", | ||
customData: {}, | ||
@@ -26,10 +26,15 @@ bind() { | ||
this.customData.onScroll = () => { | ||
if (this.customData.elementSelector === 'window') { | ||
if (this.customData.elementSelector === "window") { | ||
const element = this.customData.watchScrollOnElement as Window; | ||
if (element.scrollY <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = 'top'; | ||
} else if ((element.innerHeight + element.pageYOffset + this.customData.offsetBottom) >= document.body.offsetHeight) { | ||
this.el.dataset.scrollPositionY = 'bottom'; | ||
this.el.dataset.scrollPositionY = "top"; | ||
} else if ( | ||
element.innerHeight + | ||
element.pageYOffset + | ||
this.customData.offsetBottom >= | ||
document.body.offsetHeight | ||
) { | ||
this.el.dataset.scrollPositionY = "bottom"; | ||
} else { | ||
this.el.dataset.scrollPositionY = 'scrolled'; | ||
this.el.dataset.scrollPositionY = "scrolled"; | ||
} | ||
@@ -39,25 +44,32 @@ } else { | ||
if (element.scrollTop <= 0 + this.customData.offsetTop) { | ||
this.el.dataset.scrollPositionY = 'top'; | ||
} else if ((element.scrollTop + this.customData.offsetBottom) >= element.scrollHeight - element.clientHeight) { | ||
this.el.dataset.scrollPositionY = 'bottom'; | ||
this.el.dataset.scrollPositionY = "top"; | ||
} else if ( | ||
element.scrollTop + this.customData.offsetBottom >= | ||
element.scrollHeight - element.clientHeight | ||
) { | ||
this.el.dataset.scrollPositionY = "bottom"; | ||
} else { | ||
this.el.dataset.scrollPositionY = 'scrolled'; | ||
this.el.dataset.scrollPositionY = "scrolled"; | ||
} | ||
} | ||
}; | ||
}, | ||
routine(el: HTMLElement, elementSelector = 'window') { | ||
routine(el: HTMLElement, elementSelector = "window") { | ||
// Remove old scroll event | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener('scroll', debounce.bind(this, this.customData.onScroll.bind(this))); | ||
this.customData.watchScrollOnElement.removeEventListener( | ||
"scroll", | ||
debounce.bind(this, this.customData.onScroll.bind(this)) | ||
); | ||
} | ||
// Set new element to watch for the scroll event | ||
if (elementSelector === 'window') { | ||
if (elementSelector === "window") { | ||
this.customData.watchScrollOnElement = window; | ||
} else if (elementSelector === 'this') { | ||
} else if (elementSelector === "this") { | ||
this.customData.watchScrollOnElement = this.el; | ||
} else { | ||
this.customData.watchScrollOnElement = document.querySelector(elementSelector); | ||
this.customData.watchScrollOnElement = document.querySelector( | ||
elementSelector | ||
); | ||
} | ||
@@ -68,7 +80,13 @@ | ||
// console.debug('addEventListener', this.customData.watchScrollOnElement); | ||
this.customData.watchScrollOnElement.addEventListener('scroll', debounce(this.customData.onScroll.bind(this)), { passive: true }); | ||
this.customData.watchScrollOnElement.addEventListener( | ||
"scroll", | ||
debounce(this.customData.onScroll.bind(this)), | ||
{ passive: true } | ||
); | ||
} | ||
this.customData.offsetTop = Number(this.el.dataset.offsetTop) || DEFAULT_OFFSET; | ||
this.customData.offsetBottom = Number(this.el.dataset.offsetBottom) || DEFAULT_OFFSET; | ||
this.customData.offsetTop = | ||
Number(this.el.dataset.offsetTop) || DEFAULT_OFFSET; | ||
this.customData.offsetBottom = | ||
Number(this.el.dataset.offsetBottom) || DEFAULT_OFFSET; | ||
this.customData.elementSelector = elementSelector; | ||
@@ -82,5 +100,8 @@ | ||
if (this.customData.watchScrollOnElement) { | ||
this.customData.watchScrollOnElement.removeEventListener('scroll', debounce(this.customData.onScroll.bind(this))); | ||
this.customData.watchScrollOnElement.removeEventListener( | ||
"scroll", | ||
debounce(this.customData.onScroll.bind(this)) | ||
); | ||
} | ||
}, | ||
}; |
@@ -1,5 +0,6 @@ | ||
export { dataScrollPositionYBinder } from './data-scroll-position-y.binder'; | ||
export { touchEventsBinder } from './touch-events.binder'; | ||
export { scrollEventsBinder } from './scroll-events.binder'; | ||
export { autoscrollBinder } from './scrollbar-autoscroll.binder'; | ||
export { scrollbarDraggableBinder } from './scrollbar-draggable.binder'; | ||
export { dataScrollPositionYBinder } from "./data-scroll-position-y.binder"; | ||
export { touchEventsBinder } from "./touch-events.binder"; | ||
export { scrollEventsBinder } from "./scroll-events.binder"; | ||
export { autoscrollBinder } from "./scrollbar-autoscroll.binder"; | ||
export { scrollbarDraggableBinder } from "./scrollbar-draggable.binder"; | ||
export { syncElementPropertyBinder } from "./sync-element-property.binder"; |
@@ -1,6 +0,6 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { ScrollEventsService } from '../services/touch-events/scroll-events.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { ScrollEventsService } from "../services/touch-events/scroll-events.service"; | ||
export const scrollEventsBinder: Binder<string> = { | ||
name: 'scroll-events', | ||
name: "scroll-events", | ||
bind(el) { | ||
@@ -18,4 +18,4 @@ if (!this.customData) { | ||
routine() { | ||
// nothing | ||
// nothing | ||
}, | ||
}; |
@@ -1,4 +0,4 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { isString } from '@ribajs/utils/src/type'; | ||
import { Autoscroll, AutoscrollOptions } from '../services/autoscroll.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { isString } from "@ribajs/utils/src/type"; | ||
import { Autoscroll, AutoscrollOptions } from "../services/autoscroll.service"; | ||
@@ -9,7 +9,7 @@ /** | ||
export const autoscrollBinder: Binder<AutoscrollOptions> = { | ||
name: 'autoscroll', | ||
name: "autoscroll", | ||
routine(el: HTMLElement, options: AutoscrollOptions) { | ||
this.customData = this.customData || {}; | ||
if (options && options.width && isString(options.width)) { | ||
if (options.width === '100vw') { | ||
if (options.width === "100vw") { | ||
el.style.width = options.width; | ||
@@ -16,0 +16,0 @@ } else { |
@@ -1,3 +0,3 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { Dragscroll, DragscrollOptions } from '../services/dragscroll.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { Dragscroll, DragscrollOptions } from "../services/dragscroll.service"; | ||
@@ -8,3 +8,3 @@ /** | ||
export const scrollbarDraggableBinder: Binder<DragscrollOptions> = { | ||
name: 'scrollbar-draggable', | ||
name: "scrollbar-draggable", | ||
routine(el: HTMLElement, options: DragscrollOptions) { | ||
@@ -11,0 +11,0 @@ this.customData = this.customData || {}; |
@@ -1,6 +0,6 @@ | ||
import { Binder } from '@ribajs/core'; | ||
import { TouchEventsService } from '../services/touch-events/touch-events.service'; | ||
import { Binder } from "@ribajs/core"; | ||
import { TouchEventsService } from "../services/touch-events/touch-events.service"; | ||
export const touchEventsBinder: Binder<string> = { | ||
name: 'touch-events', | ||
name: "touch-events", | ||
bind(el) { | ||
@@ -18,4 +18,4 @@ if (!this.customData) { | ||
routine() { | ||
// nothing | ||
// nothing | ||
}, | ||
}; |
@@ -1,5 +0,5 @@ | ||
import { RibaModule } from '@ribajs/core'; | ||
import * as binders from './binders'; | ||
import { RibaModule } from "@ribajs/core"; | ||
import * as binders from "./binders"; | ||
// import * as formatters from './formatters'; | ||
import * as services from './services'; | ||
import * as services from "./services"; | ||
// import * as components from './components'; | ||
@@ -6,0 +6,0 @@ |
@@ -1,4 +0,4 @@ | ||
export * from './services'; | ||
export * from './binders'; | ||
export * from './types'; | ||
export * from './extras.module'; | ||
export * from "./services"; | ||
export * from "./binders"; | ||
export * from "./types"; | ||
export * from "./extras.module"; |
@@ -1,6 +0,6 @@ | ||
import { Utils as ExtraUtils } from './utils.service'; | ||
import { Gameloop } from './gameloop.service'; | ||
import { Utils as ExtraUtils } from "./utils.service"; | ||
import { Gameloop } from "./gameloop.service"; | ||
export interface AutoscrollOptions { | ||
angle?: 'vertical' | 'horizontal'; | ||
angle?: "vertical" | "horizontal"; | ||
direction?: 1 | -1; | ||
@@ -13,5 +13,4 @@ velocity?: number; | ||
export class Autoscroll { | ||
protected touchCapable = "ontouchstart" in window; | ||
protected touchCapable = ('ontouchstart' in window); | ||
protected direction = 1; | ||
@@ -33,3 +32,3 @@ | ||
protected angle: 'horizontal' | 'vertical' = 'horizontal'; | ||
protected angle: "horizontal" | "vertical" = "horizontal"; | ||
@@ -46,3 +45,6 @@ protected pauseOnHover = true; | ||
this.angle = this.options.angle || this.angle; | ||
this.pauseOnHover = typeof(this.options.pauseOnHover) === 'boolean' ? this.options.pauseOnHover : this.pauseOnHover; | ||
this.pauseOnHover = | ||
typeof this.options.pauseOnHover === "boolean" | ||
? this.options.pauseOnHover | ||
: this.pauseOnHover; | ||
@@ -52,3 +54,5 @@ this.limit = this.getLimit(this.el); | ||
window.addEventListener('resize', this.onResize.bind(this), {passive: true}); | ||
window.addEventListener("resize", this.onResize.bind(this), { | ||
passive: true, | ||
}); | ||
@@ -63,26 +67,54 @@ if (this.direction === -1) { | ||
this.el.addEventListener('mouseenter', this.onMouseIn.bind(this), {passive: true}); | ||
this.el.addEventListener('mouseover', this.onMouseIn.bind(this), {passive: true}); | ||
this.el.addEventListener('focusin', this.onMouseIn.bind(this), {passive: true}); | ||
this.el.addEventListener('touchstart', this.onMouseIn.bind(this), {passive: true}); | ||
this.el.addEventListener("mouseenter", this.onMouseIn.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("mouseover", this.onMouseIn.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("focusin", this.onMouseIn.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("touchstart", this.onMouseIn.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener('mouseleave', this.onMouseOut.bind(this), {passive: true}); | ||
this.el.addEventListener('focusout', this.onMouseOut.bind(this), {passive: true}); | ||
this.el.addEventListener("mouseleave", this.onMouseOut.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("focusout", this.onMouseOut.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener('mouseup', this.onMouseUp.bind(this), {passive: true}); | ||
this.el.addEventListener('touchend', this.onMouseUp.bind(this), {passive: true}); | ||
this.el.addEventListener("mouseup", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("touchend", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
if (this.touchCapable) { | ||
this.el.addEventListener('scroll', this.onMouseUp.bind(this), {passive: true}); | ||
this.el.addEventListener('scrollend', this.onMouseUp.bind(this), {passive: true}); | ||
this.el.addEventListener("scroll", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("scrollend", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
// See ScrollEventsService for "scrollended" event | ||
this.el.addEventListener('scrollended', this.onMouseUp.bind(this), {passive: true}); | ||
this.el.addEventListener("scrollended", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
} else { | ||
this.el.addEventListener('scroll', this.onScroll.bind(this), {passive: true}); | ||
this.el.addEventListener('scrollend', this.onScroll.bind(this), {passive: true}); | ||
this.el.addEventListener('scrollended', this.onScroll.bind(this), {passive: true}); | ||
this.el.addEventListener("scroll", this.onScroll.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("scrollend", this.onScroll.bind(this), { | ||
passive: true, | ||
}); | ||
this.el.addEventListener("scrollended", this.onScroll.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
Gameloop.events.on('render', this.render.bind(this)); | ||
Gameloop.events.on('update', this.updateMove.bind(this)); | ||
Gameloop.events.on("render", this.render.bind(this)); | ||
Gameloop.events.on("update", this.updateMove.bind(this)); | ||
@@ -105,3 +137,3 @@ Gameloop.startLoop({ maxFPS: 60 }); | ||
public pause() { | ||
this.el.style.scrollBehavior = ''; | ||
this.el.style.scrollBehavior = ""; | ||
this._pause = true; | ||
@@ -122,3 +154,3 @@ } | ||
// Disable smooth scrolling on autoscroll if set | ||
this.el.style.scrollBehavior = 'auto'; | ||
this.el.style.scrollBehavior = "auto"; | ||
}, delay); | ||
@@ -128,27 +160,27 @@ } | ||
protected removeEventListeners() { | ||
window.removeEventListener('resize', this.onResize.bind(this)); | ||
window.removeEventListener("resize", this.onResize.bind(this)); | ||
this.el.removeEventListener('mouseenter', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('mouseover', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('focusin', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('touchstart', this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("mouseenter", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("mouseover", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("focusin", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener("touchstart", this.onMouseIn.bind(this)); | ||
this.el.removeEventListener('mouseleave', this.onMouseOut.bind(this)); | ||
this.el.removeEventListener('focusout', this.onMouseOut.bind(this)); | ||
this.el.removeEventListener("mouseleave", this.onMouseOut.bind(this)); | ||
this.el.removeEventListener("focusout", this.onMouseOut.bind(this)); | ||
this.el.removeEventListener('mouseup', this.onMouseUp.bind(this)); | ||
this.el.removeEventListener('touchend', this.onMouseUp.bind(this)); | ||
this.el.removeEventListener("mouseup", this.onMouseUp.bind(this)); | ||
this.el.removeEventListener("touchend", this.onMouseUp.bind(this)); | ||
if (this.touchCapable) { | ||
this.el.removeEventListener('scroll', this.onMouseUp.bind(this)); | ||
this.el.removeEventListener('scrollend', this.onMouseUp.bind(this)); | ||
this.el.removeEventListener('scrollended', this.onMouseUp.bind(this)); | ||
this.el.removeEventListener("scroll", this.onMouseUp.bind(this)); | ||
this.el.removeEventListener("scrollend", this.onMouseUp.bind(this)); | ||
this.el.removeEventListener("scrollended", this.onMouseUp.bind(this)); | ||
} else { | ||
this.el.removeEventListener('scroll', this.onScroll.bind(this)); | ||
this.el.removeEventListener('scrollend', this.onScroll.bind(this)); | ||
this.el.removeEventListener('scrollended', this.onScroll.bind(this)); | ||
this.el.removeEventListener("scroll", this.onScroll.bind(this)); | ||
this.el.removeEventListener("scrollend", this.onScroll.bind(this)); | ||
this.el.removeEventListener("scrollended", this.onScroll.bind(this)); | ||
} | ||
Gameloop.events.off('render', this.render.bind(this)); | ||
Gameloop.events.off('update', this.updateMove.bind(this)); | ||
Gameloop.events.off("render", this.render.bind(this)); | ||
Gameloop.events.off("update", this.updateMove.bind(this)); | ||
} | ||
@@ -187,3 +219,5 @@ | ||
protected getPosition() { | ||
return (this.angle === 'vertical' ? this.el.scrollTop : this.el.scrollLeft) || 0; | ||
return ( | ||
(this.angle === "vertical" ? this.el.scrollTop : this.el.scrollLeft) || 0 | ||
); | ||
} | ||
@@ -196,3 +230,5 @@ | ||
protected getLimit(el: HTMLElement) { | ||
return this.angle === 'vertical' ? ExtraUtils.getScrollPosition(el).maxY : ExtraUtils.getScrollPosition(el).maxX; | ||
return this.angle === "vertical" | ||
? ExtraUtils.getScrollPosition(el).maxY | ||
: ExtraUtils.getScrollPosition(el).maxX; | ||
} | ||
@@ -210,3 +246,3 @@ | ||
* https://isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing | ||
* | ||
* | ||
* Without this the scrollbar scrolls smooth, need to find out why. | ||
@@ -228,3 +264,3 @@ */ | ||
this.lastMove = this.move; | ||
const append = ((this.velocity * this.direction) * delta); | ||
const append = this.velocity * this.direction * delta; | ||
this.move += append; | ||
@@ -243,3 +279,3 @@ | ||
protected scroll(move: number) { | ||
if (this.angle === 'vertical') { | ||
if (this.angle === "vertical") { | ||
this.el.scrollTop = move; | ||
@@ -250,3 +286,2 @@ } else { | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Utils } from './utils.service'; | ||
import { Utils } from "./utils.service"; | ||
@@ -17,5 +17,8 @@ export interface DragscrollOptions { | ||
protected pushed = false; | ||
protected touchCapable = ('ontouchstart' in window); | ||
protected touchCapable = "ontouchstart" in window; | ||
constructor(el: HTMLElement, options: DragscrollOptions = { detectGlobalMove: true }) { | ||
constructor( | ||
el: HTMLElement, | ||
options: DragscrollOptions = { detectGlobalMove: true } | ||
) { | ||
this.el = el; | ||
@@ -29,20 +32,34 @@ this.options = options; | ||
el.removeEventListener('mousedown', this.onMouseDown.bind(this), false); | ||
el.addEventListener('mousedown', this.onMouseDown.bind(this), {passive: true}); | ||
el.removeEventListener("mousedown", this.onMouseDown.bind(this), false); | ||
el.addEventListener("mousedown", this.onMouseDown.bind(this), { | ||
passive: true, | ||
}); | ||
window.addEventListener('resize', this.checkDraggable.bind(this)); | ||
window.addEventListener("resize", this.checkDraggable.bind(this)); | ||
// Use global move if your element does not use the full width / height | ||
if (this.options.detectGlobalMove) { | ||
window.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
window.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
window.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
window.removeEventListener( | ||
"mousemove", | ||
this.onMouseMove.bind(this), | ||
false | ||
); | ||
window.addEventListener('mouseup', this.onMouseUp.bind(this), {passive: true}); | ||
window.addEventListener('mousemove', this.onMouseMove.bind(this), {passive: true}); | ||
window.addEventListener("mouseup", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
window.addEventListener("mousemove", this.onMouseMove.bind(this), { | ||
passive: true, | ||
}); | ||
} else { | ||
el.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
el.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
el.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
el.removeEventListener("mousemove", this.onMouseMove.bind(this), false); | ||
el.addEventListener('mouseup', this.onMouseUp.bind(this), {passive: true}); | ||
el.addEventListener('mousemove', this.onMouseMove.bind(this), {passive: true}); | ||
el.addEventListener("mouseup", this.onMouseUp.bind(this), { | ||
passive: true, | ||
}); | ||
el.addEventListener("mousemove", this.onMouseMove.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
@@ -56,3 +73,3 @@ | ||
this.removeEventListeners(); | ||
this.el.classList.remove('draggable'); | ||
this.el.classList.remove("draggable"); | ||
} | ||
@@ -62,10 +79,10 @@ | ||
if (Utils.isScrollable(this.el)) { | ||
this.el.classList.add('draggable'); | ||
this.el.classList.add("draggable"); | ||
return true; | ||
} | ||
this.el.classList.remove('draggable'); | ||
this.el.classList.remove("draggable"); | ||
return false; | ||
} | ||
protected onMouseDown <EventListener>(e: MouseEvent) { | ||
protected onMouseDown<EventListener>(e: MouseEvent) { | ||
this.pushed = true; | ||
@@ -76,12 +93,14 @@ this.lastClientX = e.clientX; | ||
protected onMouseUp <EventListener>() { | ||
protected onMouseUp<EventListener>() { | ||
this.pushed = false; | ||
} | ||
protected onMouseMove <EventListener>(e: MouseEvent) { | ||
protected onMouseMove<EventListener>(e: MouseEvent) { | ||
let newScrollX = 0; | ||
let newScrollY = 0; | ||
if (this.pushed) { | ||
this.el.scrollLeft -= newScrollX = (- this.lastClientX + (this.lastClientX = e.clientX)); | ||
this.el.scrollTop -= newScrollY = (- this.lastClientY + (this.lastClientY = e.clientY)); | ||
this.el.scrollLeft -= newScrollX = | ||
-this.lastClientX + (this.lastClientX = e.clientX); | ||
this.el.scrollTop -= newScrollY = | ||
-this.lastClientY + (this.lastClientY = e.clientY); | ||
if (this.el === document.body) { | ||
@@ -98,8 +117,15 @@ if (document.documentElement) { | ||
protected removeEventListeners() { | ||
window.removeEventListener('resize', this.checkDraggable); | ||
this.el.removeEventListener('mousedown', this.onMouseDown.bind(this), false); | ||
this.el.removeEventListener('mouseup', this.onMouseUp.bind(this), false); | ||
this.el.removeEventListener('mousemove', this.onMouseMove.bind(this), false); | ||
window.removeEventListener("resize", this.checkDraggable); | ||
this.el.removeEventListener( | ||
"mousedown", | ||
this.onMouseDown.bind(this), | ||
false | ||
); | ||
this.el.removeEventListener("mouseup", this.onMouseUp.bind(this), false); | ||
this.el.removeEventListener( | ||
"mousemove", | ||
this.onMouseMove.bind(this), | ||
false | ||
); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { EventDispatcher } from '@ribajs/core'; | ||
import { EventDispatcher } from "@ribajs/core"; | ||
@@ -12,5 +12,4 @@ export interface GameloopOptions { | ||
export class Gameloop { | ||
public static events = new EventDispatcher("gameloop"); | ||
public static events = new EventDispatcher('gameloop'); | ||
public static maxFPS = 60; | ||
@@ -23,5 +22,4 @@ | ||
public static startLoop(options: GameloopOptions = {}) { | ||
this.setOptions(options); | ||
this.setOptions(options); | ||
if (!this.loopStarted) { | ||
@@ -51,3 +49,4 @@ this.loopStarted = true; | ||
protected static setOptions(options: GameloopOptions) { | ||
this.maxFPS = typeof(options.maxFPS) === 'number' ? options.maxFPS : this.maxFPS; | ||
this.maxFPS = | ||
typeof options.maxFPS === "number" ? options.maxFPS : this.maxFPS; | ||
} | ||
@@ -60,5 +59,4 @@ | ||
protected static loop(timestamp: number) { | ||
// Throttle the frame rate. | ||
if (timestamp < this.lastFrameTimeMs + (1000 / this.maxFPS)) { | ||
if (timestamp < this.lastFrameTimeMs + 1000 / this.maxFPS) { | ||
this.frameID = requestAnimationFrame(this.loop.bind(this)); | ||
@@ -100,15 +98,15 @@ return; | ||
protected static begin(timestamp: number, delta: number) { | ||
this.events.trigger('begin', timestamp, delta); | ||
this.events.trigger("begin", timestamp, delta); | ||
} | ||
protected static render(interp: number) { | ||
this.events.trigger('render', interp); | ||
this.events.trigger("render", interp); | ||
} | ||
protected static update(delta: number) { | ||
this.events.trigger('update', delta); | ||
this.events.trigger("update", delta); | ||
} | ||
protected static end(delta: number) { | ||
this.events.trigger('end', delta); | ||
this.events.trigger("end", delta); | ||
} | ||
@@ -123,3 +121,2 @@ | ||
} | ||
} |
@@ -1,7 +0,7 @@ | ||
export * from './autoscroll.service'; | ||
export * from './dragscroll.service'; | ||
export * from './fullscreen.service'; | ||
export * from './gameloop.service'; | ||
export * from './touch-events/scroll-events.service'; | ||
export * from './touch-events/touch-events.service'; | ||
export * from './utils.service'; | ||
export * from "./autoscroll.service"; | ||
export * from "./dragscroll.service"; | ||
export * from "./fullscreen.service"; | ||
export * from "./gameloop.service"; | ||
export * from "./touch-events/scroll-events.service"; | ||
export * from "./touch-events/touch-events.service"; | ||
export * from "./utils.service"; |
export abstract class BaseTouchEventsService { | ||
protected touchCapable = ('ontouchstart' in window); | ||
protected touchCapable = "ontouchstart" in window; | ||
/** The element to trigger the events on */ | ||
@@ -12,3 +12,7 @@ protected el: HTMLElement; | ||
protected triggerCustomEvent(eventName: string, originalEvent: Event, extraParameters: any = {}) { | ||
protected triggerCustomEvent( | ||
eventName: string, | ||
originalEvent: Event, | ||
extraParameters: any = {} | ||
) { | ||
extraParameters.originalEvent = originalEvent; | ||
@@ -22,3 +26,2 @@ extraParameters.target = originalEvent.target; | ||
} | ||
} |
// import { Utils as ExtraUtils } from '../utils.service'; | ||
import { BaseTouchEventsService } from './base-touch-events.service'; | ||
import { BaseTouchEventsService } from "./base-touch-events.service"; | ||
export class ScrollEventsService extends BaseTouchEventsService { | ||
public isScrolling = false; | ||
protected _scrollEvent: Array<'touchmove' | 'scroll' | 'scrollend'>; | ||
protected _scrollEvent: Array<"touchmove" | "scroll" | "scrollend">; | ||
@@ -19,3 +18,5 @@ /** The element to trigger the events on */ | ||
// Watch also native scrollend to not trigger scrollended before scrollend was triggered | ||
this._scrollEvent = this.touchCapable ? ['touchmove', 'scrollend', 'scroll'] : ['scroll', 'scrollend']; | ||
this._scrollEvent = this.touchCapable | ||
? ["touchmove", "scrollend", "scroll"] | ||
: ["scroll", "scrollend"]; | ||
this.addEventListeners(); | ||
@@ -34,3 +35,6 @@ } | ||
for (const eventName of this._scrollEvent) { | ||
this.el.removeEventListener<any>(eventName, this.onScrollEvent.bind(this)); | ||
this.el.removeEventListener<any>( | ||
eventName, | ||
this.onScrollEvent.bind(this) | ||
); | ||
} | ||
@@ -41,3 +45,5 @@ } | ||
for (const eventName of this._scrollEvent) { | ||
this.el.addEventListener<any>(eventName, this.onScrollEvent.bind(this), {passive: true}); | ||
this.el.addEventListener<any>(eventName, this.onScrollEvent.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
@@ -64,3 +70,3 @@ } | ||
this.isScrolling = true; | ||
this.triggerCustomEvent('scrollstart', event, {}); | ||
this.triggerCustomEvent("scrollstart", event, {}); | ||
} | ||
@@ -75,3 +81,3 @@ | ||
this.scrollTimer = window.setTimeout(() => { | ||
this.triggerCustomEvent('scrollended', event, {}); | ||
this.triggerCustomEvent("scrollended", event, {}); | ||
this.isScrolling = false; | ||
@@ -78,0 +84,0 @@ }, 200); |
@@ -1,6 +0,6 @@ | ||
import { Utils as ExtraUtils } from '../utils.service'; | ||
import { Position } from '../../types'; | ||
import { Utils as ExtraUtils } from "../utils.service"; | ||
import { Position } from "../../types"; | ||
// import { ScrollEventsService } from './scroll-events.service'; | ||
import { BaseTouchEventsService } from './base-touch-events.service'; | ||
import { BaseTouchEventsService } from "./base-touch-events.service"; | ||
@@ -44,6 +44,6 @@ /** | ||
startevent: Array<'touchstart' | 'mousedown'>; | ||
endevent: Array<'touchend' | 'touchcancel' | 'mouseup'>; | ||
moveevent: Array<'touchmove' | 'mousemove'>; | ||
tapevent: Array<'tap' | 'click'>; | ||
startevent: Array<"touchstart" | "mousedown">; | ||
endevent: Array<"touchend" | "touchcancel" | "mouseup">; | ||
moveevent: Array<"touchmove" | "mousemove">; | ||
tapevent: Array<"tap" | "click">; | ||
} | ||
@@ -70,3 +70,2 @@ | ||
export class TouchEventsService extends BaseTouchEventsService { | ||
// GETTERS: | ||
@@ -101,4 +100,6 @@ | ||
/** Set the X threshold of swipe events */ | ||
public set swipeThresholdX( threshold: number ) { | ||
if ( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } | ||
public set swipeThresholdX(threshold: number) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
this.settings.swipeHThreshold = threshold; | ||
@@ -108,4 +109,6 @@ } | ||
/** Set the Y threshold of swipe events */ | ||
public set swipeThresholdY( threshold: number ) { | ||
if ( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } | ||
public set swipeThresholdY(threshold: number) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
this.settings.swipeVThreshold = threshold; | ||
@@ -115,4 +118,6 @@ } | ||
/** Set the double tap interval */ | ||
public set doubleTapInt( interval: number ) { | ||
if ( typeof interval !== 'number' ) { throw new Error('Interval parameter must be a type of number'); } | ||
public set doubleTapInt(interval: number) { | ||
if (typeof interval !== "number") { | ||
throw new Error("Interval parameter must be a type of number"); | ||
} | ||
this.settings.doubletapInterval = interval; | ||
@@ -122,4 +127,6 @@ } | ||
/** Set the taphold threshold */ | ||
public set tapHoldThreshold( threshold: number ) { | ||
if ( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } | ||
public set tapHoldThreshold(threshold: number) { | ||
if (typeof threshold !== "number") { | ||
throw new Error("Threshold parameter must be a type of number"); | ||
} | ||
this.settings.tapholdThreshold = threshold; | ||
@@ -129,6 +136,7 @@ } | ||
/** Set the pixel range for tapas */ | ||
public set tapRange( range: number ) { | ||
if ( typeof range !== 'number' ) { throw new Error('Ranger parameter must be a type of number'); } | ||
this. | ||
settings.tapPixelRange = range; | ||
public set tapRange(range: number) { | ||
if (typeof range !== "number") { | ||
throw new Error("Ranger parameter must be a type of number"); | ||
} | ||
this.settings.tapPixelRange = range; | ||
} | ||
@@ -207,16 +215,19 @@ | ||
constructor(el: HTMLElement, settings: Settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: ('ontouchstart' in window), | ||
constructor( | ||
el: HTMLElement, | ||
settings: Settings = { | ||
tapPixelRange: 5, | ||
swipeHThreshold: 50, | ||
swipeVThreshold: 50, | ||
tapholdThreshold: 750, | ||
doubletapInterval: 500, | ||
shakeThreshold: 15, | ||
touchCapable: "ontouchstart" in window, | ||
startevent: ['touchstart'], | ||
endevent: ['touchend'], | ||
moveevent: ['touchmove'], | ||
tapevent: ['tap'], | ||
}) { | ||
startevent: ["touchstart"], | ||
endevent: ["touchend"], | ||
moveevent: ["touchmove"], | ||
tapevent: ["tap"], | ||
} | ||
) { | ||
super(el); | ||
@@ -226,6 +237,8 @@ this.el = el; | ||
// Set settings by device type (if device is touch capable) | ||
settings.startevent = settings.touchCapable ? ['touchstart'] : ['mousedown']; | ||
settings.endevent = settings.touchCapable ? ['touchend'] : ['mouseup']; | ||
settings.moveevent = settings.touchCapable ? ['touchmove'] : ['mousemove']; | ||
settings.tapevent = settings.touchCapable ? ['tap'] : ['click']; | ||
settings.startevent = settings.touchCapable | ||
? ["touchstart"] | ||
: ["mousedown"]; | ||
settings.endevent = settings.touchCapable ? ["touchend"] : ["mouseup"]; | ||
settings.moveevent = settings.touchCapable ? ["touchmove"] : ["mousemove"]; | ||
settings.tapevent = settings.touchCapable ? ["tap"] : ["click"]; | ||
@@ -259,15 +272,32 @@ this.settings = settings; | ||
protected getSwipeDir(startPosition: Position, endPosition: Position, hThreshold: number = this.settings.swipeHThreshold, vThreshold: number = this.settings.swipeVThreshold) { | ||
let swipeDir = ''; | ||
if (startPosition.y > endPosition.y && (startPosition.y - endPosition.y > vThreshold)) { | ||
swipeDir = 'swipeup'; | ||
protected getSwipeDir( | ||
startPosition: Position, | ||
endPosition: Position, | ||
hThreshold: number = this.settings.swipeHThreshold, | ||
vThreshold: number = this.settings.swipeVThreshold | ||
) { | ||
let swipeDir = ""; | ||
if ( | ||
startPosition.y > endPosition.y && | ||
startPosition.y - endPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipeup"; | ||
} | ||
if (startPosition.x < endPosition.x && (endPosition.x - startPosition.x > hThreshold)) { | ||
swipeDir = 'swiperight'; | ||
if ( | ||
startPosition.x < endPosition.x && | ||
endPosition.x - startPosition.x > hThreshold | ||
) { | ||
swipeDir = "swiperight"; | ||
} | ||
if (startPosition.y < endPosition.y && (endPosition.y - startPosition.y > vThreshold)) { | ||
swipeDir = 'swipedown'; | ||
if ( | ||
startPosition.y < endPosition.y && | ||
endPosition.y - startPosition.y > vThreshold | ||
) { | ||
swipeDir = "swipedown"; | ||
} | ||
if (startPosition.x > endPosition.x && (startPosition.x - endPosition.x > hThreshold)) { | ||
swipeDir = 'swipeleft'; | ||
if ( | ||
startPosition.x > endPosition.x && | ||
startPosition.x - endPosition.x > hThreshold | ||
) { | ||
swipeDir = "swipeleft"; | ||
} | ||
@@ -277,3 +307,7 @@ return swipeDir; | ||
protected getPostion(event: TouchEvent | MouseEvent, type: TouchType = TouchType.DEFAULT, index = 0): Position { | ||
protected getPostion( | ||
event: TouchEvent | MouseEvent, | ||
type: TouchType = TouchType.DEFAULT, | ||
index = 0 | ||
): Position { | ||
let touchesTypes: TouchList; | ||
@@ -292,4 +326,8 @@ switch (type) { | ||
const position = { | ||
x: (this.settings.touchCapable) ? touchesTypes[index].pageX : (event as MouseEvent).pageX, | ||
y: (this.settings.touchCapable) ? touchesTypes[index].pageY : (event as MouseEvent).pageY, | ||
x: this.settings.touchCapable | ||
? touchesTypes[index].pageX | ||
: (event as MouseEvent).pageX, | ||
y: this.settings.touchCapable | ||
? touchesTypes[index].pageY | ||
: (event as MouseEvent).pageY, | ||
}; | ||
@@ -299,3 +337,7 @@ return position; | ||
protected getOffset(event: TouchEvent | MouseEvent, type: TouchType = TouchType.DEFAULT, index = 0): Offset { | ||
protected getOffset( | ||
event: TouchEvent | MouseEvent, | ||
type: TouchType = TouchType.DEFAULT, | ||
index = 0 | ||
): Offset { | ||
const boundingClientRect = this.el.getBoundingClientRect(); | ||
@@ -315,4 +357,20 @@ let touchesTypes: TouchList; | ||
const offset = { | ||
x: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageX - (boundingClientRect ? boundingClientRect.left : 0)) : Math.round((event as any as MouseEvent).pageX - (boundingClientRect ? boundingClientRect.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round(touchesTypes[index].pageY - (boundingClientRect ? boundingClientRect.top : 0)) : Math.round((event as any as MouseEvent).pageY - (boundingClientRect ? boundingClientRect.top : 0)), | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageX - | ||
(boundingClientRect ? boundingClientRect.left : 0) | ||
) | ||
: Math.round( | ||
((event as any) as MouseEvent).pageX - | ||
(boundingClientRect ? boundingClientRect.left : 0) | ||
), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
touchesTypes[index].pageY - | ||
(boundingClientRect ? boundingClientRect.top : 0) | ||
) | ||
: Math.round( | ||
((event as any) as MouseEvent).pageY - | ||
(boundingClientRect ? boundingClientRect.top : 0) | ||
), | ||
}; | ||
@@ -322,3 +380,8 @@ return offset; | ||
protected getTouchData(event: TouchEvent | MouseEvent, withIndex = false, positionType = TouchType.DEFAULT, offsetType = TouchType.CHANGED): TouchData { | ||
protected getTouchData( | ||
event: TouchEvent | MouseEvent, | ||
withIndex = false, | ||
positionType = TouchType.DEFAULT, | ||
offsetType = TouchType.CHANGED | ||
): TouchData { | ||
const touchData: TouchData = { | ||
@@ -330,3 +393,5 @@ position: this.getPostion(event, positionType), | ||
if (withIndex) { | ||
touchData.index = ExtraUtils.getElementIndex(event.target as Element | null); | ||
touchData.index = ExtraUtils.getElementIndex( | ||
event.target as Element | null | ||
); | ||
} | ||
@@ -338,9 +403,15 @@ return touchData; | ||
for (const eventName of this.settings.startevent) { | ||
this.el.addEventListener<any>(eventName, this.onStartEvent.bind(this), {passive: true}); | ||
this.el.addEventListener<any>(eventName, this.onStartEvent.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
for (const eventName of this.settings.moveevent) { | ||
this.el.addEventListener<any>(eventName, this.onMoveEvent.bind(this), {passive: true}); | ||
this.el.addEventListener<any>(eventName, this.onMoveEvent.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
for (const eventName of this.settings.endevent) { | ||
this.el.addEventListener<any>(eventName, this.onEndEvent.bind(this), {passive: true}); | ||
this.el.addEventListener<any>(eventName, this.onEndEvent.bind(this), { | ||
passive: true, | ||
}); | ||
} | ||
@@ -365,3 +436,8 @@ } | ||
if (!this.firstTap) { | ||
this.firstTap = this.getTouchData(event, true, TouchType.DEFAULT, TouchType.CHANGED); | ||
this.firstTap = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
} | ||
@@ -376,3 +452,8 @@ | ||
this.finalCoord = this.getPostion(event, TouchType.TARGET); | ||
this.startEvnt = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
this.startEvnt = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
@@ -414,3 +495,7 @@ this.tapstart(event); | ||
protected tapstart(event: TouchEvent | MouseEvent) { | ||
this.triggerCustomEvent('tapstart', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
this.triggerCustomEvent( | ||
"tapstart", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
@@ -421,3 +506,7 @@ } | ||
protected tapmove(event: TouchEvent | MouseEvent) { | ||
this.triggerCustomEvent('tapmove', event, this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED)); | ||
this.triggerCustomEvent( | ||
"tapmove", | ||
event, | ||
this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED) | ||
); | ||
return true; | ||
@@ -428,3 +517,7 @@ } | ||
protected tapend(event: TouchEvent | MouseEvent) { | ||
this.triggerCustomEvent('tapend', event, this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED)); | ||
this.triggerCustomEvent( | ||
"tapend", | ||
event, | ||
this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED) | ||
); | ||
return true; | ||
@@ -443,17 +536,8 @@ } | ||
if ( | ||
( | ||
this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y | ||
) | ||
|| | ||
( | ||
diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange | ||
) | ||
(this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange) | ||
) { | ||
@@ -463,3 +547,5 @@ this.tapheld = true; | ||
const duration = endTime - this.startTime; | ||
const touchesLength: number = ((event as TouchEvent).targetTouches) ? (event as TouchEvent).targetTouches.length : 1; | ||
const touchesLength: number = (event as TouchEvent).targetTouches | ||
? (event as TouchEvent).targetTouches.length | ||
: 1; | ||
const touches = new Array<Partial<TouchData>>(); | ||
@@ -471,8 +557,26 @@ | ||
position: { | ||
x: (this.settings.touchCapable) ? (event as TouchEvent).changedTouches[i].pageX : (event as MouseEvent).pageX, | ||
y: (this.settings.touchCapable) ? (event as TouchEvent).changedTouches[i].pageY : (event as MouseEvent).pageY, | ||
x: this.settings.touchCapable | ||
? (event as TouchEvent).changedTouches[i].pageX | ||
: (event as MouseEvent).pageX, | ||
y: this.settings.touchCapable | ||
? (event as TouchEvent).changedTouches[i].pageY | ||
: (event as MouseEvent).pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round((event as TouchEvent).changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round((event as MouseEvent).pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round((event as TouchEvent).changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round((event as MouseEvent).pageY - (elOffset ? elOffset.top : 0)), | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
(event as TouchEvent).changedTouches[i].pageX - | ||
(elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round( | ||
(event as MouseEvent).pageX - (elOffset ? elOffset.left : 0) | ||
), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
(event as TouchEvent).changedTouches[i].pageY - | ||
(elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round( | ||
(event as MouseEvent).pageY - (elOffset ? elOffset.top : 0) | ||
), | ||
}, | ||
@@ -483,3 +587,4 @@ }; | ||
} | ||
const eventName = (touchesLength > 1) ? 'taphold' + touchesLength : 'taphold'; | ||
const eventName = | ||
touchesLength > 1 ? "taphold" + touchesLength : "taphold"; | ||
@@ -494,3 +599,2 @@ const touchData = { | ||
} | ||
}, this.settings.tapholdThreshold); | ||
@@ -511,15 +615,16 @@ | ||
if ( | ||
delta < this.settings.doubletapInterval | ||
&& | ||
delta > 100 | ||
&& | ||
( | ||
this.firstTap | ||
&& | ||
ExtraUtils.getElementIndex(event.target as Element | null) === this.firstTap.index | ||
) | ||
delta < this.settings.doubletapInterval && | ||
delta > 100 && | ||
this.firstTap && | ||
ExtraUtils.getElementIndex(event.target as Element | null) === | ||
this.firstTap.index | ||
) { | ||
this.doubletapped = true; | ||
window.clearTimeout(this.tapTimer); | ||
const lastTap: TouchData = this.getTouchData(event, true, TouchType.CHANGED, TouchType.CHANGED); | ||
const lastTap: TouchData = this.getTouchData( | ||
event, | ||
true, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
const touchData = { | ||
@@ -531,3 +636,3 @@ firstTap: this.firstTap, | ||
if (!this.cooling) { | ||
this.triggerCustomEvent('doubletap', event, touchData); | ||
this.triggerCustomEvent("doubletap", event, touchData); | ||
this.firstTap = null; | ||
@@ -540,6 +645,10 @@ } | ||
} else { | ||
this.actionTimer = window.setTimeout(() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, this.settings.doubletapInterval, [event]); | ||
this.actionTimer = window.setTimeout( | ||
() => { | ||
this.firstTap = null; | ||
window.clearTimeout(this.actionTimer); | ||
}, | ||
this.settings.doubletapInterval, | ||
[event] | ||
); | ||
} | ||
@@ -560,33 +669,21 @@ this.lastTouch = now; | ||
if ( | ||
!this.doubletapped | ||
&& | ||
!this.tapheld | ||
&& | ||
( | ||
( | ||
( | ||
this.startPosition.x === this.endPosition.x | ||
) | ||
&& | ||
( | ||
this.startPosition.y === this.endPosition.y | ||
) | ||
) | ||
|| | ||
( | ||
diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange | ||
) | ||
) | ||
!this.doubletapped && | ||
!this.tapheld && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchData: TouchData = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
const touchData: TouchData = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
// Was it a taphold? | ||
if ((touchData.time - this.startTime) < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent('singletap', event, touchData); | ||
if (touchData.time - this.startTime < this.settings.tapholdThreshold) { | ||
this.triggerCustomEvent("singletap", event, touchData); | ||
} | ||
@@ -605,27 +702,14 @@ } | ||
if ( | ||
this.tapStarted | ||
&& | ||
( | ||
(Date.now() - this.startTime) < this.settings.tapholdThreshold | ||
) | ||
&& | ||
( | ||
( | ||
this.startPosition.x === this.endPosition.x | ||
&& | ||
this.startPosition.y === this.endPosition.y | ||
) | ||
|| | ||
( | ||
diffPosition.x >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.x <= this.settings.tapPixelRange | ||
&& | ||
diffPosition.y >= -this.settings.tapPixelRange | ||
&& | ||
diffPosition.y <= this.settings.tapPixelRange | ||
) | ||
) | ||
this.tapStarted && | ||
Date.now() - this.startTime < this.settings.tapholdThreshold && | ||
((this.startPosition.x === this.endPosition.x && | ||
this.startPosition.y === this.endPosition.y) || | ||
(diffPosition.x >= -this.settings.tapPixelRange && | ||
diffPosition.x <= this.settings.tapPixelRange && | ||
diffPosition.y >= -this.settings.tapPixelRange && | ||
diffPosition.y <= this.settings.tapPixelRange)) | ||
) { | ||
const touchesLength: number = ((event as TouchEvent).targetTouches) ? (event as TouchEvent).targetTouches.length : 1; | ||
const touchesLength: number = (event as TouchEvent).targetTouches | ||
? (event as TouchEvent).targetTouches.length | ||
: 1; | ||
const touches = new Array<Partial<TouchData>>(); | ||
@@ -637,8 +721,26 @@ | ||
position: { | ||
x: (this.settings.touchCapable) ? (event as TouchEvent).changedTouches[i].pageX : (event as MouseEvent).pageX, | ||
y: (this.settings.touchCapable) ? (event as TouchEvent).changedTouches[i].pageY : (event as MouseEvent).pageY, | ||
x: this.settings.touchCapable | ||
? (event as TouchEvent).changedTouches[i].pageX | ||
: (event as MouseEvent).pageX, | ||
y: this.settings.touchCapable | ||
? (event as TouchEvent).changedTouches[i].pageY | ||
: (event as MouseEvent).pageY, | ||
}, | ||
offset: { | ||
x: (this.settings.touchCapable) ? Math.round((event as TouchEvent).changedTouches[i].pageX - (elOffset ? elOffset.left : 0)) : Math.round((event as MouseEvent).pageX - (elOffset ? elOffset.left : 0)), | ||
y: (this.settings.touchCapable) ? Math.round((event as TouchEvent).changedTouches[i].pageY - (elOffset ? elOffset.top : 0)) : Math.round((event as MouseEvent).pageY - (elOffset ? elOffset.top : 0)), | ||
x: this.settings.touchCapable | ||
? Math.round( | ||
(event as TouchEvent).changedTouches[i].pageX - | ||
(elOffset ? elOffset.left : 0) | ||
) | ||
: Math.round( | ||
(event as MouseEvent).pageX - (elOffset ? elOffset.left : 0) | ||
), | ||
y: this.settings.touchCapable | ||
? Math.round( | ||
(event as TouchEvent).changedTouches[i].pageY - | ||
(elOffset ? elOffset.top : 0) | ||
) | ||
: Math.round( | ||
(event as MouseEvent).pageY - (elOffset ? elOffset.top : 0) | ||
), | ||
}, | ||
@@ -655,3 +757,3 @@ }; | ||
const eventName = (touchesLength > 1) ? 'tap' + touchesLength : 'tap'; | ||
const eventName = touchesLength > 1 ? "tap" + touchesLength : "tap"; | ||
this.triggerCustomEvent(eventName, event, touchData); | ||
@@ -677,3 +779,8 @@ } | ||
const endEvnt: TouchData = this.getTouchData(event, false, TouchType.DEFAULT, TouchType.CHANGED); | ||
const endEvnt: TouchData = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.DEFAULT, | ||
TouchType.CHANGED | ||
); | ||
@@ -687,3 +794,3 @@ // Calculate the swipe amount (normalized): | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
@@ -694,3 +801,3 @@ yAmount, | ||
this.hasSwiped = true; | ||
this.triggerCustomEvent('swipe', event, touchData); | ||
this.triggerCustomEvent("swipe", event, touchData); | ||
this.triggerCustomEvent(swipeDir, event, touchData); | ||
@@ -705,5 +812,13 @@ } | ||
protected swipeend(event: TouchEvent | MouseEvent) { | ||
const endEvnt: TouchData = this.getTouchData(event, false, TouchType.CHANGED, TouchType.CHANGED); | ||
const endEvnt: TouchData = this.getTouchData( | ||
event, | ||
false, | ||
TouchType.CHANGED, | ||
TouchType.CHANGED | ||
); | ||
if (this.hasSwiped && this.startEvnt) { | ||
const swipeDir = this.getSwipeDir(this.startEvnt.position, endEvnt.position); | ||
const swipeDir = this.getSwipeDir( | ||
this.startEvnt.position, | ||
endEvnt.position | ||
); | ||
@@ -717,3 +832,3 @@ // Calculate the swipe amount (normalized): | ||
endEvnt, | ||
direction: swipeDir.replace('swipe', ''), | ||
direction: swipeDir.replace("swipe", ""), | ||
xAmount, | ||
@@ -723,7 +838,5 @@ yAmount, | ||
}; | ||
this.triggerCustomEvent('swipeend', event, touchData); | ||
this.triggerCustomEvent("swipeend", event, touchData); | ||
} | ||
} | ||
} |
@@ -1,5 +0,4 @@ | ||
import { ScrollPosition } from '../types/scroll-position'; | ||
import { ScrollPosition } from "../types/scroll-position"; | ||
export class Utils { | ||
// easings methods, see https://pawelgrzybek.com/page-scroll-in-vanilla-javascript/ | ||
@@ -23,3 +22,3 @@ | ||
public static easeOutCubic(t: number) { | ||
return (--t) * t * t + 1; | ||
return --t * t * t + 1; | ||
} | ||
@@ -33,6 +32,6 @@ public static easeInOutCubic(t: number) { | ||
public static easeOutQuart(t: number) { | ||
return 1 - (--t) * t * t * t; | ||
return 1 - --t * t * t * t; | ||
} | ||
public static easeInOutQuart(t: number) { | ||
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t; | ||
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; | ||
} | ||
@@ -43,6 +42,6 @@ public static easeInQuint(t: number) { | ||
public static easeOutQuint(t: number) { | ||
return 1 + (--t) * t * t * t * t; | ||
return 1 + --t * t * t * t * t; | ||
} | ||
public static easeInOutQuint(t: number) { | ||
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; | ||
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t; | ||
} | ||
@@ -49,0 +48,0 @@ |
@@ -1,2 +0,2 @@ | ||
export * from './position'; | ||
export * from './scroll-position'; | ||
export * from "./position"; | ||
export * from "./scroll-position"; |
@@ -1,2 +0,2 @@ | ||
import { Position } from './position'; | ||
import { Position } from "./position"; | ||
@@ -3,0 +3,0 @@ export interface ScrollPosition extends Position { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
187198
26
80
5634
+ Added@ribajs/core@1.9.0-alpha.1(transitive)
+ Added@ribajs/utils@1.9.0-alpha.1(transitive)
- Removed@ribajs/core@1.9.0-alpha.0(transitive)
- Removed@ribajs/utils@1.9.0-alpha.0(transitive)
Updated@ribajs/core@1.9.0-alpha.1
Updated@ribajs/utils@1.9.0-alpha.1