医学道
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
video/src/components/image/image.tsx

136 lines
3.7 KiB

import {FC, useEffect, useState} from "react";
import { Image, ImageProps, View } from "@tarojs/components";
import shard from '@/static/img/shard.png'
import Taro from "@tarojs/taro";
import avatar from '@/static/img/avatar.png'
import healthShard from '@/static/img/healthShard.png'
import professionShard from '@/static/img/professionShard.png'
import brandSecond from '@/static/img/brandSecond.png'
import courseShard from '@/static/img/courseShard.png'
import logo from '@/static/img/logo.svg'
interface Props extends ImageProps {
width?: number | string
height?: number | string
fallback?: string
errorType?: ImgErrType
loadingImage?: string
errorImage?: string
fit?: boolean // 当网络图片加载完成后高度自动
}
const Img: FC<Props> = ({src, mode = 'aspectFill', width, fallback = shard, ...props}) => {
const [isError, setIsError] = useState(false)
const [loading, setLoading] = useState(true)
const [errorUrl, setErrorUrl] = useState(fallback)
const [height, setHeight] = useState(props.height)
const imgAnimation = Taro.createAnimation({duration: 0}).opacity(0).step()
const [animationData, setAnimationData] = useState<TaroGeneral.IAnyObject>(imgAnimation.export())
console.log(height,'height')
console.log(loading,'loading')
useEffect(() => {
if (!isError && props.fit) {
Taro.getImageInfo({
src,
success() {
setHeight(undefined)
}
})
}
setIsError(!src)
setLoading(!!src)
}, [src])
useEffect(() => {
if (props.errorImage) {
setErrorUrl(props.errorImage)
return
}
switch (props.errorType) {
case undefined:
case "acquiesce":
setErrorUrl(fallback)
break
case "avatar":
setErrorUrl(avatar)
break
case 'health':
setErrorUrl(healthShard)
break
case 'profession':
setErrorUrl(professionShard)
break
case 'brand':
setErrorUrl(brandSecond)
break
case 'course':
setErrorUrl(courseShard)
break
}
}, [props.errorType])
// 图片加载失败
function onErrorHandler() {
setLoading(false)
setIsError(true)
}
function onLoadHandler() {
setLoading(false)
setIsError(false)
imgAnimation.opacity(1).step({duration: 200})
setAnimationData(imgAnimation.export())
}
return (
<View className={props?.className}
style={{
overflow: 'hidden',
width: width ? typeof width === 'string' ? width : `${width}rpx` : "100%",
height: height ? typeof height === 'string' ? height : `${height}rpx` : "100%",
backgroundColor: (isError || !loading) ? 'transparent' : '#F8F8F8',
}}>
{ loading &&
<View style={{width: "100%", height: '100%',display:'flex',justifyContent:'center',alignItems:'center'}}>
<Image
src={logo}
mode={"widthFix"}
style={{width: `100rpx`}}/>
</View>
}
{!isError &&
<View animation={animationData} style={{height: '100%', width: '100%'}}>
<Image
{...props}
src={src}
mode={mode}
lazyLoad
fadeIn
defaultSource={errorUrl}
style={{
width: width ? `${width}rpx` : "100%",
height: height ? `${height}rpx` : "100%",
verticalAlign: 'middle'
}}
onError={onErrorHandler}
onLoad={onLoadHandler}/>
</View>
}
{
isError && !loading &&
<Image
mode='aspectFill'
src={errorUrl}
lazyLoad
fadeIn
style={{width: "100%", height: '100%'}}/>
}
</View>
)
}
export default Img