import React, { useState, useEffect } from 'react';
import { ImageProps } from './interface';
import { Image as XrnImage } from '@xrnjs/image';
import {
ColorValue,
ImageErrorEventData,
ImageStyle,
StyleSheet,
} from 'react-native';
import { useMemoizedFn } from 'ahooks';
import { getStrObj, isSvgXml } from './utils';
import { NumberProp, SvgXml, XmlProps } from 'react-native-svg';
import { omitBy } from 'lodash';
const Image = (props: ImageProps) => {
const {
source,
tintColor,
onError,
onLoad,
style,
width,
height,
...restProps
} = props;
const [svg, setSvg] = useState('');
const fStyle = StyleSheet.flatten(style); // 数组转换为普通样式对象
const {
width: stWidth,
height: stHeight,
opacity,
} = (fStyle || {}) as ImageStyle;
const { width: sWidth, height: sHeight } = source as any ?? {};
// 权重 style > source > props
const finalW = stWidth ?? sWidth ?? width;
const finalH = stHeight ?? sHeight ?? height;
let svgProps: XmlProps = {
...restProps,
onError: onError as unknown as (error: Error) => void,
onLoad: onLoad as unknown as () => void,
style,
width: finalW as NumberProp,
height: finalH as NumberProp,
opacity: opacity as NumberProp,
xml: svg,
};
// 兼容问题处理
if (tintColor) {
svgProps = {
...svgProps,
fill: tintColor as ColorValue,
stroke: tintColor as ColorValue,
};
}
// 当源发生变化时,重置 svg 状态,确保重新加载并解析新图片
useEffect(() => {
setSvg('');
}, [source]);
const _onError = useMemoizedFn((errorData: ImageErrorEventData) => {
const errorInfo = getStrObj(errorData?.error);
// 二次校验数据,确保是svg数据
if (errorInfo?.isSvg && errorInfo?.data && isSvgXml(errorInfo?.data)) {
setSvg(errorInfo.data);
return;
}
setSvg('');
onError?.(errorData);
});
const size = omitBy(
{ width: finalW, height: finalH },
(v) => v === undefined
);
return svg ? (
) : (
);
};
export default Image;
// import { Image } from 'react-native';
// export default Image;