Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image组件使用expo-image的修改建议 #16510

Open
ShaoGongBra opened this issue Sep 12, 2024 · 0 comments
Open

Image组件使用expo-image的修改建议 #16510

ShaoGongBra opened this issue Sep 12, 2024 · 0 comments
Labels
F-react Framework - React T-rn Target - 编译到 React Native V-4 Version - 4.x

Comments

@ShaoGongBra
Copy link
Contributor

相关平台

React Native

使用框架: React

复现步骤

expo-image支持gif、svg等,不用再去封装svg,且svg也支持mode
expo-image的性能更好
expo-image支持小程序的更多的mode

这个patch是修改为expo-image,增加了heightFix的支持

diff --git a/node_modules/@tarojs/components-rn/dist/components/Image/index.js b/node_modules/@tarojs/components-rn/dist/components/Image/index.js
index bc2ae99..f5aa4a7 100644
--- a/node_modules/@tarojs/components-rn/dist/components/Image/index.js
+++ b/node_modules/@tarojs/components-rn/dist/components/Image/index.js
@@ -16,30 +16,20 @@
 import * as React from 'react';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import { Image, StyleSheet } from 'react-native';
+import { Image as ExpoImage } from 'expo-image';
 import { omit } from '../../utils';
 import useClickable from '../hooks/useClickable';
-// fix: https://github.com/facebook/metro/issues/836
-// 保证 react-native-svg 是最后一个依赖
 const omitProp = (props) => {
     return omit(props, ['source', 'src', 'resizeMode', 'onLoad', 'onError', 'onLayout', 'style']);
 };
 const resizeModeMap = {
-    scaleToFill: 'stretch',
+    scaleToFill: 'fill',
     aspectFit: 'contain',
     aspectFill: 'cover',
-    center: 'center',
+    center: 'none',
     // And widthFix
     // Not supported value...
 };
