Skip to content

Instantly share code, notes, and snippets.

@iremlopsum
Created July 24, 2019 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iremlopsum/b9f4e079edfd267ec9439c41579c7197 to your computer and use it in GitHub Desktop.
Save iremlopsum/b9f4e079edfd267ec9439c41579c7197 to your computer and use it in GitHub Desktop.
animatedSVGMap
import React, { PureComponent } from 'react'
import { View, StyleSheet, Animated, Easing } from 'react-native'
import { scale } from 'react-native-size-matters'
import Svg, { G, Path } from 'react-native-svg'
import withStore from '@new-redux/withStore'
import { Colors } from '../../../Values'
import { getCountryColor } from '../../../Helper/worldHelper'
import { VIEW_BOX, mapPathData } from '../svg-map-data'
const AnimatedG = Animated.createAnimatedComponent(G)
class WorldMap extends PureComponent {
animatedXValue = new Animated.Value(0)
animatedYValue = new Animated.Value(0)
animatedScaleValue = new Animated.Value(1)
animatedOpacityValue = new Animated.Value(1)
componentDidMount = () => {
Animated.parallel([
Animated.timing(this.animatedXValue, {
toValue: 150,
duration: 1000,
delay: 1000,
easing: Easing.bezier(0.65, 0, 0.24, 1),
useNativeDriver: true,
}),
Animated.timing(this.animatedYValue, {
toValue: 70,
duration: 1000,
delay: 1000,
easing: Easing.bezier(0.65, 0, 0.24, 1),
useNativeDriver: true,
}),
Animated.timing(this.animatedScaleValue, {
toValue: 1.5,
duration: 1000,
delay: 1000,
easing: Easing.bezier(0.65, 0, 0.24, 1),
useNativeDriver: true,
}),
Animated.timing(this.animatedOpacityValue, {
toValue: 0,
duration: 1000,
delay: 1000,
easing: Easing.bezier(0.65, 0, 0.24, 1),
useNativeDriver: true,
}),
]).start()
}
renderCountry = (continent, country, index) => {
const paths = mapPathData[continent][country]['paths']
const color = getCountryColor(country)
return (
<G fill={color} key={country + index}>
{paths.map((path, index) => {
return <Path d={path} key={index} />
})}
</G>
)
}
renderContinent = continent => {
const { currentContinent } = this.props
const cd = mapPathData[continent]
const countriesPerContinent = Object.keys(cd)
// Checking if there's a current continent defined, if is,
// then render only current continent, otherwise render the whole map
if (currentContinent) {
if (currentContinent === continent) {
return countriesPerContinent.map((country, index) => this.renderCountry(continent, country, index))
}
return null
}
if (continent === 'namerica') {
return countriesPerContinent.map((country, index) => this.renderCountry(continent, country, index))
}
return (
<AnimatedG opacity={this.animatedOpacityValue}>
{countriesPerContinent.map((country, index) => this.renderCountry(continent, country, index))}
</AnimatedG>
)
}
renderMap() {
const { currentContinent } = this.props
const continents = Object.keys(mapPathData)
const viewBox = VIEW_BOX[currentContinent] || VIEW_BOX.world // define viewBox either based on current continent or show the whole world
const svgProps = {
baseProfile: 'tiny',
x: '0px',
y: '0px',
viewBox: `${viewBox.minX} ${viewBox.minY} ${viewBox.width} ${viewBox.height}`,
fill: Colors.WHITE,
width: '100%',
height: scale(200),
}
return (
<Animated.View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
paddingHorizontal: scale(40),
transform: [
{
translateY: this.animatedYValue,
},
{
translateX: this.animatedXValue,
},
{
scale: this.animatedScaleValue,
},
],
}}
>
<Svg {...svgProps}>{continents.map(this.renderContinent)}</Svg>
</Animated.View>
)
}
render() {
return <View style={styles.container}>{this.renderMap()}</View>
}
}
const newStoreParams = {
state: {
visitedLocations: ['user', 'visitedLocations'],
},
}
export default withStore(WorldMap, newStoreParams)
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
paddingHorizontal: scale(40),
height: scale(200),
width: '100%',
backgroundColor: Colors.WHITE,
overflow: 'hidden',
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment