React-Native Animated Polyline

shayam thomas
3 min readJun 8, 2019

--

Small Intro

Hey !!

I’m new to react native.
I usually develop web products using react and node, and now I also wanted to get into mobile app development. I have already cloned Uber as a web product and I am currently building a mobile app for it, so that I have a pack of web and app both.

That’s how I got into react-native.

Development

I studied the relevant docs and started working. Initially I struggled in integrating google map, however I have successfully achieved it. Later I wanted to bring in polyline in the google map, same as one of Uber’s features and I am done with it as well. But what about animating it, again — just like Uber?

I have finally figured that out too and I’m gonna tell you how.

Animating polyline

Below is the code for map and polyline integration in the app as shown in the image provided following.

import React, {Component, Fragment} from 'react';
import { Text, TouchableOpacity, View} from 'react-native';
import MapView, {PROVIDER_GOOGLE, Polyline, Circle} from 'react-native-maps';
export default class Booking extends Component {
render() {
return (
<Fragment>

{/* Map */}
<MapView
provider={PROVIDER_GOOGLE}
style={styles.mapView}
customMapStyle={MapStyle}
zoomEnabled={false}
region={{
latitude: 13.021301505791406,
longitude: 80.18522389233112,
latitudeDelta: 0.04749824275133463,
longitudeDelta: 0.0274658203125,
}}>

{/* Default Polyline */}
<Polyline
coordinates={Direction}
strokeColor="#666"
strokeWidth={5}
/>

{/*Source Circle */}
<Circle
center={{
"latitude": 13.030710000000001,
"longitude": 80.17604
}}
radius={50}
strokeColor={"#484848"}
strokeWidth={5}
fillColor={"#fff"}
zIndex={1}
/>

{/* Destination Circle */}
<Circle
center={{
"latitude": 13.04174,
"longitude": 80.19337
}}
radius={50}
strokeColor={"#484848"}
strokeWidth={5}
fillColor={"#fff"}
zIndex={1}
/>
</MapView>


</Fragment>
);
}
}

How did I animate it?

I did some research and I got this chunk of code from Stack overflow.

var polyline = GMSPolyline()
var animationPolyline = GMSPolyline()
var path = GMSPath()
var animationPath = GMSMutablePath()
var i: UInt = 0
var timer: Timer!
func drawRoute(routeDict: Dictionary<String, Any>) {

let routesArray = routeDict ["routes"] as! NSArray

if (routesArray.count > 0){
let routeDict = routesArray[0] as! Dictionary<String, Any>
let routeOverviewPolyline = routeDict["overview_polyline"] as! Dictionary<String, Any>
let points = routeOverviewPolyline["points"]
self.path = GMSPath.init(fromEncodedPath: points as! String)!

self.polyline.path = path
self.polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
self.polyline.strokeWidth = 3.0
self.polyline.map = self.mapView

self.timer = Timer.scheduledTimer(timeInterval: 0.003, target: self, selector: #selector(animatePolylinePath), userInfo: nil, repeats: true)
}
}

func animatePolylinePath() {
if (self.i < self.path.count()) {
self.animationPath.add(self.path.coordinate(at: self.i))
self.animationPolyline.path = self.animationPath
self.animationPolyline.strokeColor = UIColor.black
self.animationPolyline.strokeWidth = 3
self.animationPolyline.map = self.mapView
self.i += 1
}
else {
self.i = 0
self.animationPath = GMSMutablePath()
self.animationPolyline.map = nil
}
}

self.timer.invalidate()

The above code written in swift animates polyline in iOS app. I have comprehended the same idea and brought it out in react native. Below is the code which animates polyline in React-native.

export default class Booking extends Component {
render() {
const DirectionRoutes = [...Direction].reverse();
return (
<Fragment>

{/* Status bar*/}
<CustomStatusBar/>

{/* Map */}
<MapView
provider={PROVIDER_GOOGLE}
style={styles.mapView}
customMapStyle={MapStyle}
zoomEnabled={false}
region={{
latitude: 13.021301505791406,
longitude: 80.18522389233112,
latitudeDelta: 0.04749824275133463,
longitudeDelta: 0.0274658203125,
}}>

{/* Default Polyline */}
<Polyline
coordinates={Direction}
strokeColor="#666"
strokeWidth={5}
/>

{/* Animating polyline */}
<AnimatingPolylineComponent Direction={DirectionRoutes}/>

{/*Source Circle */}
<Circle
center={{
"latitude": 13.030710000000001,
"longitude": 80.17604
}}
radius={50}
strokeColor={"#484848"}
strokeWidth={5}
fillColor={"#fff"}
zIndex={1}
/>

{/* Destination Circle */}
<Circle
center={{
"latitude": 13.04174,
"longitude": 80.19337
}}
radius={50}
strokeColor={"#484848"}
strokeWidth={5}
fillColor={"#fff"}
zIndex={1}
/>
</MapView>


</Fragment>
);
}
}
class AnimatingPolylineComponent extends Component {
state = {
polylinePath: this.props.Direction
};

componentDidMount() {
this.animatePolyline();
}

animatePolyline = () => {
this.interval = setInterval(() => this.animatePolylineStart(), 70);
};

componentWillUnmount() {
clearInterval(this.interval);
}

animatePolylineStart = () => {
if (this.state.polylinePath.length < this.props.Direction.length) {
const Direction = this.props.Direction;
const polylinePath = [
...Direction.slice(0, this.state.polylinePath.length - 1)
];
this.setState({polylinePath});
} else {
this.setState({polylinePath: []})
}
};

render() {
return (
<Fragment>
{
(this.state.polylinePath.length > 0) && <Polyline
coordinates={this.state.polylinePath}
strokeColor="#484848"
strokeWidth={5}
/>
}
</Fragment>
)
}
}

You may add more polyline components with different time intervals and different colors.

And that’s how I did it. I hope this articles helps. Thanks.

Don’t forget to clap and share :)

--

--