{"id":13493265,"url":"https://github.com/franciscop/ola","last_synced_at":"2025-05-15T08:06:28.347Z","repository":{"id":57314098,"uuid":"186016586","full_name":"franciscop/ola","owner":"franciscop","description":"🌊 Smooth animation library for interpolating numbers","archived":false,"fork":false,"pushed_at":"2021-10-11T03:05:58.000Z","size":6823,"stargazers_count":1808,"open_issues_count":0,"forks_count":32,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-10-29T17:39:56.434Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/franciscop.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":"https://www.paypal.me/franciscopresencia/19"}},"created_at":"2019-05-10T15:59:50.000Z","updated_at":"2024-10-08T17:18:38.000Z","dependencies_parsed_at":"2022-09-20T23:30:54.052Z","dependency_job_id":null,"html_url":"https://github.com/franciscop/ola","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscop%2Fola","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscop%2Fola/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscop%2Fola/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscop%2Fola/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/franciscop","download_url":"https://codeload.github.com/franciscop/ola/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248870278,"owners_count":21175008,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T19:01:13.672Z","updated_at":"2025-04-14T11:25:36.306Z","avatar_url":"https://github.com/franciscop.png","language":"JavaScript","funding_links":["https://www.paypal.me/franciscopresencia/19"],"categories":["Typescript / Javascript","JavaScript","目录"],"sub_categories":[],"readme":"# Ola [![npm install ola](https://img.shields.io/badge/npm%20install-ola-blue.svg)](https://www.npmjs.com/package/ola) [![test badge](https://github.com/franciscop/ola/workflows/tests/badge.svg)](https://github.com/franciscop/ola/blob/master/ola.test.js) [![gzip size](https://img.badgesize.io/franciscop/ola/master/ola.min.js.svg?compression=gzip\u0026label=size)](https://github.com/franciscop/ola/blob/master/ola.min.js)\n\nSmooth animation library for [inbetweening](https://en.wikipedia.org/wiki/Inbetweening) / [interpolating](https://en.wikipedia.org/wiki/Interpolation_(computer_graphics)) numbers in realtime:\n\n\u003ca href=\"https://jsfiddle.net/franciscop/oechmra8/\"\u003e\n  \u003cimg align=\"right\" width=\"375\" src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/line.gif\"\u003e\n\u003c/a\u003e\n\n```js\n// Start tracking the value\nconst pos = Ola({ y: 0 });\n\n// Set the value to update async\npos.set({ y: 100 });\n\n// Read the evolution over time\nsetInterval(() =\u003e graph(pos.y), 5);\n```\n\nIt works with multiple values/dimensions:\n\n\u003ca href=\"https://jsfiddle.net/franciscop/jsfv13no/\"\u003e\n  \u003cimg align=\"right\" width=\"375\" src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/ball.gif\"\u003e\n\u003c/a\u003e\n\n```js\nconst pos = Ola({ x: 0, y: 0 });\n\nwindow.addEventListener('click', e =\u003e {\n  pos.set({ x: e.pageX, y: e.pageY });\n});\n\nsetInterval(() =\u003e {\n  ball.style.left = `${pos.x}px`;\n  ball.style.top = `${pos.y}px`;\n}, 10);\n```\n\nAlso works great with many instances since they are independent:\n\n\u003ca href=\"https://jsfiddle.net/franciscop/7b3wqo91/\"\u003e\n  \u003cimg align=\"right\" width=\"375\" src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/dots.gif\"\u003e\n\u003c/a\u003e\n\n```js\n// Generates 1000 instances seamlessly\nconst dots = Ola(Array(1000).fill(0));\n\n// Everything updates every 600ms\nsetInterval(() =\u003e dots.forEach((dot, i) =\u003e {\n  dots[i] = Math.random();\n}), 600);\n\n// ... read + paint screen here\n```\n\n\u003e Tip: click on the GIFs for a live demo with the code :)\n\n## Getting started\n\nInstall it with npm:\n\n```\nnpm install ola\n```\n\nThen import it and use it:\n\n```js\nimport Ola from \"ola\";\nconst pos = Ola({ x: 0 });\nconsole.log(pos.x); // 0\n```\n\nIf you prefer to use a CDN:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ola\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\"\u003e\n  const pos = Ola({ x: 0 });\n  console.log(pos.x); // 0\n\u003c/script\u003e\n```\n\n## Documentation\n\nThere are three distinct operations that can be run: creating an instance, setting it to update and reading it.\n\n### Create an instance\n\n```js\nOla(initial, time = 300);\n```\n\nThe first parameter is the initial value. It can be either a single number, or an object of `key:numbers` or an array of numbers:\n\n```js\nconst heater = Ola(20); // Alias of `{ value: 20 }`\nconst motor = Ola({ angle: 180 }); // A named parameter for clarity\nconst position = Ola({ x: 0, y: 0 }); // Any number of properties\nconst heights = Ola([0, 0, 0, 0]); // A group of heights\n```\n\nThe second parameter is how long the transition will last. It should be a number that represents the time in milliseconds:\n\n```js\nconst heater = Ola(20); // Default = 300 ms\nconst motor = Ola({ angle: 180 }, 1000); // Turn the motor slowly\nconst position = Ola({ x: 0, y: 0 }, 100); // Quick movements for the position\nconst heights = Ola([0, 0, 0, 0], 300); // 300, same as the default\n```\n\nPassing a single number as a parameter is the same as passing `{ value: num }`, we are just helping by setting a shortname. It is offered for convenience, but recommend not mixing both styles in the same project.\n\nIt works with Javascript numbers, but please keep things reasonable (under `Number.MAX_VALUE / 10`):\n\n```js\nconsole.log(Ola(100));\nconsole.log(Ola(-100));\nconsole.log(Ola(0.001));\nconsole.log(Ola(1 / 100));\n```\n\nThe time it takes to update can also be updated while setting the value, which will update it for any subsequent transition:\n\n```js\n// All `pos.set()` will take 1 full second\nconst pos = Ola({ x: 0 }, 1000);\npos.set({ x: 100 }, 3000);\n```\n\n### Update the value\n\n```js\nheater.value = 25; // Since the constructor used a number, use `.value`\nmotor.angle = 90; // Turn -90 degrees from before\nposition.set({ x: 100, y: 100 }); // Move 0,0 =\u003e 100,100\nheights[1] = 120; // Move the second (0-index) item to 120\n```\n\nWhen we update a property **it is not updated instantaneously** (that's the whole point of this library), but instead it's set to update asynchronously:\n\n```js\nconst pos = Ola({ x: 0 });\npos.set({ x: 100 });\n\n// 0 - still hasn't updated\nconsole.log(pos.x);\n\n// 100 - after 300ms it's fully updated\nsetTimeout(() =\u003e console.log(pos.x), 1000);\n```\n\nRemember that if you set the value as `Ola(10)`, this is really an alias for `Ola({ value: 10 })`, so use the property `.value` to update it:\n\n```js\nheater.value = 25;\nheater.set({ value: 25 });\n```\n\nYou can see in this graph, the blue line is the value that is set though `.set()`, while the red line is the value that reading it returns:\n\n\u003ca href=\"https://jsfiddle.net/franciscop/oechmra8/\"\u003e\n  \u003cimg width=\"375\" height=\"180\" src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/line.gif\"\u003e\n\u003c/a\u003e\n\n### Read the value\n\n```js\nlog(heater.value); // Since the constructor used a number, use `.value`\nlog(motor.angle); // Read as an object property\nlog(position.get(\"x\")); // Find the X value\nlog(heights[1]); // Move the first item to 120\n```\n\nYou can read the value at any time, and the value will be calculated at that moment in time:\n\n```js\nconst pos = Ola({ x: 0 });\npos.set({ x: 100 });\n\nsetInterval(() =\u003e {\n  // It will update every time it's read\n  console.log(pos.x);\n}, 10);\n```\n\nIn contrast to other libraries, there's no need to tick/update the function every N ms or before reading the value, since `Ola()` uses math functions you should just read it when needed.\n\n## Advanced usage\n\nIf you need to access more advanced features, you can read these two properties:\n\n```js\n// All the details about the current transition, please see the source for more info\nlog(heater._value);  // { to: 25, from: 20, ... }\nlog(motor._angle);  // { to: 90, from: 180, ... }\n\n// The value that will be set when the transition is finished\nlog(heater.$value);  // 25\nlog(motor.$angle);  // 90\n```\n\n## Features\n\nWhile there are some other great libraries like Tween, this one has some improvements:\n\n### Smooth in realtime\n\nOther libraries don't move smoothly when there's an update **while the previous transition is still ongoing**. Ola makes sure there are no harsh corners:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003cimg src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/smooth_ola.png\"\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cimg src=\"https://raw.githubusercontent.com/franciscop/ola/master/docs/smooth_tweenmax.png\"\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      Smooth interpolation \u003cstrong\u003ewith Ola()\u003c/strong\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      Harsh interpolation \u003cstrong\u003ewith Tweenmax\u003c/strong\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nStatus of libraries updating animation mid-way:\n\n- **Ola.js** - working smoothly, see screenshot above.\n- **TweenMax** - harsh transition. See screenshot above.\n- **Tween.js** - no transitions at all, feature request made in 2016: https://github.com/tweenjs/tween.js/issues/257\n- [**Open an Issue**](https://github.com/franciscop/ola/issues/new) with other libraries that you know.\n\n### Lazy loading\n\nSince this is driven by mathematical equations, the library doesn't calculate any value until it needs to be read/updated. It will also _only_ change the one we need instead of all of the values:\n\n```js\nconst position = Ola({ x: 0, y: 0 });\nposition.x = 10; // Only updates X\nconsole.log(position.x); // Calculates only X position, not y\n```\n\nNot only this is great for performance, but it also makes for a clean self-contained API where each instance is independent and portable.\n\n## Others from Author\n\nLike this project? Francisco has many more! Check them out:\n\n- **[server.js](https://serverjs.io/)** - a batteries-included Node.js server\n- **[translate.js](https://github.com/franciscop/translate)** - to easily translate text on the browser and Node.js\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscop%2Fola","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffranciscop%2Fola","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscop%2Fola/lists"}