@use "sass:math";

/**
 * Easings
 *
 *      converted from source: https://github.com/ai/easings.net/blob/master/src/easings/easingsFunctions.ts
 *      each ease receive a value $x in a range of 0 to 1
 *
 *      examples :
 *
 *      @for (dollar)i from 0 through 10 {
 *          .test {
 *              transition-delay: #{ease-out-cubic((dollar)i / 10)}s;
 *          }
 *      }
 *
 *      ease-in-quad
 *      ease-out-quad
 *      ease-in-out-quad
 *
 *      ease-in-cubic
 *      ease-out-cubic
 *      ease-in-out-cubic
 *
 *      ease-in-quart
 *      ease-out-quart
 *      ease-in-out-quart
 *
 *      ease-in-quint
 *      ease-out-quint
 *      ease-in-out-quint
 *
 *      ease-in-sine
 *      ease-out-sine
 *      ease-in-out-sine
 *
 *      ease-in-expo
 *      ease-out-expo
 *      ease-in-out-expo
 *
 *      ease-in-circ
 *      ease-out-circ
 *      ease-in-out-circ
 *
 *      ease-in-back
 *      ease-out-back
 *      ease-in-out-back
 *
 *      ease-in-elastic
 *      ease-out-elastic
 *      ease-in-out-elastic
 *
 *      ease-in-bounce
 *      ease-out-bounce
 *      ease-in-out-bounce
 *
 */
$easings-const-c1: 1.70158;
$easings-const-c2: $easings-const-c1 * 1.525;
$easings-const-c3: $easings-const-c1 + 1;
$easings-const-c4: math.div(2 * math.$pi, 3);
$easings-const-c5: math.div(2 * math.$pi, 4.5);

// ==========
// Quad
// ==========

@function ease-in-quad($x) {
    @return $x * $x;
}

@function ease-out-quad($x) {
    @return 1 - (1 - $x) * (1 - $x);
}

@function ease-in-out-quad($x) {
    @if ($x < .5) {
        @return 2 * $x * $x;
    } @else {
        @return 1 - math.pow(-2 * $x + 2, 2) / 2;
    }
}

// ==========
// Cubic
// ==========

@function ease-in-cubic($x) {
    @return $x * $x * $x;
}

@function ease-out-cubic($x) {
    @return 1 - math.pow(1 - $x, 3);
}

@function ease-in-out-cubic($x) {
    @if ($x < .5) {
        @return 4 * $x * $x * $x;
    } @else {
        @return 1 - math.pow(-2 * $x + 2, 2) / 2;
    }
}

// ==========
// Quart
// ==========

@function ease-in-quart($x) {
    @return $x * $x * $x * $x;
}

@function ease-out-quart($x) {
    @return 1 - math.pow(1 - $x, 4);
}

@function ease-in-out-quart($x) {
    @if ($x < .5) {
        @return 8 * $x * $x * $x * $x;
    } @else {
        @return 1 - math.pow(-2 * $x + 2, 4) / 2;
    }
}

// ==========
// Quint
// ==========

@function ease-in-quint($x) {
    @return $x * $x * $x * $x * $x;
}

@function ease-out-quint($x) {
    @return 1 - math.pow(1 - $x, 5);
}

@function ease-in-out-quint($x) {
    @if ($x < .5) {
        @return 16 * $x * $x * $x * $x * $x;
    } @else {
        @return 1 - math.div(math.pow(-2 * $x + 2, 5), 2);
    }
}

// ==========
// Sin
// ==========

@function ease-in-sine($x) {
    @return 1 - math.cos(math.div($x * math.$pi), 2);
}

@function ease-out-sine($x) {
    @return math.sin(math.div($x * math.$pi), 2);
}

@function ease-in-out-sine($x) {
    @return -math.div((math.cos(math.$pi * $x) - 1), 2);
}

// ==========
// Expo
// ==========

@function ease-in-expo($x) {
    @if ($x == 0) {
        @return 0;
    } @else {
        @return math.pow(2, 10 * $x - 10);
    }
}

