addimated
Version:
An always interruptable, declarative animation library for React
167 lines (148 loc) • 4.47 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import { AnimatedProps } from "./AnimatedProps";
import { AnimatedWithChildren } from "./AnimatedWithChildren";
import { Animation } from "./Animation";
function _flush(rootNode) {
var animatedStyles = new Set();
function findAnimatedStyles(node) {
if (node instanceof AnimatedProps) {
animatedStyles.add(node);
} else {
node.__getChildren().forEach(findAnimatedStyles);
}
}
findAnimatedStyles(rootNode);
animatedStyles.forEach(function (animatedStyle) {
return animatedStyle.update();
});
}
var AnimatedValue =
/*#__PURE__*/
function (_AnimatedWithChildren) {
_inherits(AnimatedValue, _AnimatedWithChildren);
// TODO: Tracking
// TODO: Listeners
function AnimatedValue(value, manager) {
var _this;
_classCallCheck(this, AnimatedValue);
_this = _possibleConstructorReturn(this, _getPrototypeOf(AnimatedValue).call(this));
_this.manager = manager;
_this.model = value;
_this.offset = 0;
_this.animations = [];
return _this;
}
_createClass(AnimatedValue, [{
key: "__attach",
value: function __attach() {
this.manager.attachValue(this);
this.flush();
}
}, {
key: "__detach",
value: function __detach() {
this.stopAnimations();
this.manager.detatchValue(this);
}
}, {
key: "__getValue",
value: function __getValue() {
return this.animations.reduce(function (acc, anim) {
return acc + anim.getValue();
}, this.offset + this.model);
}
/**
* Directly set the value. This will stop any animations running on the value
* and update all the bound properties.
*/
}, {
key: "setValue",
value: function setValue(value) {
this.stopAnimations();
this.model = value;
this.flush();
}
/**
* Sets an offset that is applied on top of whatever value is set, whether via
* `setValue`, an animation, or `Animated.event`. Useful for compensating
* things like the start of a pan gesture.
*/
}, {
key: "setOffset",
value: function setOffset(offset) {
this.offset = offset;
}
/**
* Merges the offset value into the base value and resets the offset to zero.
* The final output of the value is unchanged.
*/
}, {
key: "flattenOffset",
value: function flattenOffset() {
this.model += this.offset;
this.offset = 0;
}
/**
* Sets the offset value to the base value, and resets the base value to zero.
* The final output of the value is unchanged.
*/
}, {
key: "extractOffset",
value: function extractOffset() {
this.offset += this.model;
this.model = 0;
}
}, {
key: "step",
value: function step(timestamp) {
if (this.animations.length === 0) {
this.velocity = null;
this.previousValue = null;
this.previousTimestamp = null;
return null;
}
this.animations.forEach(function (anim) {
anim.step(timestamp);
});
this.animations = this.animations.filter(function (anim) {
return !anim.ended;
});
var nextValue = this.__getValue();
var prevVal = this.previousValue;
var prevTime = this.previousTimestamp;
if (prevVal && prevTime) {
this.velocity = (nextValue - prevVal) / (timestamp - prevTime);
}
this.previousTimestamp = timestamp;
this.previousValue = nextValue;
return this;
}
}, {
key: "animate",
value: function animate(animation, callback) {
this.animations = animation.start(this, this.model, callback);
this.manager.requestTick();
}
}, {
key: "stopAnimations",
value: function stopAnimations(callback) {
this.animations.forEach(function (anim) {
anim.stop();
});
this.animations = [];
callback && callback(this.__getValue());
}
}, {
key: "flush",
value: function flush() {
_flush(this);
}
}]);
return AnimatedValue;
}(AnimatedWithChildren);
export { AnimatedValue };
//# sourceMappingURL=AnimatedValue.js.map