UNPKG

react-native-animated-weather-icons-fork

Version:

This is a Fork from Animated Weather Icons for React Native from stan-sack & CurtisTD

344 lines (303 loc) 10.2 kB
import React from 'react' import PropTypes from 'prop-types' import { Animated, View, Easing } from 'react-native' import Svg, { Path } from 'react-native-svg' import transformUtil from '../utils/transformUtil' class SunCloudIcon extends React.Component { constructor(props) { super(props) this.handleBaseLayout = this.handleBaseLayout.bind(this) this.state = { growTimer: new Animated.Value(0.5), rayTimer: new Animated.Value(0), } this.animationLength = 4000 / props.speed this.growStages = [] this.growStages.push(Animated.timing( this.state.growTimer, { toValue: 1, duration: this.animationLength * 0.15, useNativeDriver: true, easing: Easing.bezier(0.2, 0.85, 0.4, 1.5) } )) this.growStages.push(Animated.timing( this.state.growTimer, { toValue: 1, duration: this.animationLength * 0.65, useNativeDriver: true, easing: Easing.bezier(0.2, 0.85, 0.4, 1.5) } )) this.growStages.push(Animated.timing( this.state.growTimer, { toValue: 0.5, duration: this.animationLength * 0.1, useNativeDriver: true, easing: Easing.bezier(0.2, 0.85, 0.4, 1.5) } )) this.growStages.push(Animated.timing( this.state.growTimer, { toValue: 0.5, duration: this.animationLength * 0.1, useNativeDriver: true, easing: Easing.bezier(0.2, 0.85, 0.4, 1.5) } )) this.state.rayOneScale = this.state.rayTimer.interpolate({ inputRange: [0, 0.1, 0.15, 0.8, 0.9, 1], outputRange: [0.5, 0.5, 1, 1, 0.5, 0.5], }) this.state.rayTwoScale = this.state.rayTimer.interpolate({ inputRange: [0, 0.15, 0.2, 0.8, 0.9, 1], outputRange: [0.5, 0.5, 1, 1, 0.5, 0.5], }) this.state.rayThreeScale = this.state.rayTimer.interpolate({ inputRange: [0, 0.2, 0.25, 0.8, 0.9, 1], outputRange: [0.5, 0.5, 1, 1, 0.5, 0.5], }) this.state.rayFourScale = this.state.rayTimer.interpolate({ inputRange: [0, 0.25, 0.3, 0.8, 0.9, 1], outputRange: [0.5, 0.5, 1, 1, 0.5, 0.5], }) this.state.rayFiveScale = this.state.rayTimer.interpolate({ inputRange: [0, 0.3, 0.35, 0.8, 0.9, 1], outputRange: [0.5, 0.5, 1, 1, 0.5, 0.5], }) } componentDidMount() { this.state.rayTimer.addListener(({ value }) => { this.flushRayTransforms( [ this.rayOneRef, this.rayTwoRef, this.rayThreeRef, this.rayFourRef, this.rayFiveRef ], [ this.state.rayOneScale, this.state.rayTwoScale, this.state.rayThreeScale, this.state.rayFourScale, this.state.rayFiveScale ] ) }) this.continueAnimation = true this.runAnimation() } componentWillUnmount() { this.continueAnimation = false this.state.rayTimer.removeAllListeners() } runAnimation() { this.state.growTimer.setValue(0.5) this.state.rayTimer.setValue(0) Animated.parallel([ Animated.sequence(this.growStages), Animated.timing( this.state.rayTimer, { toValue: 1, duration: this.animationLength, useNativeDriver: true, }, ) ]).start( () => { this.continueAnimation && this.runAnimation() } ) } flushRayTransforms(refs, scales) { if (!this.state.centreX) { return } let matrixes = scales.map(scale => transformUtil.scale(scale.__getValue(), scale.__getValue(), 1)) transformUtil.transformMutateReturn( matrixes[0], { x: -(19 / 25.5) * this.state.centreX, y: -(5 / 25.5) * this.state.centreY, z: 0 } ) transformUtil.transformMutateReturn( matrixes[1], { x: -(15 / 25.5) * this.state.centreX, y: -(15 / 25.5) * this.state.centreY, z: 0 } ) transformUtil.transformMutateReturn( matrixes[2], { x: -(5 / 25.5) * this.state.centreX, y: -(19.5 / 25.5) * this.state.centreY, z: 0 } ) transformUtil.transformMutateReturn( matrixes[3], { x: (5 / 25.5) * this.state.centreX, y: -(15 / 25.5) * this.state.centreY, z: 0 } ) transformUtil.transformMutateReturn( matrixes[4], { x: (9 / 25.5) * this.state.centreX, y: -(5 / 25.5) * this.state.centreY, z: 0 } ) refs.map((ref, i) => ref.setNativeProps({ style: { transform: [ { matrix: matrixes[i], }, ], }, })) } handleBaseLayout(e) { const layout = e.nativeEvent.layout this.setState({ centreX: layout.height / 2, centreY: layout.height / 2, }) } render() { return ( <View style={{ height: this.props.size, width: this.props.size }}> <View style={{ position: 'absolute' }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={ 'M400,256c-5.3,0-10.6,0.4-15.8,1.1c-16.8-22.8-39-40.5-64.2-51.7c-10.5-4.6-21.5-8.1\ -32.9-10.4c-10.1-2-20.5-3.1-31.1-3.1c-45.8,0-88.4,19.6-118.2,52.9c-3.5,3.9-6.9,\ 8-10,12.3c-5.2-0.8-10.5-1.1-15.8-1.1c-1.5,0-3,0-4.4,0.1C47.9,258.4,0,307.7,0,368c0,\ 61.8,50.2,112,112,112c13.7,0,27.1-2.5,39.7-7.3c29,25.2,65.8,39.3,104.3,39.3c38.5,0,\ 75.3-14.1,104.3-39.3c12.6,4.8,26,7.3,39.7,7.3c61.8,0,112-50.2,112-112S461.8,256,\ 400,256z M400,448c-17.1,0-32.9-5.5-45.9-14.7C330.6,461.6,295.6,480,256,480c-39.6,\ 0-74.6-18.4-98.1-46.7c-13,9.2-28.8,14.7-45.9,14.7c-44.2,0-80-35.8-80-80s35.8-80,\ 80-80c7.8,0,15.4,1.2,22.5,3.3c2.7,0.8,5.4,1.7,8,2.8c4.5-8.7,9.9-16.9,16.2-24.4C185,\ 241.9,216.8,224,256,224c10.1,0,20,1.2,29.4,3.5c10.6,2.5,20.7,6.4,30.1,11.4c23.2,\ 12.4,42.1,31.8,54.1,55.2c9.4-3.9,19.7-6.1,30.5-6.1c44.2,0,80,35.8,80,80S444.2,448,\ 400,448z' } /> </Svg> </View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS style={{ position: 'absolute', transform: [{ scale: this.state.growTimer }], opacity: this.state.growTimer.interpolate({ inputRange: [0.5, 1], outputRange: [0, 1], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M127.8,259.1c3.1-4.3,6.5-8.4,10-12.3c-6-11.2-9.4-24-9.4-37.7c0-44.1,35.7-79.8,\ 79.8-79.8c40,0,73.1,29.4,78.9,67.7c11.4,2.3,22.4,5.7,32.9,\ 10.4c-0.4-29.2-12-56.6-32.7-77.3C266.1,109,238,97.4,208.2,97.4c-29.9,0-57.9,\ 11.6-79.1,32.8c-21.1,21.1-32.8,49.2-32.8,79.1c0,17.2,3.9,33.9,11.2,48.9c1.5-0.1,\ 3-0.1,4.4-0.1C117.3,258,122.6,258.4,127.8,259.1z'} /> </Svg> </Animated.View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS ref={(ref) => { this.rayOneRef = ref }} onLayout={this.handleBaseLayout} style={{ position: 'absolute', opacity: this.state.rayTimer.interpolate({ inputRange: [0, 0.1, 0.15, 0.8, 0.9, 1], outputRange: [0, 0, 1, 1, 0, 0], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M16,224h32c8.8,0,16-7.2,16-16s-7.2-16-16-16H16c-8.8,0-16,7.2-16,16S7.2,224,16,224z'} /> </Svg> </Animated.View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS ref={(ref) => { this.rayTwoRef = ref }} onLayout={this.handleBaseLayout} style={{ position: 'absolute', opacity: this.state.rayTimer.interpolate({ inputRange: [0, 0.15, 0.2, 0.8, 0.9, 1], outputRange: [0, 0, 1, 1, 0, 0], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M83.5,106.2c6.3,6.2,16.4,6.2,22.6,0c6.3-6.2,6.3-16.4,0-22.6L83.5,\ 60.9c-6.2-6.2-16.4-6.2-22.6,0c-6.2,6.2-6.2,16.4,0,22.6L83.5,106.2z'} /> </Svg> </Animated.View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS ref={(ref) => { this.rayThreeRef = ref }} onLayout={this.handleBaseLayout} style={{ position: 'absolute', opacity: this.state.rayTimer.interpolate({ inputRange: [0, 0.2, 0.25, 0.8, 0.9, 1], outputRange: [0, 0, 1, 1, 0, 0], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M208,64c8.8,0,16-7.2,16-16V16c0-8.8-7.2-16-16-16s-16,7.2-16,16v32C195,56.8,\ 199.2,64,208,64z'} /> </Svg> </Animated.View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS ref={(ref) => { this.rayFourRef = ref }} onLayout={this.handleBaseLayout} style={{ position: 'absolute', opacity: this.state.rayTimer.interpolate({ inputRange: [0, 0.25, 0.3, 0.8, 0.9, 1], outputRange: [0, 0, 1, 1, 0, 0], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M332.4,106.2l22.6-22.6c6.2-6.2,6.2-16.4,0-22.6c-6.2-6.2-16.4-6.2-22.6,\ 0l-22.6,22.6c-6.2,6.2-6.2,16.4,0,22.6S326.2,112.4,332.4,106.2z'} /> </Svg> </Animated.View> <Animated.View renderToHardwareTextureAndroid shouldRasterizeIOS ref={(ref) => { this.rayFiveRef = ref }} onLayout={this.handleBaseLayout} style={{ position: 'absolute', opacity: this.state.rayTimer.interpolate({ inputRange: [0, 0.3, 0.35, 0.8, 0.9, 1], outputRange: [0, 0, 1, 1, 0, 0], }), }}> <Svg viewBox={'0 0 512 512'} height={this.props.size} width={this.props.size}> <Path fill={this.props.color} d={'M352,208c0,8.8,7.2,16,16,16h32c8.8,0,16-7.2,16-16s-7.2-16-16-16h-32C359.2,\ 195,352,199.2,352,208z'} /> </Svg> </Animated.View> </View> ) } } SunCloudIcon.propTypes = { size: PropTypes.number, speed: PropTypes.number, color: PropTypes.string } const SunCloudIconAnimated = Animated.createAnimatedComponent(SunCloudIcon) export default SunCloudIconAnimated