diff --git a/example/src/scenes/Home.js b/example/src/scenes/Home.js index eaa8833c87..435213f857 100644 --- a/example/src/scenes/Home.js +++ b/example/src/scenes/Home.js @@ -28,6 +28,7 @@ import QueryWithRect from '../examples/QueryWithRect'; import ShapeSourceIcon from '../examples/ShapeSourceIcon'; import CustomVectorSource from '../examples/CustomVectorSource'; import ShowPointAnnotation from '../examples/ShowPointAnnotation'; +import AnimatedLine from '../examples/AnimatedLine'; import CreateOfflineRegion from '../examples/CreateOfflineRegion'; import DriveTheLine from '../examples/DriveTheLine'; import ImageOverlay from '../examples/ImageOverlay'; @@ -107,6 +108,7 @@ const Examples = [ new ExampleItem('Shape Source From Icon', ShapeSourceIcon), new ExampleItem('Custom Vector Source', CustomVectorSource), new ExampleItem('Show Point Annotation', ShowPointAnnotation), + new ExampleItem('Animated Line', AnimatedLine), new ExampleItem('Marker View', MarkerView), new ExampleItem('Create Offline Region', CreateOfflineRegion), new ExampleItem('Animation Along a Line', DriveTheLine), diff --git a/javascript/utils/animated/AnimatedLineString.js b/javascript/utils/animated/AnimatedLineString.js index 57c9195dc1..b99025a3c7 100644 --- a/javascript/utils/animated/AnimatedLineString.js +++ b/javascript/utils/animated/AnimatedLineString.js @@ -1,39 +1,43 @@ -import { Animated } from 'react-native'; +import {Animated} from 'react-native'; + +import AnimatedCoordinates from './AnimatedCoordinates'; // Used react-native-maps as a reference // https://github.com/react-community/react-native-maps/blob/master/lib/components/AnimatedRegion.js +// https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/nodes/AnimatedWithChildren.js const AnimatedWithChildren = Object.getPrototypeOf(Animated.ValueXY); - -import AnimatedCoordinates from './AnimatedCoordinates'; +if (__DEV__) { + if (AnimatedWithChildren.name !== 'AnimatedWithChildren') { + console.error( + 'AnimatedRegion could not obtain AnimatedWithChildren base class', + ); + } +} const DEFAULT_COORD = [0, 0]; const DEFAULT_LINE = { type: 'LineString', - coordinates: [DEFAULT_COORD, DEFAULT_COORD] + coordinates: [DEFAULT_COORD, DEFAULT_COORD], }; export class AnimatedLineString extends AnimatedWithChildren { constructor(line = DEFAULT_LINE) { super(); - //this._listeners = {}; - - this.coordinates = []; - - line.coordinates.forEach((coord) => { - this.coordinates.push(new AnimatedCoordinates(coord)); - }); + this.coordinates = line.coordinates.map( + coord => new AnimatedCoordinates(coord), + ); } flattenOffset() { - this.coordinates.forEach((coord) => { + this.coordinates.forEach(coord => { coord.flattenOffset(); }); } stopAnimation(cb) { - this.coordinates.forEach((coord) => { + this.coordinates.forEach(coord => { coord.stopAnimation(); }); @@ -43,19 +47,19 @@ export class AnimatedLineString extends AnimatedWithChildren { } resetAnimation() { - this.coordinates.forEach((coord) => { + this.coordinates.forEach(coord => { coord.resetAnimation(); - }) + }); } addListener(cb) { - this.coordinates.forEach((coord) => { + this.coordinates.forEach(coord => { coord.addListener(cb); }); } removeListener(id) { - this.coordinates.forEach((coord) => { + this.coordinates.forEach(coord => { coord.removeListener(id); }); } @@ -77,23 +81,40 @@ export class AnimatedLineString extends AnimatedWithChildren { _cleanup(coordinates) { while (this.coordinates.length > coordinates.length) { - const popped = this.coordinates.pop(); + this.coordinates.pop(); } super.__callListeners(this.__getValue()); } - animate(type, config) { - const { coordinates, ...rest } = config; + _onAnimationDone(animation, doneCB) { + return new Proxy(animation, { + get(obj, prop) { + if (prop === 'start') { + return function start(origDoneCB, ...args) { + return obj.start((startParams, ...startArgs) => { + doneCB(startParams); + if (origDoneCB) { + origDoneCB(startParams, ...startArgs); + } + }, ...args); + }; + } + return obj[prop]; + }, + }); + } + animate(type, config) { + const {coordinates, ...rest} = config; const last = this._last(coordinates); this._setup(coordinates); // Animate existing values - let animations = coordinates.map((coord, i) => { + const animations = coordinates.map((coord, i) => { return this.coordinates[i][type]({ ...config, - coordinates: coordinates[i] + coordinates: coordinates[i], }); }); @@ -103,13 +124,20 @@ export class AnimatedLineString extends AnimatedWithChildren { animations.push( this.coordinates[i][type]({ ...config, - coordinates: last - }) + coordinates: last, + }), ); i++; } - return Animated.parallel(animations); + return this._onAnimationDone( + Animated.parallel(animations), + ({finished}) => { + if (finished) { + this._cleanup(coordinates); + } + }, + ); } runImmediate(type, coordinates) { @@ -130,31 +158,31 @@ export class AnimatedLineString extends AnimatedWithChildren { this.runImmediate('setOffset', line.coordinates); } - spring(config = { coordinates: DEFAULT_COORD }) { + spring(config = {coordinates: DEFAULT_COORD}) { return this.animate('spring', config); } - timing(config = { coordinates: DEFAULT_COORD }) { + timing(config = {coordinates: DEFAULT_COORD}) { return this.animate('timing', config); } - decay(config = { coordinates: DEFAULT_COORD }) { + decay(config = {coordinates: DEFAULT_COORD}) { return this.animate('decay', config); } __getValue() { return { type: 'LineString', - coordinates: this.coordinates.map((coord) => coord.__getValue()) + coordinates: this.coordinates.map(coord => coord.__getValue()), }; } __attach() { - this.coordinates.forEach((coord) => coord.__attach(this)); + this.coordinates.forEach(coord => coord.__attach(this)); } __detach() { - this.coordinates.forEach((coord) => coord.__detach(this)); + this.coordinates.forEach(coord => coord.__detach(this)); } }