Skip to content

Commit

Permalink
feat(image): add fast image pkg.
Browse files Browse the repository at this point in the history
  • Loading branch information
shangqunfeng committed Nov 5, 2024
1 parent c39bdd2 commit 6a7bd25
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 34 deletions.
4 changes: 4 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"react-native-gesture-handler": "^2.19.0",
"react-native-linear-gradient": "^2.8.3",
"react-native-safe-area-context": "^4.10.1",
"@d11/react-native-fast-image": "^8.8.0",
"react-native-webview": "^13.10.5",
"vue": "^2.7.10",
"vue-demi": "^0.14.6",
Expand Down Expand Up @@ -79,6 +80,9 @@
},
"react-native-linear-gradient": {
"optional": true
},
"@d11/react-native-fast-image": {
"optional": true
}
},
"publishConfig": {
Expand Down
20 changes: 11 additions & 9 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
import { SvgCssUri } from 'react-native-svg/css'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { SVG_REGEXP, useLayout, useTransformStyle } from './utils'
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage } from './utils'

export type Mode =
| 'scaleToFill'
Expand All @@ -51,6 +51,7 @@ export interface ImageProps {
'enable-offset'?: boolean;
'enable-var'?: boolean
'external-var-context'?: Record<string, any>
'enable-fast-image'?: boolean
'parent-font-size'?: number
'parent-width'?: number
'parent-height'?: number
Expand Down Expand Up @@ -100,6 +101,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
style = {},
'enable-var': enableVar,
'external-var-context': externalVarContext,
'enable-fast-image': enableFastImage,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight,
Expand Down Expand Up @@ -363,18 +365,18 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
...modeStyle
}}
/>
: <RNImage
source={{ uri: src }}
resizeMode={resizeMode}
onLoad={bindload && onImageLoad}
onError={binderror && onImageError}
style={{
: renderImage({
source: { uri: src },
resizeMode: resizeMode,
onLoad: bindload && onImageLoad,
onError: binderror && onImageError,
style: {
transformOrigin: 'top left',
width: isCropMode ? imageWidth : '100%',
height: isCropMode ? imageHeight : '100%',
...(isCropMode && modeStyle)
}}
/>
}
}, enableFastImage)
}
</View>
)
Expand Down
55 changes: 30 additions & 25 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* ✔ hover-start-time
* ✔ hover-stay-time
*/
import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent, Text } from 'react-native'
import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, Children, cloneElement } from 'react'
import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
import { useRef, useState, useEffect, forwardRef, ReactNode, JSX } from 'react'
import useInnerProps from './getInnerListeners'
import { ExtendedViewStyle } from './types/common'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils'
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage } from './utils'
import LinearGradient from 'react-native-linear-gradient'

