Компоненты/Карточка с переворотом

Карточка с переворотом

28 сентября 2026

Карточка переворачивается в ту сторону, с какой её коснулись, с бликом, лёгким наклоном и приподнимающейся тенью; на вебе — в сторону, откуда пришёл курсор.

Установка

npx astra-rn add direction-aware-flip-card
pnpm dlx astra-rn add direction-aware-flip-card
yarn dlx astra-rn add direction-aware-flip-card
bunx --bun astra-rn add direction-aware-flip-card

Файлы

index.tsx
НазадЦифровые часыДалееГруппа раскрытий

Карточка с двумя сторонами-картинками переворачивается в ту сторону, с которой её коснулись: тап по левой половине переворачивает влево, по правой — вправо. В вебе направление задаёт сторона, с которой зашёл курсор, а пока он над карточкой, она немного наклоняется вслед за ним, по поверхности скользит блик и тень становится глубже.

С клавиатуры в вебе карточка переворачивается пробелом или Enter. Переворот идёт на пружине в UI-потоке Reanimated; при «Уменьшении движения» наклон отключается, а переворот происходит мгновенно. Работает на iOS, Android и в вебе.

Вручную

Поставьте зависимости:

npm install react-native-gesture-handler react-native-reanimated react-native-svg
pnpm add react-native-gesture-handler react-native-reanimated react-native-svg
yarn add react-native-gesture-handler react-native-reanimated react-native-svg
bun add react-native-gesture-handler react-native-reanimated react-native-svg

Скопируйте эти файлы в src/shared/components/molecules/direction-aware-flip-card/:

Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.

Использование

import React from "react";
import { ScrollView, StyleSheet, View } from "react-native";
import { DirectionAwareFlipCard } from "@/shared/components/molecules/direction-aware-flip-card";
import { PHOTO_SOURCES } from "~/assets/photos";
import { Showcase, useCustomize } from "~/showcase";

const CUSTOMIZE = [
  { key: "width", label: "Ширина", type: "slider", min: 200, max: 480, step: 10, unit: "px", default: 360 },
  { key: "height", label: "Высота", type: "slider", min: 300, max: 760, step: 10, unit: "px", default: 620 },
  { key: "radius", label: "Скругление", type: "slider", min: 0, max: 48, step: 1, unit: "px", default: 12 },
  { key: "duration", label: "Длительность переворота", type: "slider", min: 0.15, max: 1.5, step: 0.05, unit: "с", default: 0.45 },
  { key: "frontSrc", label: "Лицевая сторона", type: "image", default: PHOTO_SOURCES["cinematic-carousel-2"] },
  { key: "backSrc", label: "Обратная сторона", type: "image", default: PHOTO_SOURCES["cinematic-carousel-4"] },
] as const;

export default function DirectionAwareFlipCardScreen() {
  const custom = useCustomize(CUSTOMIZE);

  return (
    <Showcase>
      <ScrollView contentContainerStyle={styles.stage}>
        <View style={styles.frame}>
          <DirectionAwareFlipCard
            frontSrc={custom.frontSrc}
            backSrc={custom.backSrc}
            width={custom.width}
            height={custom.height}
            radius={custom.radius}
            duration={custom.duration}
          />
        </View>
      </ScrollView>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  stage: {
    flexGrow: 1,
    alignItems: "center",
    justifyContent: "center",
    paddingVertical: 48,
  },
  frame: {
    width: "100%",
    alignItems: "center",
    justifyContent: "center",
  },
});

Пропсы

Пропс
Описание
frontSrc

Тип FlipCardImage

backSrc

Тип FlipCardImage

frontAlt?

Тип string

backAlt?

Тип string

width?

Тип number

height?

Тип number

radius?

Тип number

duration?

Тип number

style?

Тип StyleProp<ViewStyle>