Comparing version 1.1.1 to 1.1.2
@@ -11,2 +11,5 @@ import EventEmitter from 'eventemitter3'; | ||
easing?: TEasing; | ||
delay?: number; | ||
direction?: 'normal' | 'reverse' | 'alternate'; | ||
loop?: number; | ||
} | ||
@@ -18,8 +21,15 @@ export declare class Animate extends EventEmitter { | ||
private easing; | ||
private delay; | ||
private direction; | ||
private loop; | ||
private startTime; | ||
private requestId?; | ||
private process?; | ||
private previousValue; | ||
constructor({ from, to, duration, easing }: AnimateOptions); | ||
private loopsCompleted; | ||
private isReversed; | ||
private hasCompleted; | ||
constructor({ from, to, duration, easing, delay, direction, loop, }: AnimateOptions); | ||
private isValidAnimatableValue; | ||
private interpolate; | ||
private updateValue; | ||
private getInterpolatedValue; | ||
private tick; | ||
@@ -26,0 +36,0 @@ start(): this; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -8,27 +31,59 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
const eventemitter3_1 = __importDefault(require("eventemitter3")); | ||
const framesync_1 = __importStar(require("framesync")); | ||
const easing_1 = require("./easing"); | ||
class Animate extends eventemitter3_1.default { | ||
constructor({ from, to, duration, easing = easing_1.easing.linear }) { | ||
constructor({ from, to, duration, easing = easing_1.easing.linear, delay = 0, direction = 'normal', loop = 1, }) { | ||
super(); | ||
this.tick = (now) => { | ||
try { | ||
const elapsed = now - this.startTime; | ||
const t = Math.min(1, elapsed / this.duration); | ||
const easedT = this.easing(t); | ||
const currentValue = this.updateValue(this.from, this.to, easedT); | ||
if (JSON.stringify(currentValue) !== JSON.stringify(this.previousValue)) { | ||
this.emit('update', currentValue); | ||
this.previousValue = currentValue; | ||
this.tick = ({ timestamp }) => { | ||
const elapsed = timestamp - this.startTime - this.delay; | ||
if (elapsed < 0) { | ||
this.process = framesync_1.default.update(this.tick, true); | ||
return; | ||
} | ||
let t = Math.min(1, elapsed / this.duration); | ||
if (this.isReversed) | ||
t = 1 - t; | ||
const easedT = this.easing(t); | ||
const currentValue = this.getInterpolatedValue(this.from, this.to, easedT); | ||
if (JSON.stringify(currentValue) !== JSON.stringify(this.previousValue)) { | ||
this.emit('update', currentValue); | ||
this.previousValue = currentValue; | ||
} | ||
// Check if animation is complete | ||
if ((!this.isReversed && t < 1) || (this.isReversed && t > 0)) { | ||
this.process = framesync_1.default.update(this.tick, true); | ||
} | ||
else { | ||
this.loopsCompleted += 1; | ||
if (this.direction === 'alternate') { | ||
this.isReversed = !this.isReversed; | ||
} | ||
if (t < 1) { | ||
this.requestId = requestAnimationFrame(this.tick); | ||
if (this.loop === Infinity || this.loopsCompleted < this.loop) { | ||
this.startTime = timestamp; | ||
this.process = framesync_1.default.update(this.tick, true); | ||
} | ||
else { | ||
else if (!this.hasCompleted) { | ||
if (this.process !== undefined) | ||
framesync_1.cancelSync.update(this.process); | ||
this.hasCompleted = true; | ||
this.emit('complete'); | ||
} | ||
} | ||
catch (error) { | ||
this.emit('error', error); | ||
} | ||
}; | ||
// Validate the options | ||
if (!this.isValidAnimatableValue(from) || !this.isValidAnimatableValue(to)) { | ||
throw new Error('Invalid animatable value'); | ||
} | ||
if (typeof duration !== 'number' || duration <= 0) { | ||
throw new Error('Duration must be a positive number'); | ||
} | ||
if (typeof delay !== 'number' || delay < 0) { | ||
throw new Error('Delay must be a non-negative number'); | ||
} | ||
if (!['normal', 'reverse', 'alternate'].includes(direction)) { | ||
throw new Error('Invalid direction'); | ||
} | ||
if (typeof loop !== 'number' || loop < 0) { | ||
throw new Error('Loop must be a non-negative number'); | ||
} | ||
this.from = from; | ||
@@ -38,9 +93,25 @@ this.to = to; | ||
this.easing = easing; | ||
this.delay = delay; | ||
this.direction = direction; | ||
this.loop = loop; | ||
this.startTime = performance.now(); | ||
this.previousValue = from; | ||
this.loopsCompleted = 0; | ||
this.isReversed = direction === 'reverse'; | ||
this.hasCompleted = false; | ||
} | ||
isValidAnimatableValue(value) { | ||
if (typeof value === 'number') | ||
return true; | ||
if (Array.isArray(value)) | ||
return value.every(val => typeof val === 'number' || this.isValidAnimatableValue(val)); | ||
if (typeof value === 'object') { | ||
return Object.values(value).every(val => typeof val === 'number' || this.isValidAnimatableValue(val)); | ||
} | ||
return false; | ||
} | ||
interpolate(start, end, t) { | ||
return start + (end - start) * t; | ||
} | ||
updateValue(from, to, t) { | ||
getInterpolatedValue(from, to, t) { | ||
if (typeof from === 'number' && typeof to === 'number') { | ||
@@ -52,4 +123,3 @@ return this.interpolate(from, to, t); | ||
? this.interpolate(start, to[index], t) | ||
: start // For non-number elements, just return the original value | ||
); | ||
: start); | ||
} | ||
@@ -66,3 +136,3 @@ if (typeof from === 'object' && typeof to === 'object') { | ||
else if (typeof fromObj[key] === 'object' && typeof toObj[key] === 'object') { | ||
result[key] = this.updateValue(fromObj[key], toObj[key], t); | ||
result[key] = this.getInterpolatedValue(fromObj[key], toObj[key], t); | ||
} | ||
@@ -80,9 +150,12 @@ else { | ||
this.startTime = performance.now(); | ||
this.loopsCompleted = 0; | ||
this.isReversed = this.direction === 'reverse'; | ||
this.hasCompleted = false; | ||
this.emit('start'); | ||
this.requestId = requestAnimationFrame(this.tick); | ||
this.process = framesync_1.default.update(this.tick, true); | ||
return this; | ||
} | ||
stop() { | ||
if (this.requestId) { | ||
cancelAnimationFrame(this.requestId); | ||
if (this.process !== undefined) { | ||
framesync_1.cancelSync.update(this.process); | ||
this.emit('stop'); | ||
@@ -89,0 +162,0 @@ } |
{ | ||
"name": "nimate", | ||
"version": "1.1.1", | ||
"version": "1.1.2", | ||
"description": "A simple, flexible animation library.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -23,15 +23,2 @@ # nimate | ||
**Note:** If `requestAnimationFrame` is not available in your environment, you will need to polyfill it. You can use the `raf` package for this: | ||
```bash | ||
npm install raf | ||
``` | ||
Then, import and use the polyfill in your project: | ||
```javascript | ||
import raf from 'raf'; | ||
raf.polyfill(); | ||
``` | ||
## 💻 Usage | ||
@@ -148,2 +135,5 @@ | ||
- `easing` (EasingFunction, optional): The easing function to use. Default is `Easing.linear`. | ||
- `delay` (number, optional): The delay before the animation starts in milliseconds. Default is `0`. | ||
- `direction` ('normal' | 'reverse' | 'alternate', optional): The direction of the animation. Default is `'normal'`. | ||
- `loop` (number, optional): The number of times the animation should loop. Default is `1`. | ||
@@ -161,3 +151,2 @@ #### Methods | ||
- `stop`: Emitted when the animation is stopped. | ||
- `error`: Emitted when an error occurs during the animation. | ||
@@ -164,0 +153,0 @@ ### `Sequence` |
18812
309
170