{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7dac7da5",
   "metadata": {
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [],
   "source": [
    "import diplotocus as dpl\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "def plot(ease,ease_str,lims=(-0.1,1.1)):\n",
    "    x = np.linspace(0,1,200)\n",
    "    y = [ease.ease(el) for el in x]\n",
    "\n",
    "    tl = dpl.Timeline(quiet=True,figsize=(6,5),xlim=lims,ylim=lims,noaxis=True)\n",
    "    ax = tl.main_axis\n",
    "    ax.plot(x,y,alpha=0.5)\n",
    "    ax.text(0.1,0.8,ease_str)\n",
    "    ax.text(0.1,0.3,'Linear',alpha=0.5)\n",
    "    e = dpl.plot(x=0,y=0.75,c='k',marker='o',markersize=10,easing=ease)\n",
    "    l = dpl.plot(x=0,y=0.25,c='k',marker='o',markersize=10,alpha=0.5)\n",
    "    p = dpl.plot(x=x,y=y,c='C0')\n",
    "    e.translate((0,0),(1,0),200)\n",
    "    l.translate((0,0),(1,0),200)\n",
    "    p.draw(200)\n",
    "    tl.animate((e,l,p))\n",
    "    tl.wait(25)\n",
    "    tl.save_video(path='../_static/{}.mp4'.format(ease_str),speed=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2e0a313",
   "metadata": {},
   "source": [
    "# Easing functions\n",
    "\n",
    "By default, all animations are rendered with a linear time progression. If your video has multiple steps, the transition between them will appear abrupt as you end one and start another. This can be fixed by using **easing functions**. Easing functions are mappings between *frame number* and a *time parameter*. For example, you might want to start your animations slowly, and end very fast; in this case you'd want to use a non-linear easing function.\n",
    "\n",
    "There are multiple ways to use an easing function in diplotocus. You can either set an easing for a whole *timeline*, a *plot object*, a *seq.animate() function* or an *animation function*. If multiple easings are set, the priority goes from the more specific to the more general, i.e. the easing is selected in this order :\n",
    "- an easing set on the *animation function*, or if not set :\n",
    "- an easing set on the *seq.animate() function*, or if not set :\n",
    "- an easing set on the *plot object*, or if not set :\n",
    "- an easing set on the *timeline*, or if not set :\n",
    "- no easing (i.e. `dpl.easeLinear()`).\n",
    "\n",
    "Here are all the easing functions implemented in diplotocus:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40f2ec9e",
   "metadata": {},
   "source": [
    "## easeLinear\n",
    "\n",
    "```\n",
    "    f(x) = x\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c89efe3c",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeLinear.mp4?randId=8045\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeLinear(),'easeLinear')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43e52796",
   "metadata": {},
   "source": [
    "## Sine\n",
    "### easeInSine:\n",
    "\n",
    "```\n",
    "    f(x) = 1 - cos((x * π) / 2)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7be552c4",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInSine.mp4?randId=6795\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInSine(),'easeInSine')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4f7c6c1",
   "metadata": {},
   "source": [
    "### easeOutSine():\n",
    "\n",
    "```\n",
    "    f(x) = sin((x * π) / 2)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "33067726",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutSine.mp4?randId=754\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutSine(),'easeOutSine')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "009eb22a",
   "metadata": {},
   "source": [
    "### easeInOutSine():\n",
    "\n",
    "```\n",
    "    f(x) = -(cos(π * x) - 1) / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e6d0238d",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutSine.mp4?randId=5201\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutSine(),'easeInOutSine')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3163255",
   "metadata": {},
   "source": [
    "## Quadratic\n",
    "### easeInQuad():\n",
    "\n",
    "```\n",
    "    f(x) = x^2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9928adac",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInQuad.mp4?randId=8209\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInQuad(),'easeInQuad')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0f77dc5",
   "metadata": {},
   "source": [
    "### easeOutQuad():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - (1 - x) * (1 - x)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7cd9cab3",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutQuad.mp4?randId=1819\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutQuad(),'easeOutQuad')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0659b981",
   "metadata": {},
   "source": [
    "### easeInOutQuad():\n",
    "\n",
    "```\n",
    "    f(x) = x < 0.5 ? 2 * x^2 : 1 - (-2 * x + 2)^2 / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0ddee08c",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutQuad.mp4?randId=2021\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutQuad(),'easeInOutQuad')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "767f078b",
   "metadata": {},
   "source": [
    "## Cubic\n",
    "### easeInCubic():\n",
    "\n",
    "```\n",
    "    f(x) = x^3\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "158f852b",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInCubic.mp4?randId=8338\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInCubic(),'easeInCubic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e04138c3",
   "metadata": {},
   "source": [
    "### easeOutCubic():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - (1 - x)^3\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ef03b09d",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutCubic.mp4?randId=5278\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutCubic(),'easeOutCubic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa55c2c4",
   "metadata": {},
   "source": [
    "### easeInOutCubic():\n",
    "\n",
    "```\n",
    "    f(x) = x < 0.5 ? 4 * x^3 : 1 - (-2 * x + 2)^3 / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "0888eda0",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutCubic.mp4?randId=3295\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutCubic(),'easeInOutCubic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa27642e",
   "metadata": {},
   "source": [
    "## Quartic\n",
    "### easeInQuart():\n",
    "\n",
    "```\n",
    "    f(x) = x^4\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "56660979",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInQuart.mp4?randId=8964\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInQuart(),'easeInQuart')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "081b7b83",
   "metadata": {},
   "source": [
    "### easeOutQuart():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - (1 - x)^4\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d32bc32f",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutQuart.mp4?randId=1936\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutQuart(),'easeOutQuart')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b931d13f",
   "metadata": {},
   "source": [
    "### easeInOutQuart():\n",
    "\n",
    "```\n",
    "    f(x) = x < 0.5 ? 8 * x^4 : 1 - (-2 * x + 2)^4 / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "de170f5c",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutQuart.mp4?randId=9967\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutQuart(),'easeInOutQuart')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8acb4760",
   "metadata": {},
   "source": [
    "## Quintic\n",
    "### easeInQuint():\n",
    "\n",
    "```\n",
    "    f(x) = x^5\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c8f3fca2",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInQuint.mp4?randId=2554\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInQuint(),'easeInQuint')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7148b591",
   "metadata": {},
   "source": [
    "### easeOutQuint():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - (1 - x)^5\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d5bdc9aa",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutQuint.mp4?randId=2306\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutQuint(),'easeOutQuint')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0b4cfad",
   "metadata": {},
   "source": [
    "### easeInOutQuint():\n",
    "\n",
    "```\n",
    "    f(x) = x < 0.5 ? 16 * x^5 : 1 - (-2 * x + 2)^5 / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b4ceafb7",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutQuint.mp4?randId=2051\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutQuint(),'easeInOutQuint')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65603806",
   "metadata": {},
   "source": [
    "## Exponential\n",
    "### easeInExpo():\n",
    "\n",
    "```\n",
    "    f(x) = x === 0 ? 0 : 2^(10 * x - 10)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "4b704b90",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInExpo.mp4?randId=4373\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInExpo(),'easeInExpo')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d70d383",
   "metadata": {},
   "source": [
    "### easeOutExpo():\n",
    "\n",
    "```\n",
    "    f(x) = x === 1 ? 1 : 1 - 2^(-10 * x)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "342b16a7",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutExpo.mp4?randId=1365\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutExpo(),'easeOutExpo')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07d6ffab",
   "metadata": {},
   "source": [
    "### easeInOutExpo():\n",
    "\n",
    "```\n",
    "    f(x) = x === 0\n",
    "        ? 0\n",
    "        : x === 1\n",
    "        ? 1\n",
    "        : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2\n",
    "        : (2 - Math.pow(2, -20 * x + 10)) / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0d07d175",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutExpo.mp4?randId=4434\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutExpo(),'easeInOutExpo')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f7c4712",
   "metadata": {},
   "source": [
    "## Circular\n",
    "### easeInCirc():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - sqrt(1 - x^2)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "1f1776ef",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInCirc.mp4?randId=4820\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInCirc(),'easeInCirc')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5125a1fc",
   "metadata": {},
   "source": [
    "### easeOutCirc():\n",
    "\n",
    "```\n",
    "    f(x) = sqrt(1 - (x - 1)^2)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "dd01f5a1",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutCirc.mp4?randId=5740\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutCirc(),'easeOutCirc')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9afda920",
   "metadata": {},
   "source": [
    "### easeInOutCirc():\n",
    "\n",
    "```\n",
    "    f(x) = x < 0.5\n",
    "        ? (1 - sqrt(1 - (2 * x)^2)) / 2\n",
    "        : (sqrt(1 - (-2 * x + 2)^2) + 1) / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "8bb07213",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutCirc.mp4?randId=5368\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutCirc(),'easeInOutCirc')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ababb15f",
   "metadata": {},
   "source": [
    "## Back\n",
    "### easeInBack():\n",
    "\n",
    "```\n",
    "    c1 = 1.70158\n",
    "    c3 = c1 + 1\n",
    "    \n",
    "    f(x) = c3 * x * x * x - c1 * x * x\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "ba1fe8fd",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInBack.mp4?randId=754\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInBack(),'easeInBack',lims=(-0.15,1.15))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d14a822f",
   "metadata": {},
   "source": [
    "### easeOutBack():\n",
    "\n",
    "```\n",
    "    c1 = 1.70158\n",
    "    c3 = c1 + 1\n",
    "    \n",
    "    f(x) = 1 + c3 * (x - 1)^3 + c1 * (x - 1)^2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "5afa85f8",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutBack.mp4?randId=2312\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutBack(),'easeOutBack',lims=(-0.15,1.15))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cd16b5b",
   "metadata": {},
   "source": [
    "### easeInOutBack():\n",
    "\n",
    "```\n",
    "    c1 = 1.70158\n",
    "    c2 = c1 * 1.525\n",
    "    \n",
    "    f(x) = x < 0.5\n",
    "        ? ((2 * x)^2 * ((c2 + 1) * 2 * x - c2)) / 2\n",
    "        : ((2 * x - 2)^2 * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "828555e7",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutBack.mp4?randId=1120\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutBack(),'easeInOutBack',lims=(-0.15,1.15))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05f9cef4",
   "metadata": {},
   "source": [
    "## Elastic\n",
    "### easeInElastic():\n",
    "\n",
    "```\n",
    "    c4 = (2 * π) / 3\n",
    "\n",
    "    f(x) = x === 0\n",
    "        ? 0\n",
    "        : x === 1\n",
    "        ? 1\n",
    "        : -2^(10 * x - 10) * sin((x * 10 - 10.75) * c4)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "d74ea318",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInElastic.mp4?randId=9788\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInElastic(),'easeInElastic',lims=(-0.4,1.1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3ea107f",
   "metadata": {},
   "source": [
    "### easeOutElastic():\n",
    "\n",
    "```\n",
    "    c4 = (2 * π) / 3\n",
    "\n",
    "    f(x) = x === 0\n",
    "        ? 0\n",
    "        : x === 1\n",
    "        ? 1\n",
    "        : 2^(-10 * x) * sin((x * 10 - 0.75) * c4) + 1\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "cb30cdb2",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutElastic.mp4?randId=8762\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutElastic(),'easeOutElastic',lims=(-0.1,1.4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "823c568d",
   "metadata": {},
   "source": [
    "### easeInOutElastic():\n",
    "\n",
    "```\n",
    "    c4 = c5 = (2 * π) / 4.5\n",
    "\n",
    "    f(x) = x === 0\n",
    "        ? 0\n",
    "        : x === 1\n",
    "        ? 1\n",
    "        : x < 0.5\n",
    "        ? -(2^(20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2\n",
    "        : (2^(-20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "085400ca",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutElastic.mp4?randId=3307\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutElastic(),'easeInOutElastic',lims=(-0.4,1.4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08597675",
   "metadata": {},
   "source": [
    "## Bounce\n",
    "### easeInBounce():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - f_easeOutBounce(1 - x)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "820dc152",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInBounce.mp4?randId=7882\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInBounce(),'easeInBounce')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa76aa08",
   "metadata": {},
   "source": [
    "### easeOutBounce():\n",
    "\n",
    "```\n",
    "    n1 = 7.5625\n",
    "    d1 = 2.75\n",
    "\n",
    "    if (x < 1 / d1) {\n",
    "        f(x) = n1 * x * x\n",
    "    } else if (x < 2 / d1) {\n",
    "        f(x) = n1 * (x -= 1.5 / d1) * x + 0.75\n",
    "    } else if (x < 2.5 / d1) {\n",
    "        f(x) = n1 * (x -= 2.25 / d1) * x + 0.9375\n",
    "    } else {\n",
    "        f(x) = n1 * (x -= 2.625 / d1) * x + 0.984375\n",
    "    }\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "9a7a5874",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeOutBounce.mp4?randId=9002\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeOutBounce(),'easeOutBounce')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "116166ee",
   "metadata": {},
   "source": [
    "### easeInOutBounce():\n",
    "\n",
    "```\n",
    "    f(x) = 1 - f_easeOutBounce(1 - x)\n",
    "    f(x) = x < 0.5\n",
    "        ? (1 - f_easeOutBounce(1 - 2 * x)) / 2\n",
    "        : (1 + f_easeOutBounce(2 * x - 1)) / 2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "7531eee4",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/easeInOutBounce.mp4?randId=3579\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(dpl.easings.easeInOutBounce(),'easeInOutBounce')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d390ac6a",
   "metadata": {},
   "source": [
    "## easeCubicBezier(x1,y1,x2,y2)\n",
    "\n",
    "This function lets you define a custom easing function, as a [cubic Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves). The implementation is similar to the CSS one, i.e. it is inverting the x(t)=t relation to find a y(t) solution, given the positions of the control points P1=(x1,y1) and P2=(x2,y2).\n",
    "\n",
    "```{note}\n",
    "You can use [cubic-bezier.com](https://cubic-bezier.com) to find the right easing for you.\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fbe493c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/cubicBezier.mp4?randId=4646\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ease = dpl.easings.easeCubicBezier(.43,-0.5,.56,1.5)\n",
    "\n",
    "x = np.linspace(0,1,200)\n",
    "y = [ease.ease(el) for el in x]\n",
    "\n",
    "ease_str = 'Cubic Bézier'\n",
    "\n",
    "lims = (-0.1,1.1)\n",
    "\n",
    "tl = dpl.Timeline(quiet=True,figsize=(6,5),xlim=lims,ylim=lims,noaxis=True)\n",
    "ax = tl.main_axis\n",
    "ax.plot(x,y,alpha=0.5)\n",
    "ax.text(0.1,0.8,ease_str)\n",
    "ax.text(0.1,0.3,'Linear',alpha=0.5)\n",
    "e = dpl.plot(x=0,y=0.75,c='k',marker='o',markersize=10,easing=ease)\n",
    "l = dpl.plot(x=0,y=0.25,c='k',marker='o',markersize=10,alpha=0.5)\n",
    "p = dpl.plot(x=x,y=y,c='C0')\n",
    "e.translate((0,0),(1,0),200)\n",
    "l.translate((0,0),(1,0),200)\n",
    "p.draw(200)\n",
    "tl.animate((e,l,p))\n",
    "tl.wait(25)\n",
    "tl.save_video(path='../_static/cubicBezier.mp4',speed=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff16f5c6",
   "metadata": {},
   "source": [
    "## custom easing function\n",
    "For more complicated easing functions than cubic Bézier curves, you can define your own by creating a child class of the `diplotocus.easings.Easing` class. All you have to do is define its `ease(self,x)` method so it returns a time parameter for a given linear time `x`. Here's an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "f2f08f89",
   "metadata": {},
   "outputs": [],
   "source": [
    "class myEase(dpl.easings.Easing):\n",
    "    def ease(self,x):\n",
    "        if x < 0.75:\n",
    "            return np.abs(np.sin(x*4/.75*np.pi))/(x*5+1)\n",
    "        else:\n",
    "            return ((x-.75)/.25)**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fa09b39",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
       "            <source src=\"../_static/customEase.mp4?randId=5319\" type=\"video/mp4\">\n",
       "            </video>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ease = myEase()\n",
    "\n",
    "x = np.linspace(0,1,200)\n",
    "y = [ease.ease(el) for el in x]\n",
    "\n",
    "ease_str = 'My ease'\n",
    "\n",
    "lims = (-0.1,1.1)\n",
    "\n",
    "tl = dpl.Timeline(quiet=True,figsize=(6,5),xlim=lims,ylim=lims,noaxis=True)\n",
    "ax = tl.main_axis\n",
    "ax.plot(x,y,alpha=0.5)\n",
    "ax.text(0.1,0.8,ease_str)\n",
    "ax.text(0.1,0.3,'Linear',alpha=0.5)\n",
    "e = dpl.plot(x=0,y=0.75,c='k',marker='o',markersize=10,easing=ease)\n",
    "l = dpl.plot(x=0,y=0.25,c='k',marker='o',markersize=10,alpha=0.5)\n",
    "p = dpl.plot(x=x,y=y,c='C0')\n",
    "e.translate((0,0),(1,0),200)\n",
    "l.translate((0,0),(1,0),200)\n",
    "p.draw(200)\n",
    "tl.animate((e,l,p))\n",
    "tl.wait(25)\n",
    "tl.save_video(path='../_static/customEase.mp4',speed=4)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
