// Touch adapter for h5/js/swipe-track.js. Pixel offsets stay local to the page; // vertical scroll and taps are preserved, including a tap immediately after a drag. function finite(value) { return typeof value === 'number' && isFinite(value); } function point(event, ending) { var touches = event && (ending ? event.changedTouches : event.touches || event.changedTouches); if (!touches || touches.length !== 1) return null; var touch = touches[0], x = touch.clientX != null ? touch.clientX : touch.pageX; var y = touch.clientY != null ? touch.clientY : touch.pageY; return finite(x) && finite(y) ? { x: x, y: y, id: touch.identifier } : null; } function time(event) { return event && finite(event.timeStamp) ? event.timeStamp : Date.now(); } function start(event, index, width, count, options) { var p = point(event); if (!p || !finite(width) || width <= 0 || !finite(index) || !finite(count) || count < 1) return null; return { id: p.id, index: index, width: width, count: count, options: options || {}, x: p.x, y: p.y, lastX: p.x, lastAt: time(event), velocity: 0, horizontal: false, vertical: false }; } function move(state, event) { var p = point(event); if (!state || !p || p.id !== state.id) return null; var dx = p.x - state.x, dy = p.y - state.y, options = state.options; if (!state.horizontal && !state.vertical && Math.max(Math.abs(dx), Math.abs(dy)) > (options.startThreshold || 8)) { if (Math.abs(dy) * (options.directionRatio || 1) >= Math.abs(dx)) state.vertical = true; else state.horizontal = true; } if (!state.horizontal || state.vertical) return { offset: 0, dragging: false }; var elapsed = time(event) - state.lastAt; if (elapsed > 0) state.velocity = (p.x - state.lastX) / elapsed; state.lastX = p.x; state.lastAt = time(event); var offset = -state.index * state.width + dx, min = -(state.count - 1) * state.width; var limit = options.maxOverscroll == null ? Infinity : options.maxOverscroll; if (offset > 0) offset = Math.min(limit, offset * .25); else if (offset < min) offset = min - Math.min(limit, (min - offset) * .25); return { offset: offset + state.index * state.width, dragging: true }; } function end(state, event, canceled) { if (!state) return null; var p = point(event, true), next = state.index; if (!canceled && p && p.id === state.id && state.horizontal && !state.vertical) { var dx = p.x - state.x, speed = time(event) - state.lastAt > 100 ? 0 : state.velocity; if (Math.abs(dx) >= Math.min(50, state.width * .2) || (Math.abs(dx) > 12 && Math.abs(speed) > .4)) { next = Math.round(state.index - dx / state.width); if (next === state.index) next += (Math.abs(speed) > .4 ? speed : dx) < 0 ? 1 : -1; } } return { index: Math.max(0, Math.min(state.count - 1, next)), dragged: state.horizontal }; } module.exports = { start: start, move: move, end: end };