import React, { useRef, useState } from 'react'; import type { NativeSyntheticEvent, ImageLoadEventData, ImageErrorEventData } from 'react-native'; import { View, Text, Animated, TouchableOpacity, Platform } from 'react-native'; import Icon from '@pingtou/rn-vant-icons'; import type { ImageProps } from './type'; import createStyles from './style'; import { useTheme } from '../Theme'; /** * Image 图片 * 参考代码:https://github.com/HandlebarLabs/react-native-examples-and-tutorials/blob/master/tutorials/progressive-image-loading/ProgressiveImage.js * @description 增强版的 img 标签,提供多种图片填充模式,支持图片懒加载、加载中提示、加载失败提示。 */ const Image = (props: ImageProps): JSX.Element => { const { imageStyle, style, onLoad, onError, onPress, alt, radius = 0, round, loading, showError = true, showLoading = true, animated = true, duration = 200, fadeDuration = 0, children, ...resetProps } = props; const [isLoaded, setIsLoaded] = useState(false); const [isError, setIsError] = useState(false); const ImageAnimated = useRef(new Animated.Value(0)).current; const theme = useTheme(); const Styles = React.useMemo( () => createStyles(theme, { round, radius, }), [round, radius, theme] ); /** * 图片加载好了 */ const onLoadImage = (event: NativeSyntheticEvent) => { setIsLoaded(true); Animated.timing(ImageAnimated, { toValue: 1, duration: animated ? duration : 0, useNativeDriver: Platform.OS !== 'web', }).start(); onLoad && onLoad(event); }; /** * 图片加载失败 */ const onErrorImage = (event: NativeSyntheticEvent) => { setIsLoaded(true); setIsError(true); onError && onError(event); }; // 是否展示 loading const _showLoading = !isLoaded && showLoading; // 是否展示 error const _showError = isError && showError; // 是否展示背景颜色 const _showBackground = _showLoading || _showError; return ( {_showLoading && ( {loading || ( )} )} {_showError && ( {alt ? ( {alt} ) : ( )} )} {children} ); }; export default Image;