@function ease-out-expo($x) {
    @if ($x == 1) {
        @return 1;
    } @else {
        @return 1 - math.pow(2, -10 * $x);
    }
}

@function ease-in-out-expo($x) {
    @if ($x == 0) {
        @return 0;
    } @else if ($x == 1) {
        @return 1;
    } @else if ($x < .5) {
        @return math.pow(2, 20 * $x - 10) / 2;
    } @else {
        @return (2 - math.pow(2, -20 * $x + 10)) / 2;
    }
}

// ==========
// Circ
// ==========

@function ease-in-circ($x) {
    @return 1 - math.sqrt(1 - math.pow($x, 2));
}

@function ease-out-circ($x) {
    @return math.sqrt(1 - math.pow($x - 1, 2));
}

@function ease-in-out-circ($x) {
    @if ($x < .5) {
        @return (1 - math.sqrt(1 - math.pow(2 * $x, 2))) / 2;
    } @else {
        @return (math.sqrt(1 - math.pow(-2 * $x + 2, 2)) + 1) / 2;
    }
}

// ==========
// Back
// ==========

@function ease-in-back($x) {
    @return $easings-const-c3 * $x * $x * $x - $easings-const-c1 * $x * $x;
}

@function ease-out-back($x) {
    @return 1 + $easings-const-c3 * math.pow($x - 1, 3) + $easings-const-c1 * math.pow($x - 1, 2);
}

@function ease-in-out-back($x) {
    @if ($x < .5) {
        @return (math.pow(2 * $x, 2) * (($easings-const-c2 + 1) * 2 * $x - $easings-const-c2)) / 2;
    } @else {
        @return (math.pow(2 * $x - 2, 2) * (($easings-const-c2 + 1) * ($x * 2 - 2) + $easings-const-c2) + 2) / 2;
    }
}

// ==========
// Elastic
// ==========

@function ease-in-elastic($x) {
    @if ($x == 0) {
        @return 0;
    } @else if ($x == 1) {
        @return 1;
    } @else if ($x < .5) {
        @return -(math.pow(2, 10 * $x - 10)) * sin(($x * 10 - 10.75) * $easings-const-c4);
    }
}

@function ease-out-elastic($x) {
    @if ($x == 0) {
        @return 0;
    } @else if ($x == 1) {
        @return 1;
    } @else if ($x < .5) {
        @return math.pow(2, -10 * $x) * math.sin(($x * 10 - .75) * $easings-const-c4) + 1;
    }
}

@function ease-in-out-elastic($x) {
    @if ($x == 0) {
        @return 0;
    } @else if ($x == 1) {
        @return 1;
    } @else if ($x < .5) {
        @return -(math.pow(2, 20 * $x - 10) * math.sin((20 * $x - 11.125) * $easings-const-c5)) / 2;
    } @else {
        @return (math.pow(2, -20 * $x + 10) * math.sin((20 * $x - 11.125) * $easings-const-c5)) / 2 + 1;
    }
}

// ==========
// Bounce
// ==========

@function ease-in-bounce($x) {
    @return 1 - ease-out-bounce(1 - $x);
}

@function ease-out-bounce($x) {
    $n1: 7.5625;
    $d1: 2.75;

    @if ($x < 1 / $d1) {
        @return $n1 * $x * $x;
    } @else if ($x < 2 / $d1) {
        $x: $x - 1.5 / $d1;
        @return $n1 * $x * $x + .75;
    } @else if ($x < 2.5 / $d1) {
        $x: $x - 2.25 / $d1;
        @return $n1 * $x * $x + .9375;
    } @else {
        $x: $x - 2.625 / $d1;
        @return $n1 * $x * $x + .984375;
    }
}

@function ease-in-out-bounce($x) {
    @if ($x < .5) {
        @return (1 - ease-out-bounce(1 - 2 * $x)) / 2;
    } @else {
        @return (1 + ease-out-bounce(2 * $x - 1)) / 2;
    }
}
