@egjs/flicking
Version:
Everyday 30 million people experience. It's reliable, flexible and extendable carousel.
118 lines (100 loc) • 3.21 kB
text/typescript
/**
* Copyright (c) 2015 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
import State from "./State";
import { STATE_TYPE, EVENTS } from "../consts";
import { FlickingContext } from "../types";
class DraggingState extends State {
public readonly type = STATE_TYPE.DRAGGING;
public readonly holding = true;
public readonly playing = true;
public onChange(e: any, { moveCamera, transitTo }: FlickingContext): void {
if (!e.delta.flick) {
return;
}
moveCamera(e)
.onStopped(() => {
transitTo(STATE_TYPE.DISABLED);
});
}
public onRelease(e: any, context: FlickingContext): void {
const { flicking, viewport, triggerEvent, transitTo, stopCamera } = context;
const delta = this.delta;
const absDelta = Math.abs(delta);
const options = flicking.options;
const horizontal = options.horizontal;
const moveType = viewport.moveType;
const inputEvent = e.inputEvent;
const velocity = horizontal
? inputEvent.velocityX
: inputEvent.velocityY;
const inputDelta = horizontal
? inputEvent.deltaX
: inputEvent.deltaY;
const isNextDirection = Math.abs(velocity) > 1
? velocity < 0
: absDelta > 0
? delta > 0
: inputDelta < 0;
const swipeDistance = viewport.options.bound
? Math.max(absDelta, Math.abs(inputDelta))
: absDelta;
const swipeAngle = inputEvent.deltaX
? Math.abs(180 * Math.atan(inputEvent.deltaY / inputEvent.deltaX) / Math.PI)
: 90;
const belowAngleThreshold = horizontal
? swipeAngle <= options.thresholdAngle
: swipeAngle > options.thresholdAngle;
const overThreshold = swipeDistance >= options.threshold
&& belowAngleThreshold;
const moveTypeContext = {
viewport,
axesEvent: e,
state: this,
swipeDistance,
isNextDirection,
};
// Update last position to cope with Axes's animating behavior
// Axes uses start position when animation start
triggerEvent(EVENTS.HOLD_END, e, true);
const targetPanel = this.targetPanel;
if (!overThreshold && targetPanel) {
// Interrupted while animating
const interruptDestInfo = moveType.findPanelWhenInterrupted(moveTypeContext);
viewport.moveTo(
interruptDestInfo.panel,
interruptDestInfo.destPos,
interruptDestInfo.eventType,
e,
interruptDestInfo.duration,
);
transitTo(STATE_TYPE.ANIMATING);
return;
}
const currentPanel = viewport.getCurrentPanel();
const nearestPanel = viewport.getNearestPanel();
if (!currentPanel || !nearestPanel) {
// There're no panels
e.stop();
transitTo(STATE_TYPE.IDLE);
return;
}
const destInfo = overThreshold
? moveType.findTargetPanel(moveTypeContext)
: moveType.findRestorePanel(moveTypeContext);
viewport.moveTo(
destInfo.panel,
destInfo.destPos,
destInfo.eventType,
e,
destInfo.duration,
).onSuccess(() => {
transitTo(STATE_TYPE.ANIMATING);
}).onStopped(() => {
transitTo(STATE_TYPE.DISABLED);
stopCamera(e);
});
}
}
export default DraggingState;