UNPKG

9.23 kBJavaScriptView Raw
1function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
2
3function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
4
5function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
6
7function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
8
9function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
11function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
12
13function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
14
15function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
16
17function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18
19function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
20
21/*global setTimeout:false */
22import React from "react";
23import PropTypes from "prop-types";
24import * as d3Ease from "d3-ease";
25import { victoryInterpolator } from "./util";
26import TimerContext from "../victory-util/timer-context";
27import isEqual from "react-fast-compare";
28
29var VictoryAnimation =
30/*#__PURE__*/
31function (_React$Component) {
32 _inherits(VictoryAnimation, _React$Component);
33
34 function VictoryAnimation(props, context) {
35 var _this;
36
37 _classCallCheck(this, VictoryAnimation);
38
39 _this = _possibleConstructorReturn(this, (VictoryAnimation.__proto__ || Object.getPrototypeOf(VictoryAnimation)).call(this, props, context));
40 /* defaults */
41
42 _this.state = {
43 data: Array.isArray(_this.props.data) ? _this.props.data[0] : _this.props.data,
44 animationInfo: {
45 progress: 0,
46 animating: false
47 }
48 };
49 _this.interpolator = null;
50 _this.queue = Array.isArray(_this.props.data) ? _this.props.data.slice(1) : [];
51 /* build easing function */
52
53 _this.ease = d3Ease[_this.toNewName(_this.props.easing)];
54 /*
55 There is no autobinding of this in ES6 classes
56 so we bind functionToBeRunEachFrame to current instance of victory animation class
57 */
58
59 _this.functionToBeRunEachFrame = _this.functionToBeRunEachFrame.bind(_assertThisInitialized(_this));
60 _this.timer = _this.context.animationTimer;
61 return _this;
62 }
63
64 _createClass(VictoryAnimation, [{
65 key: "componentDidMount",
66 value: function componentDidMount() {
67 // Length check prevents us from triggering `onEnd` in `traverseQueue`.
68 if (this.queue.length) {
69 this.traverseQueue();
70 }
71 }
72 }, {
73 key: "componentDidUpdate",
74 value: function componentDidUpdate(prevProps) {
75 var equalProps = isEqual(this.props, prevProps);
76
77 if (!equalProps) {
78 /* If the previous animation didn't finish, force it to complete before starting a new one */
79 if (this.interpolator && this.state.animationInfo && this.state.animationInfo.progress < 1) {
80 // eslint-disable-next-line react/no-did-update-set-state
81 this.setState({
82 data: this.interpolator(1),
83 animationInfo: {
84 progress: 1,
85 animating: false,
86 terminating: true
87 }
88 });
89 } else {
90 /* cancel existing loop if it exists */
91 this.timer.unsubscribe(this.loopID);
92 /* If an object was supplied */
93
94 if (!Array.isArray(this.props.data)) {
95 // Replace the tween queue. Could set `this.queue = [nextProps.data]`,
96 // but let's reuse the same array.
97 this.queue.length = 0;
98 this.queue.push(this.props.data);
99 /* If an array was supplied */
100 } else {
101 var _queue;
102
103 /* Extend the tween queue */
104 (_queue = this.queue).push.apply(_queue, _toConsumableArray(this.props.data));
105 }
106 /* Start traversing the tween queue */
107
108
109 this.traverseQueue();
110 }
111 }
112 }
113 }, {
114 key: "componentWillUnmount",
115 value: function componentWillUnmount() {
116 if (this.loopID) {
117 this.timer.unsubscribe(this.loopID);
118 } else {
119 this.timer.stop();
120 }
121 }
122 }, {
123 key: "toNewName",
124 value: function toNewName(ease) {
125 // d3-ease changed the naming scheme for ease from "linear" -> "easeLinear" etc.
126 var capitalize = function (s) {
127 return s && s[0].toUpperCase() + s.slice(1);
128 };
129
130 return "ease".concat(capitalize(ease));
131 }
132 /* Traverse the tween queue */
133
134 }, {
135 key: "traverseQueue",
136 value: function traverseQueue() {
137 var _this2 = this;
138
139 if (this.queue.length) {
140 /* Get the next index */
141 var data = this.queue[0];
142 /* compare cached version to next props */
143
144 this.interpolator = victoryInterpolator(this.state.data, data);
145 /* reset step to zero */
146
147 if (this.props.delay) {
148 setTimeout(function () {
149 _this2.loopID = _this2.timer.subscribe(_this2.functionToBeRunEachFrame, _this2.props.duration);
150 }, this.props.delay);
151 } else {
152 this.loopID = this.timer.subscribe(this.functionToBeRunEachFrame, this.props.duration);
153 }
154 } else if (this.props.onEnd) {
155 this.props.onEnd();
156 }
157 }
158 /* every frame we... */
159
160 }, {
161 key: "functionToBeRunEachFrame",
162 value: function functionToBeRunEachFrame(elapsed, duration) {
163 /*
164 step can generate imprecise values, sometimes greater than 1
165 if this happens set the state to 1 and return, cancelling the timer
166 */
167 duration = duration !== undefined ? duration : this.props.duration;
168 var step = duration ? elapsed / duration : 1;
169
170 if (step >= 1) {
171 this.setState({
172 data: this.interpolator(1),
173 animationInfo: {
174 progress: 1,
175 animating: false,
176 terminating: true
177 }
178 });
179
180 if (this.loopID) {
181 this.timer.unsubscribe(this.loopID);
182 }
183
184 this.queue.shift();
185 this.traverseQueue();
186 return;
187 }
188 /*
189 if we're not at the end of the timer, set the state by passing
190 current step value that's transformed by the ease function to the
191 interpolator, which is cached for performance whenever props are received
192 */
193
194
195 this.setState({
196 data: this.interpolator(this.ease(step)),
197 animationInfo: {
198 progress: step,
199 animating: step < 1
200 }
201 });
202 }
203 }, {
204 key: "render",
205 value: function render() {
206 return this.props.children(this.state.data, this.state.animationInfo);
207 }
208 }]);
209
210 return VictoryAnimation;
211}(React.Component);
212
213Object.defineProperty(VictoryAnimation, "displayName", {
214 configurable: true,
215 enumerable: true,
216 writable: true,
217 value: "VictoryAnimation"
218});
219Object.defineProperty(VictoryAnimation, "propTypes", {
220 configurable: true,
221 enumerable: true,
222 writable: true,
223 value: {
224 children: PropTypes.func,
225 data: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
226 delay: PropTypes.number,
227 duration: PropTypes.number,
228 easing: PropTypes.oneOf(["back", "backIn", "backOut", "backInOut", "bounce", "bounceIn", "bounceOut", "bounceInOut", "circle", "circleIn", "circleOut", "circleInOut", "linear", "linearIn", "linearOut", "linearInOut", "cubic", "cubicIn", "cubicOut", "cubicInOut", "elastic", "elasticIn", "elasticOut", "elasticInOut", "exp", "expIn", "expOut", "expInOut", "poly", "polyIn", "polyOut", "polyInOut", "quad", "quadIn", "quadOut", "quadInOut", "sin", "sinIn", "sinOut", "sinInOut"]),
229 onEnd: PropTypes.func
230 }
231});
232Object.defineProperty(VictoryAnimation, "defaultProps", {
233 configurable: true,
234 enumerable: true,
235 writable: true,
236 value: {
237 data: {},
238 delay: 0,
239 duration: 1000,
240 easing: "quadInOut"
241 }
242});
243Object.defineProperty(VictoryAnimation, "contextType", {
244 configurable: true,
245 enumerable: true,
246 writable: true,
247 value: TimerContext
248});
249export { VictoryAnimation as default };
\No newline at end of file