-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: make "To" and "SpringTransform" inherit from "AnimationValue"
These classes don't use much from "SpringValue", so I think we're better off moving the shared functionality into a shared superclass, like "AnimationValue".
- Loading branch information
1 parent
084c8ac
commit c74d4c0
Showing
6 changed files
with
221 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,117 @@ | ||
import { FluidValue, FluidObserver, FluidType, defineHidden } from 'shared' | ||
import { Animated } from './Animated' | ||
import { | ||
FluidValue, | ||
FluidObserver, | ||
FluidType, | ||
defineHidden, | ||
is, | ||
each, | ||
} from 'shared' | ||
import { AnimatedValue } from './AnimatedValue' | ||
import { AnimatedArray } from './AnimatedArray' | ||
|
||
export const isAnimationValue = (value: any): value is AnimationValue => | ||
(value && value[FluidType]) == 2 | ||
|
||
/** Called whenever an `AnimationValue` is changed */ | ||
export type OnChange<T = unknown> = ( | ||
value: T, | ||
source: AnimationValue<T> | ||
) => void | ||
|
||
/** An object or function that observes an `AnimationValue` */ | ||
export type AnimationObserver<T = unknown> = FluidObserver<T> | OnChange<T> | ||
|
||
let nextId = 1 | ||
|
||
/** @internal A kind of `FluidValue` that provides access to an `Animated` object, a generated identifier, and the current value */ | ||
export abstract class AnimationValue<T = any> implements FluidValue<T> { | ||
constructor() { | ||
/** | ||
* A kind of `FluidValue` that manages an `AnimatedValue` node. | ||
* | ||
* Its underlying value can be accessed and even observed. | ||
*/ | ||
export abstract class AnimationValue<T = any> | ||
implements FluidValue<T>, FluidObserver { | ||
readonly id = nextId++ | ||
|
||
abstract idle: boolean | ||
abstract node: | ||
| AnimatedValue<T> | ||
| (T extends ReadonlyArray<any> ? AnimatedArray<T> : never) | ||
|
||
protected _priority = 0 | ||
protected _children = new Set<AnimationObserver<T>>() | ||
|
||
constructor(readonly key?: keyof any) { | ||
defineHidden(this, FluidType, 2) | ||
} | ||
readonly id = nextId++ | ||
abstract node: Animated | ||
abstract get(): T | ||
abstract addChild(child: FluidObserver): void | ||
abstract removeChild(child: FluidObserver): void | ||
|
||
/** @internal Controls the order in which animations are updated */ | ||
get priority() { | ||
return this._priority | ||
} | ||
set priority(priority: number) { | ||
if (this.priority != priority) { | ||
this.priority = priority | ||
this._onPriorityChange(priority) | ||
} | ||
} | ||
|
||
/** Get the current value */ | ||
get() { | ||
return this.node.getValue() | ||
} | ||
|
||
/** @internal */ | ||
addChild(child: AnimationObserver<T>): void { | ||
if (!this._children.size) this._attach() | ||
this._children.add(child) | ||
} | ||
|
||
/** @internal */ | ||
removeChild(child: AnimationObserver<T>): void { | ||
this._children.delete(child) | ||
if (!this._children.size) this._detach() | ||
} | ||
|
||
/** @internal */ | ||
abstract onParentChange(value: T, idle: boolean, parent: FluidValue): void | ||
|
||
/** @internal */ | ||
onParentPriorityChange(priority: number, _parent: FluidValue) { | ||
// Assume we only have one parent. | ||
this.priority = priority + 1 | ||
} | ||
|
||
protected _attach() {} | ||
protected _detach() {} | ||
|
||
/** Notify observers of a change to our value */ | ||
protected _onChange(value: T, idle = false) { | ||
// Clone "_children" so it can be safely mutated by the loop. | ||
for (const observer of Array.from(this._children)) { | ||
if (is.fun(observer)) { | ||
observer(value, this) | ||
} else { | ||
observer.onParentChange(value, idle, this) | ||
} | ||
} | ||
} | ||
|
||
/** Notify observers of a change to our priority */ | ||
protected _onPriorityChange(priority: number) { | ||
each(this._children, observer => { | ||
if (!is.fun(observer)) { | ||
observer.onParentPriorityChange(priority, this) | ||
} | ||
}) | ||
} | ||
|
||
/** Reset our node and the nodes of every descendant */ | ||
protected _reset(goal?: T) { | ||
this.node.reset(!this.idle, goal) | ||
each(this._children, observer => { | ||
if (isAnimationValue(observer)) { | ||
observer._reset(goal) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.