/**
 * @since Last modified: 2024-01-18 16:17:08
 * @function ease
 * @description Make the hidden element display and gradually expand.
 * @param {object} options  - The parameters of slide down.
 * @param {getEl} [options.elem]  - The target node.The writing is the same as getEl.
 * @param {string} [options.display=block]  - The display of box.Can be filled in:'block'|'flex'|'inline-flex'|'inline-block'|'grid'.
 * @param {curves} [options.curve=easeOut]  - Animation curve.Can be filled in:'linear'|'ease'|'easeIn'|'easeOut'|'easeInOut'|'easeOutIn'.
 * @param {boolean} [options.cut=true]  - Forced overflow truncation,means to add the style attribute of the element:"overflow:hidden".
 * @param {number} [options.duration]  - The duration of slide down.The unit is ms.The default is automatically calculated by the element height.
 * @param {function} [options.doing]  - The call back in progress.Support parameters:"frame" and "step",That is the current animation frame and height.
 * @param {function} [options.done]  - The call back after completion.Support parameters:"frame" and "step",That is the current animation frame and height(orign height).
 * @returns {*} - The the target dom.
 * @see {@link https://codepen.io/axui/pen/YzBgZgE|demo @ codepen}
 * @example
 * ax.ease({elem:'#demo',from:{width:0,height:0},to:{width:100,height:100}});
 * <!--return the target dom-->
 */
'use strict';
import getEl from "./getEl";
import curves from "./curves";
import ax from "../ax";
type Options = { elem: any, from: T_obj, to: T_obj, before?: Function, doing?: Function, done?: Function, curve?: string, duration: number }
let ease = ({ elem, from, to, before, doing, done, duration, curve = 'easeOut' }: Options) => {
    let target = getEl(elem);
    if (!target) {
        throw new Error('The target node does not exist!');
    }
    before && before.call(target);
    let initTime = new Date().getTime(),
        repeat = () => {
            let newTime = new Date().getTime() - initTime,
                ratio = newTime / duration,
                step = curves[curve](ratio),
                frame = requestAnimationFrame(repeat);
            for (let k in from) {
                from[k] += (to[k] - from[k]) * step;
            }
            if (newTime <= duration) {
                doing && doing.call(target, frame, from);
            } else {
                cancelAnimationFrame(frame);
                done && done.call(target, frame, to);
            }
            ax.frame = frame;
        };
    repeat();
    return target;
};
export default ease;
