DylanVann / react-native-fast-image

🚩 FastImage, performant React Native image component.
MIT License
8.09k stars 1.48k forks source link

Animate in loaded images. #6

Open grundmanise opened 7 years ago

grundmanise commented 7 years ago

It would be great if an image appears with an animation when it loads.

DylanVann commented 7 years ago

I'm considering adding a couple more exports to this library to support common use cases. Potentially animate in and loading indication. I think for animate in it would just take a fadeInDuration prop and then fade in over that period of time. Default would be no fade. The export would be something like FastImageAnimated.

shinyford commented 6 years ago

Question for @DylanVann: images already seem to fade in once loaded on Android (with no way to switch that off?). Is that a Glide thing? And if so, is there a way to make the image appearance immediate, as with the iOS implementation?

belens commented 6 years ago

@DylanVann I have a fade animation for FastImage, you want it as a FastImageAnimated component? I can create a pull request.

yasir-netlinks commented 4 years ago

@belens hi there, could you share you code, Im looking on how to add the fade in animation on image load

timothystewart6 commented 4 years ago

I did it like this:


  state = {
    imageScaleValue: new Animated.Value(0),
  }

  onImageLoadEnd = () => {
    Animated.timing(this.state.imageScaleValue, {
      toValue: 1,
      duration: 150,
      delay: 5,
      useNativeDriver: true,
    }).start()
  }

 <Animated.View style={{ opacity: this.state.imageScaleValue }}>
              <FastImage
                    style={styles.image}
                    source={{
                      uri: item.imageUrl,
                      cache: FastImage.cacheControl.web,
                    }}
                    resizeMode={FastImage.resizeMode.contain}
                    onLoadEnd={() => this.onImageLoadEnd()}
                />
</Animated.View>

@yasir-netlinks Works great!

kickbk commented 2 years ago

The solution @timothystewart6 suggested works really well. An alternative option is to use a skeleton component, like from moti, and wrap FastImage like so:

import { Skeleton } from "@motify/skeleton"; // In version 17 it's imported directly from moti.

const [imageLoaded, setImageLoaded] = useState(false);
<Skeleton
  show={!imageLoaded}
  ...
>
  <FastImage
    ...
    onLoadEnd={() => setImageLoaded(true)}
  />
</Skeleton>

This has some benefits:

  1. rn-reanimated vs Animated
  2. The options that ship with Skeleton (like the wave animation, theme support, etc.)
  3. Possibly less verbose since the animation part is handled by Moti

The possible downside may be the extra dependency.

vlad-timotei commented 1 year ago

@kickbk here's a custom component that wraps FastImage and uses react-native-reanimated and implements fadeInDuration prop.

Thank you @timothystewart6 for the original idea


import React from 'react';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';
import FastImage, {FastImageProps} from 'react-native-fast-image';

interface AnimatedFastImageProps extends FastImageProps {
  fadeInDuration?: number;
}

const AnimatedFastImage: React.FC<AnimatedFastImageProps> = props => {
  const opacity = useSharedValue(0);
  const rStyles = useAnimatedStyle(() => ({
    opacity: opacity.value,
  }));

  const onLoadEnd = () => {
    opacity.value = withTiming(1, {
      duration: props.fadeInDuration || 300,
    });
  };

  return (
    <Animated.View style={rStyles}>
      <FastImage {...props} onLoadEnd={onLoadEnd} />
    </Animated.View>
  );
};

export default AnimatedFastImage;