-let SvgCssUri, WithLocalSvg;
-// react-native-svg is optional
-try {
-    // eslint-disable-next-line @typescript-eslint/no-var-requires
-    const svg = require('react-native-svg');
-    SvgCssUri = svg.SvgCssUri;
-    WithLocalSvg = svg.WithLocalSvg;
-}
-catch (e) { }
 const _Image = (props = {
     src: '',
     mode: 'scaleToFill'
@@ -49,8 +39,9 @@ const _Image = (props = {
     });
     const [ratio, setRatio] = useState(0);
     const [layoutWidth, setLayoutWidth] = useState(0);
+    const [layoutHeight, setLayoutHeight] = useState(0);
     const newProps = useClickable(props);
-    const { style, src, mode = 'scaleToFill', svg = false, onLoad, onError } = newProps;
+    const { style, src, mode = 'scaleToFill', onLoad, onError } = newProps;
     const _onError = useCallback(() => {
         if (!onError)
             return;
@@ -81,12 +72,13 @@ const _Image = (props = {
         }
     }, [onLoad]);
     const onLayout = (event) => {
-        const { width: layoutWidth } = event.nativeEvent.layout;
+        const { width: layoutWidth, height: layoutHeight } = event.nativeEvent.layout;
         const flattenStyle = StyleSheet.flatten(style) || {};
         if (mode === 'widthFix' && typeof flattenStyle.width === 'string') {
             if (ref.current.hasLayout)
                 return;
             setLayoutWidth(layoutWidth);
+            setLayoutHeight(layoutHeight);
         }
         if (ratio) {
             ref.current.hasLayout = true;
@@ -117,19 +109,10 @@ const _Image = (props = {
     const flattenStyle = StyleSheet.flatten(style) || {};
     const defaultWidth = flattenStyle.width || 300;
     const defaultHeight = flattenStyle.height || 225;
-    // remote svg image support, svg 图片暂不支持 mode
-    const remoteSvgReg = /(https?:\/\/.*\.(?:svg|svgx))/i;
-    if (SvgCssUri && typeof src === 'string' && remoteSvgReg.test(src)) {
-        return (React.createElement(SvgCssUri, { uri: src, width: defaultWidth, height: defaultHeight }));
-    }
-    // The parameter passed to require mpxTransformust be a string literal
     const source = typeof src === 'string' ? { uri: src } : src;
-    // local svg image support, svg 图片暂不支持 mode
-    if (WithLocalSvg && svg) {
-        return (React.createElement(WithLocalSvg, { asset: source, width: defaultWidth, height: defaultHeight }));
-    }
     const isWidthFix = mode === 'widthFix';
-    const rMode = (resizeModeMap[mode] || (isWidthFix ? undefined : 'stretch'));
+    const isHeightFix = mode === 'heightFix';
+    const rMode = (resizeModeMap[mode] || (isWidthFix || isHeightFix ? undefined : 'fill'));
     const imageHeight = (() => {
         if (isWidthFix) {
             if (typeof flattenStyle.width === 'string') {
@@ -146,13 +129,27 @@ const _Image = (props = {
             return defaultHeight;
         }
     })();
+    const imageWidth = (() => {
+        if (isHeightFix) {
+            if (typeof flattenStyle.height === 'string') {
+                return layoutHeight / ratio;
+            }
+            else if (typeof flattenStyle.height === 'number') {
+                return flattenStyle.height / ratio;
+            }
+            else {
+                return 300 / ratio;
+            }
+        }
+        else {
+            return defaultWidth;
+        }
+    })();
     const restImageProps = omitProp(newProps);
-    return (React.createElement(Image, Object.assign({ testID: 'image', source: source, resizeMode: rMode, onError: _onError, onLoad: _onLoad, onLayout: onLayout, style: [
-            {
-                width: 300
-            },
+    return (React.createElement(ExpoImage, Object.assign({ testID: 'image', source: source, contentFit: rMode, onError: _onError, onLoad: _onLoad, onLayout: onLayout, style: [
             style,
             {
+                width: imageWidth,
                 height: imageHeight
             }
         ] }, restImageProps)));

期望结果

1

实际结果

2

环境信息

Taro CLI 4.0.5 environment info:
    System:
      OS: macOS 14.5
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 22.8.0 - /var/folders/rf/gd60z12164z72bny7z_0d4f80000gn/T/yarn--1726113057467-0.9620051471778583/node
      Yarn: 1.22.22 - /var/folders/rf/gd60z12164z72bny7z_0d4f80000gn/T/yarn--1726113057467-0.9620051471778583/yarn
      npm: 10.8.2 - ~/.nvm/versions/node/v22.8.0/bin/npm
    npmPackages:
      @tarojs/cli: 4.0.5 => 4.0.5 
      @tarojs/components: 4.0.5 => 4.0.5 
      @tarojs/helper: 4.0.5 => 4.0.5 
      @tarojs/plugin-framework-react: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-alipay: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-h5: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-jd: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-qq: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-swan: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-tt: 4.0.5 => 4.0.5 
      @tarojs/plugin-platform-weapp: 4.0.5 => 4.0.5 
      @tarojs/react: 4.0.5 => 4.0.5 
      @tarojs/rn-runner: 4.0.5 => 4.0.5 
      @tarojs/rn-supporter: 4.0.5 => 4.0.5 
      @tarojs/runtime: 4.0.5 => 4.0.5 
      @tarojs/shared: 4.0.5 => 4.0.5 
      @tarojs/taro: 4.0.5 => 4.0.5 
      @tarojs/taro-loader: 4.0.5 => 4.0.5 
      @tarojs/taro-rn: 4.0.5 => 4.0.5 
      @tarojs/webpack5-runner: 4.0.5 => 4.0.5 
      babel-preset-taro: 4.0.5 => 4.0.5 
      eslint-config-taro: 4.0.5 => 4.0.5 
      expo: ~51.0.32 => 51.0.32 
      react: ^18.2.0 => 18.3.1 
      react-native: ~0.75.3 => 0.75.3
@TheKonka TheKonka added F-react Framework - React T-rn Target - 编译到 React Native V-4 Version - 4.x labels Sep 12, 2024
This was referenced Sep 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-react Framework - React T-rn Target - 编译到 React Native V-4 Version - 4.x
Projects
None yet
Development

No branches or pull requests

2 participants