export interface _ViewProps extends ViewProps {
Expand All @@ -20,6 +20,7 @@ export interface _ViewProps extends ViewProps {
'hover-stay-time'?: number
'enable-background'?: boolean
'enable-var'?: boolean
'enable-fast-image'?: boolean
'external-var-context'?: Record<string, any>
'parent-font-size'?: number
'parent-width'?: number
Expand Down Expand Up @@ -71,9 +72,11 @@ type PreImageInfo = {
type ImageProps = {
style: ImageStyle,
src?: string,
source?: {uri: string },
colors: Array<string>,
locations?: Array<number>
angle?: number
resizeMode?: 'cover' | 'stretch'
}

const linearMap = new Map([
Expand Down Expand Up @@ -114,17 +117,6 @@ const applyHandlers = (handlers: Handler[], args: any[]) => {
}
}

const normalizeStyle = (style: ExtendedViewStyle = {}) => {
['backgroundSize', 'backgroundPosition'].forEach(name => {
if (style[name] && typeof style[name] === 'string') {
if (style[name].trim()) {
style[name] = style[name].split(' ')
}
}
})
return style
}

const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && PERCENT_REGEX.test(val)

const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val)
Expand Down Expand Up @@ -275,7 +267,7 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
if (!dimensions) return
} else { // 数值类型 ImageStyle
// 数值类型设置为 stretch
(imageProps.style as ImageStyle).resizeMode = 'stretch'
imageProps.resizeMode = 'stretch'
dimensions = {
width: isPercent(width) ? width : +width,
height: isPercent(height) ? height : +height
Expand All @@ -291,8 +283,9 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima

// background-image转换为source
function backgroundImage (imageProps: ImageProps, preImageInfo: PreImageInfo) {
if (preImageInfo.src) {
imageProps.src = preImageInfo.src
const src = preImageInfo.src
if (src) {
imageProps.source = { uri: src }
}
}

Expand Down Expand Up @@ -321,8 +314,8 @@ function linearGradient (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) => {
// 初始化
const imageProps: ImageProps = {
resizeMode: 'cover',
style: {
resizeMode: 'cover' as ImageResizeMode,
position: 'absolute'
// ...StyleSheet.absoluteFillObject
},
Expand Down Expand Up @@ -512,7 +505,7 @@ function normalizeBackgroundSize (backgroundSize: Exclude<ExtendedViewStyle['bac
}

function preParseImage (imageStyle?: ExtendedViewStyle) {
const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = normalizeStyle(imageStyle) || {}
const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = imageStyle || {}
const { type, src, linearInfo } = parseBgImage(backgroundImage)

return {
Expand All @@ -528,7 +521,14 @@ function isDiagonalAngle (linearInfo?: LinearInfo): boolean {
return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction])
}

function wrapImage (imageStyle?: ExtendedViewStyle) {
function inheritStyle (innerStyle: Record<string, any> = {}) {
return ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'].reduce<Record<string, string>>((acc, key) => {
if (key in innerStyle) acc[key] = innerStyle[key] || 0
return acc
}, {})
}

function wrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<string, any>, enableFastImage?: boolean) {
// 预处理数据
const preImageInfo: PreImageInfo = preParseImage(imageStyle)
// 预解析
Expand Down Expand Up @@ -611,9 +611,9 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
}
}

return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
{show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
{show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
{show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size), enableFastImage) )}
</View>
}

Expand All @@ -624,9 +624,11 @@ interface WrapChildrenConfig {
backgroundStyle?: ExtendedViewStyle
varContext?: Record<string, any>
textProps?: Record<string, any>
innerStyle?: Record<string, any>
enableFastImage?: boolean
}

function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }: WrapChildrenConfig) {
function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }: WrapChildrenConfig) {
const children = wrapChildren(props, {
hasVarDec,
varContext,
Expand All @@ -635,7 +637,7 @@ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, tex
})

return [
enableBackground ? wrapImage(backgroundStyle) : null,
enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null,
children
]
}
Expand All @@ -650,6 +652,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
'enable-var': enableVar,
'external-var-context': externalVarContext,
'enable-background': enableBackground,
'enable-fast-image': enableFastImage,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight
Expand Down Expand Up @@ -777,7 +780,9 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
textStyle,
backgroundStyle,
varContext: varContextRef.current,
textProps
textProps,
innerStyle,
enableFastImage
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } fr
import { VarContext } from './context'
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
import { initialWindowMetrics } from 'react-native-safe-area-context'
import FastImage from '@d11/react-native-fast-image'

export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
Expand Down Expand Up @@ -523,3 +524,9 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
}
return children
}

export function renderImage (imageProps: Record<string, any>, enableFastImage = false) {
const Component = enableFastImage ? FastImage : Image
return <Component {...imageProps} />
}

1 change: 1 addition & 0 deletions packages/webpack-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
},
"devDependencies": {
"@ant-design/react-native": "^5.2.2",
"@d11/react-native-fast-image": "^8.8.0",
"@mpxjs/api-proxy": "^2.9.65",
"@types/babel-traverse": "^6.25.4",
"@types/babel-types": "^7.0.4",
Expand Down

0 comments on commit 6a7bd25

Please sign in to comment.