admin管理员组

文章数量:1122832

I need to implement an Animated.FlatList with animation, and I need to make the focused element on top of all the others. Using a FlatList, the subsequent element always overlaps the previous one.

I need that the image on the right goes behind the centred one.

This is what I've been doing so far:

import React from "react";
import {
  View,
  StyleSheet,
  Text,
  FlatList,
  Dimensions,
  Image,
} from "react-native";

import imagesElements from "../../config/imagesElements";
import Animated, {
  interpolate,
  useAnimatedScrollHandler,
  useAnimatedStyle,
  useSharedValue,
} from "react-native-reanimated";

const { width, height } = Dimensions.get("screen");

const _imageWidth = width * 0.7;
const _imageHeight = _imageWidth * 1.76;
const _spacing = 12;

const Photo = ({ item, index, scrollX }) => {
  const stylez = useAnimatedStyle(() => {
    return {
      transform: [
        {
          scale: interpolate(
            scrollX.value,
            [index - 1, index, index + 1],
            [0.9, 1, 0.9]
          ),
        },
        {
          rotate: \`${interpolate(
            scrollX.value,
            [index - 1, index, index + 1],
            [15, 0, -15]
          )}deg`,
        },
      ],
    };
  });

  const imageStylez = useAnimatedStyle(() => {
    return {
      opacity: interpolate(
        scrollX.value,
        [index - 1, index, index + 1],
        [0.3, 1, 0.3]
      ),
    };
  });

  const imageStylez2 = useAnimatedStyle(() => {
    return {
      zIndex: interpolate(
        scrollX.value,
        [index - 1, index, index + 1],
        [0, 1, 0]
      ),
    };
  });

return (
    <Animated.View
      style={[
        {
          width: _imageWidth,
          height: _imageHeight,
          borderRadius: 16,
          overflow: "hidden",
        },
        stylez,
        imageStylez2,
        {
          zIndex: interpolate(
            scrollX.value,
            [index - 1, index, index + 1],
            [0, 1, 0]
          ),
        },
      ]}
    >
      <Animated.Image
        source={item.uri}
        resizeMode="stretch"
        style={[{ width: "100%", height: "100%" }, imageStylez, imageStylez2]}
      />
    </Animated.View>
  );
};

const BackdropPhoto = ({ photo, index, scrollX }) => {
  const stylez = useAnimatedStyle(() => {
    return {
      opacity: interpolate(
        scrollX.value,
        [index - 1, index, index + 1],
        [0, 1, 0]
      ),
    };
  });
  return (
    <Animated.Image
      source={photo.uri}
      resizeMode="stretch"
      style={[
        StyleSheet.absoluteFill,
        { width: width, height: height },
        stylez,
      ]}
      blurRadius={50}
    />
  );
};

function PexelsWallpaper(props) {
  const scrollX = useSharedValue(0);
  const onScroll = useAnimatedScrollHandler((e) => {
    scrollX.value = e.contentOffset.x / (_imageWidth + _spacing);
  });

  return (
    <View style={styles.container}>
      <View style={StyleSheet.absoluteFill}>
        {imagesElements.imagesElements.map((photo, index) => (
          <BackdropPhoto photo={photo} index={index} scrollX={scrollX} />
        ))}
      </View>
      <Animated.FlatList
        data={imagesElements.imagesElements}
        keyExtractor={(item) => String(item.id)}
        horizontal
        style={{ flexGrow: 0 }}
        snapToInterval={_imageWidth + _spacing}
        decelerationRate={"fast"}
        contentContainerStyle={{
          gap: _spacing,
          paddingHorizontal: (width - _imageWidth) / 2,
        }}
        renderItem={({ item, index }) => {
          return <Photo item={item} index={index} scrollX={scrollX} />;
        }}
        onScroll={onScroll}
        scrollEventThrottle={1000 / 60}
        showsHorizontalScrollIndicator={false}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
});

export default PexelsWallpaper;

Any thoughts about this? Thanks

本文标签: transformApplying zIndex transorm useAnimatedStyle React nativeStack Overflow