use-elapsed-time
Advanced tools
Comparing version 2.1.8 to 3.0.0
# Change Log | ||
## 3.0.0 ( June 18th, 2021) | ||
The hooks is now written in TypeScript. | ||
**Breaking Changes:** | ||
- IE is not longer supported | ||
- `autoResetKey` props has been deprecated | ||
- `reset` method of the hook return value no longer accepts `newStartAt`. When it is fired the animation will start over from the initially provided `startAt` value | ||
- `onComplete` return value does not accept `newStartAt` | ||
**New features:** | ||
- `updateInterval` prop now controls how often the hook should rerender. Set as a number in seconds | ||
- `onUpdate` callback will be fired with the current elapsed time when the `elapsedTime` changes. | ||
**Chore:** | ||
- example folder is added, which can we be used for development or testing the hook | ||
## 2.1.8 (May 13th, 2021) | ||
@@ -4,0 +24,0 @@ |
export { useElapsedTime } from './useElapsedTime'; | ||
export type { Props, OnComplete, ReturnValue } from './types'; | ||
export type { Props, OnComplete, ReturnValue } from './useElapsedTime'; |
@@ -1,1 +0,1 @@ | ||
!function(){"use strict";var e={d:function(r,t){for(var n in t)e.o(t,n)&&!e.o(r,n)&&Object.defineProperty(r,n,{enumerable:!0,get:t[n]})},o:function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},r:function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},r={};e.r(r),e.d(r,{useElapsedTime:function(){return o}});var t=require("react");function n(e,r){return function(e){if(Array.isArray(e))return e}(e)||function(e,r){var t=e&&("undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"]);if(null!=t){var n,u,o=[],i=!0,c=!1;try{for(t=t.call(e);!(i=(n=t.next()).done)&&(o.push(n.value),!r||o.length!==r);i=!0);}catch(e){c=!0,u=e}finally{try{i||null==t.return||t.return()}finally{if(c)throw u}}return o}}(e,r)||function(e,r){if(e){if("string"==typeof e)return u(e,r);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?u(e,r):void 0}}(e,r)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=new Array(r);t<r;t++)n[t]=e[t];return n}var o=function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},u=r.duration,o=r.onComplete,c=r.startAt,a=void 0===c?0:c,f=r.autoResetKey,l=(0,t.useState)(a),s=n(l,2),m=s[0],y=s[1],d=(0,t.useRef)(-1e3*a),p=(0,t.useRef)(null),v=(0,t.useRef)(null),b=(0,t.useRef)(null),A=(0,t.useRef)(!1),g=(0,t.useRef)(!1),h=(0,t.useRef)(0),S=(0,t.useCallback)((function(e){h.current+=1,y("number"==typeof e?e:a)}),[]),R=function e(r){var t=r/1e3;if(null===v.current)return v.current=t,void(p.current=requestAnimationFrame(e));var n=t-v.current;if(v.current=t,y((function(e){var r=e+n;return"number"!=typeof u||r<u?r:(g.current=!0,u)})),g.current){if("function"==typeof o){d.current+=1e3*u;var i=d.current/1e3,c=o(i)||{},a=c.shouldRepeat,f=void 0!==a&&a,l=c.delay,s=void 0===l?0:l,m=c.newStartAt;f&&A.current&&(b.current=setTimeout((function(){S(m)}),1e3*s))}}else p.current=requestAnimationFrame(e)},w=function(){cancelAnimationFrame(p.current),clearTimeout(b.current),v.current=null};return i((function(){return e&&(p.current=requestAnimationFrame(R)),w}),[e]),i((function(){e&&A.current&&(w(),p.current=requestAnimationFrame(R))}),[u]),i((function(){A.current&&S()}),[f]),i((function(){e&&g.current&&(w(),p.current=requestAnimationFrame(R)),g.current=!1}),[h.current]),i((function(){return A.current=!0,function(){A.current=!1}}),[]),{elapsedTime:m,reset:S}},i="undefined"==typeof window?t.useEffect:t.useLayoutEffect;module.exports=r}(); | ||
var N=Object.create;var m=Object.defineProperty,P=Object.defineProperties,j=Object.getOwnPropertyDescriptor,z=Object.getOwnPropertyDescriptors,G=Object.getOwnPropertyNames,O=Object.getOwnPropertySymbols,H=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty,K=Object.prototype.propertyIsEnumerable;var V=(e,r,t)=>r in e?m(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,f=(e,r)=>{for(var t in r||(r={}))S.call(r,t)&&V(e,t,r[t]);if(O)for(var t of O(r))K.call(r,t)&&V(e,t,r[t]);return e},p=(e,r)=>P(e,z(r)),w=e=>m(e,"__esModule",{value:!0});var Q=(e,r)=>{w(e);for(var t in r)m(e,t,{get:r[t],enumerable:!0})},W=(e,r,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let u of G(r))!S.call(e,u)&&u!=="default"&&m(e,u,{get:()=>r[u],enumerable:!(t=j(r,u))||t.enumerable});return e},C=e=>W(w(m(e!=null?N(H(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);Q(exports,{useElapsedTime:()=>k});var n=C(require("react"));var d=C(require("react")),x=typeof window=="undefined"?d.useEffect:d.useLayoutEffect;var k=({isPlaying:e,duration:r,startAt:t=0,updateInterval:u=0,onComplete:R,onUpdate:T})=>{let[i,I]=(0,n.useState)(t),h=(0,n.useRef)(t*-1e3),s=(0,n.useRef)(null),c=(0,n.useRef)(null),b=(0,n.useRef)(null),o=(0,n.useRef)({elapsedTimeRef:0,durationRef:r,updateIntervalRef:u,startAtRef:t});o.current=p(f({},o.current),{durationRef:r,updateIntervalRef:u,startAtRef:t});let l=E=>{let a=E/1e3;if(c.current===null){c.current=a,s.current=requestAnimationFrame(l);return}let{durationRef:y,elapsedTimeRef:D,updateIntervalRef:F,startAtRef:J}=o.current,L=a-c.current,v=D+L;c.current=a,o.current=p(f({},o.current),{elapsedTimeRef:v});let B=J+(F===0?v:(v|0)*F),M=typeof y=="number"&&B>=y;I(M?y:B),M||(s.current=requestAnimationFrame(l))},q=()=>{s.current&&cancelAnimationFrame(s.current),b.current&&clearTimeout(b.current),c.current=null},A=(0,n.useCallback)(()=>{q(),o.current=p(f({},o.current),{elapsedTimeRef:0}),I(t),e&&(s.current=requestAnimationFrame(l))},[e]);return x(()=>{if(T==null||T(i),r&&i>=r){h.current+=r*1e3;let{shouldRepeat:E=!1,delay:a=0}=(R==null?void 0:R(h.current/1e3))||{};E&&(b.current=setTimeout(A,a*1e3))}},[i,r]),x(()=>(e&&(s.current=requestAnimationFrame(l)),q),[e]),{elapsedTime:i,reset:A}}; |
@@ -1,1 +0,1 @@ | ||
import{useState as x,useRef as t,useCallback as V,useEffect as h,useLayoutEffect as w}from"react";var u=typeof window=="undefined"?h:w,C=({isPlaying:m,duration:e,onComplete:b,autoResetKey:S,startAt:i=0})=>{let[p,q]=x(i),y=t(i*-1e3),r=t(null),c=t(null),a=t(null),s=t(!1),f=t(!1),F=t(0),T=V(n=>{F.current+=1,q(typeof n=="number"?n:i)},[]),o=n=>{let l=n/1e3;if(c.current===null){c.current=l,r.current=requestAnimationFrame(o);return}let d=l-c.current;c.current=l,q(E=>{let A=E+d;return typeof e!="number"||A<e?A:(f.current=!0,e)}),f.current||(r.current=requestAnimationFrame(o))},R=()=>{r.current&&cancelAnimationFrame(r.current),a.current&&clearTimeout(a.current),c.current=null};return u(()=>{if(e&&b&&p>=e){y.current+=e*1e3;let n=y.current/1e3,{shouldRepeat:l=!1,delay:d=0,newStartAt:E}=b(n)||{};l&&s.current&&(a.current=setTimeout(()=>{T(E)},d*1e3))}},[p,e]),u(()=>(m&&(r.current=requestAnimationFrame(o)),R),[m]),u(()=>{m&&s.current&&(R(),r.current=requestAnimationFrame(o))},[e]),u(()=>{s.current&&T()},[S]),u(()=>{m&&f.current&&(R(),r.current=requestAnimationFrame(o)),f.current=!1},[F.current]),u(()=>(s.current=!0,()=>{s.current=!1}),[]),{elapsedTime:p,reset:T}};export{C as useElapsedTime}; | ||
var w=Object.defineProperty,C=Object.defineProperties;var k=Object.getOwnPropertyDescriptors;var B=Object.getOwnPropertySymbols;var D=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var M=(t,e,r)=>e in t?w(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,i=(t,e)=>{for(var r in e||(e={}))D.call(e,r)&&M(t,r,e[r]);if(B)for(var r of B(e))J.call(e,r)&&M(t,r,e[r]);return t},l=(t,e)=>C(t,k(e));import{useState as P,useRef as c,useCallback as j}from"react";import{useEffect as L,useLayoutEffect as N}from"react";var E=typeof window=="undefined"?L:N;var z=({isPlaying:t,duration:e,startAt:r=0,updateInterval:y=0,onComplete:f,onUpdate:p})=>{let[a,v]=P(r),x=c(r*-1e3),u=c(null),o=c(null),d=c(null),n=c({elapsedTimeRef:0,durationRef:e,updateIntervalRef:y,startAtRef:r});n.current=l(i({},n.current),{durationRef:e,updateIntervalRef:y,startAtRef:r});let m=R=>{let s=R/1e3;if(o.current===null){o.current=s,u.current=requestAnimationFrame(m);return}let{durationRef:T,elapsedTimeRef:O,updateIntervalRef:q,startAtRef:S}=n.current,V=s-o.current,b=O+V;o.current=s,n.current=l(i({},n.current),{elapsedTimeRef:b});let A=S+(q===0?b:(b|0)*q),F=typeof T=="number"&&A>=T;v(F?T:A),F||(u.current=requestAnimationFrame(m))},I=()=>{u.current&&cancelAnimationFrame(u.current),d.current&&clearTimeout(d.current),o.current=null},h=j(()=>{I(),n.current=l(i({},n.current),{elapsedTimeRef:0}),v(r),t&&(u.current=requestAnimationFrame(m))},[t]);return E(()=>{if(p==null||p(a),e&&a>=e){x.current+=e*1e3;let{shouldRepeat:R=!1,delay:s=0}=(f==null?void 0:f(x.current/1e3))||{};R&&(d.current=setTimeout(h,s*1e3))}},[a,e]),E(()=>(t&&(u.current=requestAnimationFrame(m)),I),[t]),{elapsedTime:a,reset:h}};export{z as useElapsedTime}; |
@@ -5,3 +5,3 @@ export interface ReturnValue { | ||
/** Reset method to reset the elapsed time and start over from the "startAt" value */ | ||
reset: (newStartAt?: number) => void; | ||
reset: (newStartAt: number) => void; | ||
} | ||
@@ -8,0 +8,0 @@ export interface OnComplete { |
@@ -1,2 +0,27 @@ | ||
import type { Props, ReturnValue } from './types'; | ||
export declare const useElapsedTime: ({ isPlaying, duration, onComplete, autoResetKey, startAt, }: Props) => ReturnValue; | ||
export interface ReturnValue { | ||
/** Current elapsed time in seconds */ | ||
elapsedTime: number; | ||
/** Reset method to reset the elapsed time and start over from the "startAt" value */ | ||
reset: () => void; | ||
} | ||
export interface OnComplete { | ||
/** Indicates if the loop should start over. Default: false */ | ||
shouldRepeat?: boolean; | ||
/** Delay in seconds before looping again. Default: 0 */ | ||
delay?: number; | ||
} | ||
export interface Props { | ||
/** Indicates if the loop to get the elapsed time is running or it is paused */ | ||
isPlaying: boolean; | ||
/** Animation duration in seconds */ | ||
duration?: number; | ||
/** Start the animation at provided time in seconds. Default: 0 */ | ||
startAt?: number; | ||
/** Update interval in seconds. Determines how often the elapsed time value will change. When set to 0 the value will update on each key frame. Default: 0 */ | ||
updateInterval?: number; | ||
/** On animation complete event handler. It can be used to restart/repeat the animation by returning an object */ | ||
onComplete?: (totalElapsedTime: number) => OnComplete | void; | ||
/** On time update event handler. It receives the current elapsedTime time in seconds */ | ||
onUpdate?: (elapsedTime: number) => void; | ||
} | ||
export declare const useElapsedTime: ({ isPlaying, duration, startAt, updateInterval, onComplete, onUpdate, }: Props) => ReturnValue; |
{ | ||
"name": "use-elapsed-time", | ||
"version": "2.1.8", | ||
"version": "3.0.0", | ||
"description": "React hook to measure elapsed time using requestAnimationFrame", | ||
"main": "./lib/index.js", | ||
"module": "./lib/index.module.js", | ||
"types": "./lib/index.d.ts", | ||
"author": "Vasil Dimitrov", | ||
"license": "MIT", | ||
"files": [ | ||
"lib", | ||
"types" | ||
"lib" | ||
], | ||
"types": "types/use-elapsed-time.d.ts", | ||
"scripts": { | ||
"build": "webpack", | ||
"start": "node scripts/serve.js", | ||
"ts-declaration": "tsc --declaration --emitDeclarationOnly --outDir lib", | ||
"build": "yarn ts-declaration && node scripts/build.js", | ||
"test": "jest --collectCoverage --coverageDirectory=\"coverage\"", | ||
"test-watch": "jest --watch", | ||
"dev:push": "yarn build && yalc push", | ||
"prepublish": "yarn build" | ||
@@ -25,10 +28,8 @@ }, | ||
"hook", | ||
"hooks", | ||
"requestAnimationFrame", | ||
"animation", | ||
"loop", | ||
"elapsed", | ||
"time" | ||
], | ||
"author": "Vasil Dimitrov", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -42,22 +43,13 @@ "url": "https://github.com/vydimitrov/use-elapsed-time/issues" | ||
"devDependencies": { | ||
"@babel/core": "7.14.0", | ||
"@babel/preset-env": "7.14.1", | ||
"@babel/preset-react": "7.13.13", | ||
"@testing-library/react-hooks": "5.1.2", | ||
"babel-loader": "8.2.2", | ||
"@testing-library/react-hooks": "7.0.0", | ||
"@types/jest": "26.0.23", | ||
"codecov": "3.8.2", | ||
"esbuild": "0.12.9", | ||
"jest": "27.0.4", | ||
"prettier": "2.3.1", | ||
"react": "17.0.2", | ||
"jest": "26.6.3", | ||
"path": "0.12.7", | ||
"raf-stub": "3.0.0", | ||
"prettier": "2.3.0", | ||
"react-test-renderer": "17.0.2", | ||
"webpack": "5.36.2", | ||
"webpack-cli": "4.7.0" | ||
}, | ||
"browserslist": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
] | ||
"react-dom": "17.0.2", | ||
"ts-jest": "27.0.3", | ||
"typescript": "4.3.2" | ||
} | ||
} |
@@ -12,5 +12,3 @@ # useElapsedTime React hook | ||
- Set start time and duration | ||
- Easily repeat the measurement | ||
- Combine with [any easing function](http://www.gizma.com/easing/#l) to get the right animation | ||
- Built-in and ready-to-use TypeScript type definitions. | ||
- Adjust update interval to your need | ||
@@ -29,4 +27,3 @@ ## Installation | ||
const MyComponent = () => { | ||
const isPlaying = true | ||
const { elapsedTime } = useElapsedTime(isPlaying) | ||
const { elapsedTime } = useElapsedTime({ isPlaying: true }) | ||
@@ -42,37 +39,34 @@ return elapsedTime | ||
```js | ||
function useElapsedTime( | ||
const { | ||
elapsedTime: number, | ||
reset: () => void | ||
} = useElapsedTime({ | ||
isPlaying: boolean, | ||
options?: { | ||
duration?: number, | ||
startAt?: number, | ||
autoResetKey?: string | number, | ||
onComplete?: (totalElapsedTime: number) => void | { shouldRepeat: boolean, delay: number, newStartAt: number } | ||
} | ||
): { | ||
elapsedTime: number, | ||
reset?: (newStartAt: number) => void | ||
} | ||
duration?: number, | ||
startAt?: number, | ||
updateInterval?: number, | ||
onComplete?: (totalElapsedTime: number) => void | { shouldRepeat: boolean, delay: number }, | ||
onUpdate?: (elapsedTime: number) => void | ||
}) | ||
``` | ||
### 1st arg. `isPlaying: boolean` | ||
## Props | ||
> Default: `isPlaying = false` | ||
| Prop Name | Type | Default | Description | | ||
| -------------- | ------------------------------------------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| isPlaying | boolean | - | Indicates if the loop to get the elapsed time is running or it is paused | | ||
| duration | number | - | Animation duration in seconds | | ||
| startAt | number | 0 | Shift the start time to a different value than 0 | | ||
| updateInterval | number | 0 | Update interval in seconds. Determines how often the elapsed time value will change. When set to 0 the value will update on each key frame | | ||
| onComplete | (totalElapsedTime: number) => void \| { shouldRepeat: boolean, delay: number } | - | `onComplete` callback will be fired when the duration is reached. The callback will receive as an argument the `totalElapsedTime` in seconds. `onComplete` can be used to restart the elapsed time loop by returning an object with the following params: `shouldRepeat` indicates if the loop should start over; `delay` - delay before looping again in seconds | | ||
| onUpdate | (elapsedTime: number) => void | - | On time update event handler. It receives the current elapsedTime time in seconds | | ||
Indicates if the loop to get the elapsed time is running or it is paused. | ||
## Return value | ||
### 2nd arg. `options: object` | ||
The hook returns an object with `elapsedTime` in seconds and `reset` method - `{ elapsedTime, reset }` | ||
> Default: `options = {}` | ||
## Browser support | ||
| Prop Name | Type | Default | Description | | ||
| ------------ | -------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| duration | number | - | Animation duration in seconds | | ||
| startAt | number | 0 | Shift the start time to a different value than 0 | | ||
| autoResetKey | string \| number | - | Auto reset animation when the key changes. It works similar to React's `key` prop | | ||
| onComplete | (totalElapsedTime: number) => void \| { shouldRepeat: boolean, delay: number, newStartAt: number } | - | `onComplete` callback will be fired when the duration is reached. The callback will receive as an argument the `totalElapsedTime` in seconds. `onComplete` can be used to restart the elapsed time loop by returning an object with the following params: `shouldRepeat` indicates if the loop should start over; `delay` - delay before looping again in seconds; `newStartAt` set new start at value. | | ||
The hook supports [all modern browsers](https://caniuse.com/?search=es6) targeting `es6`. Internet Explorer (IE) is not longer supported. | ||
### Return value `{ elapsedTime, reset }` | ||
The hook returns an object with `elapsedTime` in seconds and `reset` method. | ||
## Use cases | ||
@@ -79,0 +73,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20116
10
73
10
79