"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WheelEvent = void 0;
const tslib_1 = require("tslib");
const event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter"));
const d3_ease_1 = require("@antv/vendor/d3-ease");
const common_1 = require("../../common");
/** 获取执行时间戳 */
const now = () => { var _a; return (_a = performance === null || performance === void 0 ? void 0 : performance.now()) !== null && _a !== void 0 ? _a : Date.now(); };
/** 动画总时间 */
const TOTAL_MS = 800;
/** swipe 手势判断阈值 */
const SWIPE_TIME_GAP = 100;
/**
 * 移动端滚动事件
 * @see https://github.com/antvis/g-gesture/blob/next/src/event/wheel.ts
 */
class WheelEvent extends event_emitter_1.default {
    constructor(canvas) {
        super();
        this.bindPointerDown = (evt) => {
            window.cancelAnimationFrame(this.raf);
            this.panning = true;
            this.preX = evt.x;
            this.preY = evt.y;
            this.speedX = 0;
            this.speedY = 0;
            this.lastMoveMS = now();
        };
        this.bindPointerMove = (evt) => {
            if (this.panning) {
                const ms = now();
                const deltaMS = ms - this.lastMoveMS;
                const deltaX = this.preX - evt.x;
                const deltaY = this.preY - evt.y;
                this.speedX = deltaX / deltaMS;
                this.speedY = deltaY / deltaMS;
                this.preX = evt.x;
                this.preY = evt.y;
                this.lastMoveMS = ms;
                this.emit('wheel', Object.assign(Object.assign({}, evt.clone()), { x: evt.x, y: evt.y, deltaX,
                    deltaY }));
            }
        };
        this.bindPointerUp = (evt) => {
            this.panning = false;
            const pointerUpMS = now();
            if (!this.speedX ||
                !this.speedY ||
                pointerUpMS - this.lastMoveMS >= SWIPE_TIME_GAP) {
                return;
            }
            const moveLoop = () => {
                const loopStartMS = now();
                this.raf = window.requestAnimationFrame(() => {
                    const ms = now();
                    const ratio = (ms - pointerUpMS) / TOTAL_MS;
                    if (ratio < 1) {
                        const currentRatio = (0, d3_ease_1.easeCubicIn)(1 - ratio);
                        const t = ms - loopStartMS;
                        this.emit('wheel', Object.assign(Object.assign({}, evt.clone()), { x: evt.x, y: evt.y, deltaX: this.speedX * currentRatio * t, deltaY: this.speedY * currentRatio * t }));
                        moveLoop();
                    }
                });
            };
            moveLoop();
        };
        this.canvas = canvas;
        this.panning = false;
        this.init();
    }
    init() {
        this.canvas.addEventListener(common_1.OriginEventType.POINTER_DOWN, this.bindPointerDown);
        this.canvas.addEventListener(common_1.OriginEventType.POINTER_MOVE, this.bindPointerMove);
        this.canvas.addEventListener(common_1.OriginEventType.POINTER_UP, this.bindPointerUp);
    }
    destroy() {
        this.canvas.removeEventListener(common_1.OriginEventType.POINTER_DOWN, this.bindPointerDown);
        this.canvas.removeEventListener(common_1.OriginEventType.POINTER_MOVE, this.bindPointerMove);
        this.canvas.removeEventListener(common_1.OriginEventType.POINTER_UP, this.bindPointerUp);
    }
}
exports.WheelEvent = WheelEvent;
//# sourceMappingURL=wheelEvent.js.map