├── .npmrc ├── .gitignore ├── demo ├── index.html ├── style.css └── src │ └── index.js ├── src └── index.js ├── package.json ├── LICENSE └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .DS_Store 4 | package-lock.json -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Demo 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, 4 | Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 5 | letter-spacing: 0; 6 | font-style: normal; 7 | text-rendering: optimizeLegibility; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | color: rgba(0, 0, 0, 0.8); 11 | font-size: 14px; 12 | margin: 0; 13 | padding: 20px; 14 | } 15 | -------------------------------------------------------------------------------- /demo/src/index.js: -------------------------------------------------------------------------------- 1 | import uot from './../../src/index.js'; 2 | 3 | let count = 0; 4 | document.querySelector('button').addEventListener('click', () => { 5 | document.querySelector('ul').innerHTML += `
  • `; 6 | let savedCount = count; 7 | uot( 8 | progress => { 9 | progress = easeInOutQuad(progress); 10 | document.querySelectorAll('li')[savedCount].textContent = progress.toFixed(2); 11 | if (progress === 1) console.log('complete'); 12 | }, 13 | 5000, 14 | count + 1 15 | ); 16 | count += 1; 17 | }); 18 | 19 | function easeInOutQuad(t) { 20 | return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 21 | } 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const observers = []; 2 | const raf = requestAnimationFrame; 3 | const p = performance; 4 | 5 | function tick() { 6 | let count = observers.length; 7 | let observer; 8 | while (count--) { 9 | observer = observers[count]; 10 | const progress = (p.now() - observer[3]) / observer[1]; 11 | observer[0](progress <= 1 ? progress : 1); 12 | if (progress >= 1) { 13 | (observer[2] -= 1) > 0 || observers.splice(count, 1); 14 | observer[3] = p.now(); 15 | } 16 | } 17 | observers.length < 1 || raf(tick); 18 | } 19 | 20 | function uot(callback, duration, repeat = 1) { 21 | const len = observers.push([callback, duration, repeat, p.now()]); 22 | len > 1 || raf(tick); 23 | return function() { 24 | observers.splice(len - 1, 1); 25 | }; 26 | } 27 | 28 | export default uot; 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uot", 3 | "version": "1.4.0", 4 | "description": "A tiny setTimeout alternative with progress.", 5 | "main": "dist/uot.mjs", 6 | "unpkg": "dist/uot.umd.js", 7 | "scripts": { 8 | "start": "http-server demo --silent & $npm_execpath run watch", 9 | "watch": "microbundle watch --format umd --entry demo/src/index.js --output demo/dist/bundle.js", 10 | "build": "microbundle --name uot --format es,umd --sourcemap false", 11 | "prepare": "$npm_execpath run build" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/vaneenige/uot.git" 16 | }, 17 | "author": { 18 | "name": "Colin van Eenige", 19 | "email": "cvaneenige@gmail.com", 20 | "url": "https://use-the-platform.com" 21 | }, 22 | "files": [ 23 | "src", 24 | "dist" 25 | ], 26 | "keywords": [ 27 | "timeout", 28 | "interval", 29 | "progress" 30 | ], 31 | "license": "MIT", 32 | "devDependencies": { 33 | "microbundle": "^0.9.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Colin van Eenige 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Update Over Time (uot) 2 | 3 | [![npm version](https://img.shields.io/npm/v/uot.svg)](https://www.npmjs.com/package/uot) 4 | [![gzip size](http://img.badgesize.io/https://unpkg.com/uot/dist/uot.mjs?compression=gzip)](https://unpkg.com/uot) 5 | [![license](https://img.shields.io/npm/l/uot.svg)](https://github.com/vaneenige/uot/blob/master/LICENSE) 6 | [![dependencies](https://img.shields.io/badge/dependencies-none-ff69b4.svg)](https://github.com/vaneenige/uot/blob/master/package.json) 7 | 8 | Update Over Time (uot) is a tiny library to provide the easiest way for updating values over time. Provide a callback and a duration you're ready to go! 9 | 10 | This utility can be useful for CSS animations, DOM changes, WebGL transitions or anything that can be updated based on a progress value. 11 | 12 | >It's basically a setTimeout (or setInterval) with progress. 13 | 14 | #### Features: 15 | 16 | - Small in size, no dependencies 17 | - Based on requestAnimationFrame 18 | - Optimized for multiple instances 19 | 20 | ## Install 21 | 22 | ``` 23 | $ npm install --save uot 24 | ``` 25 | 26 | ## Usage 27 | 28 | Import the library: 29 | ```js 30 | import updateOverTime from 'uot'; 31 | ``` 32 | 33 | Provide a callback and a duration: 34 | ```js 35 | updateOverTime((progress) => { 36 | // Progress value: 0 ... 1 37 | if (progress === 1) { 38 | // Handle complete 39 | } 40 | }, 2000); 41 | ``` 42 | 43 | > As a third parameter an optional repeat count can be provided. 44 | 45 | Use the progress value to update the DOM (or anything): 46 | ```js 47 | updateOverTime((progress) => { 48 | // Add easing to the progress value 49 | progress = easeInOutQuad(progress); 50 | // Output the progress value to the DOM 51 | document.body.textContent = progress.toFixed(2); 52 | }, 4000); 53 | ``` 54 | 55 | > At any given time only a single requestAnimationFrame will be called. 56 | 57 | ## License 58 | 59 | MIT © Colin van Eenige 60 | 61 | --------------------------------------------------------------------------------