UNPKG

@uiw/react-native

Version:
104 lines 2.73 kB
import React, { useRef, useState, useEffect } from 'react'; import { Animated, View, StyleSheet, Text } from 'react-native'; import { run } from './svg'; import Icon from '../Icon'; export default (props => { const { iconShow = false, progressShow = true, size = 25, xml = run, style, progress = 0, progressColor = '#108ee9', position, animation = { duration: 500 } } = props; const progWidth = useRef(new Animated.Value(0)).current; const [wrapWidth, setWrapWidth] = useState(0); useEffect(() => { if (wrapWidth && progress) { startAnimation(); } }, [wrapWidth, progress]); const startAnimation = () => { Animated.timing(progWidth, { toValue: getWidth(), duration: typeof animation !== 'boolean' ? animation.duration : 1000, useNativeDriver: false }).start(); }; const onLayout = e => { setWrapWidth(e.nativeEvent.layout.width); }; const getWidth = (percent = progress) => { return wrapWidth * (normalPercent(percent) / 100); }; const normalPercent = percent => { let widthPercent = 0; if (percent !== undefined && percent > 0) { widthPercent = percent > 100 ? 100 : percent; } return widthPercent; }; return <View style={[styles.container, style]}> <View onLayout={onLayout} style={[styles.pre, position === 'fixed' ? { position: 'absolute', top: 0 } : {}, { borderColor: progressColor, height: progressShow === true ? 20 : 4 }]}> {progressShow && progressShow === true && <View style={{ position: 'absolute', left: '45%', zIndex: 1000 }}> <Text style={{ fontSize: 12 }}>{progress}%</Text> </View>} <Animated.View style={[styles.preOisn, { width: progWidth, height: progressShow === true ? 20 : 4, backgroundColor: progressColor }]}></Animated.View> </View> {iconShow && iconShow === true && <View onLayout={onLayout} style={[styles.preIcon, { height: size }]}> <Animated.View style={{ marginLeft: progress === 0 ? -50 : progress === 100 ? -20 : -35, width: progWidth }}></Animated.View> <Icon xml={xml} size={size} /> </View>} </View>; }); const styles = StyleSheet.create({ container: { position: 'relative', flex: 1 }, pre: { borderWidth: 1, width: '100%', borderRadius: 20, marginBottom: 0, marginTop: 0, overflow: 'hidden' }, preIcon: { width: '100%', overflow: 'hidden', flexDirection: 'row', paddingHorizontal: 20 }, preOisn: { position: 'absolute', left: 0, top: 0 } });