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

Кластер аватаров

Pro
28 сентября 2026

Аватары влетают из размытого переднего плана и собираются в медленно вращающуюся розетку для любого числа участников.

Установка

import { useEffect, useMemo } from "react";
import Animated, { useSharedValue } from "react-native-reanimated";
import { StyleSheet, View } from "react-native";

Установка через CLIPro

Команда станет доступна после оформления Pro.

Оформить ProВойти

Файлы

index.tsx
НазадASCII-рендерДалееСтопка аватаров

Аватары участников по очереди влетают из-за края кадра — крупные, размытые и повёрнутые — и пружинно встают на свои места по кругу. В раскладке «розетка» первый аватар становится центральным, и по нему периодически пробегает блик. Когда группа собрана, кольцо начинает медленно вращаться, а сами аватары остаются ровными.

Радиус кольца подбирается под число участников и размер аватаров, а сам компонент ужимается под ширину контейнера. Анимацию можно повторить, сменив replayKey, или включить автоповтор. При «Уменьшении движения» аватары просто проявляются на местах без полёта и вращения. Работает на iOS, Android и в вебе.

Вручную

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

npm install expo-linear-gradient react-native-reanimated
pnpm add expo-linear-gradient react-native-reanimated
yarn add expo-linear-gradient react-native-reanimated
bun add expo-linear-gradient react-native-reanimated

Скопируйте эти файлы в src/shared/components/molecules/avatar-cluster/:

index.tsx
import { useEffect, useMemo } from "react";
import Animated, { useSharedValue } from "react-native-reanimated";
import { StyleSheet, View } from "react-native";
// Полный исходник открывается с подпиской Pro
export interface AvatarClusterProps {
speed?: number;
intensity?: number;
palette?: "aurora" | "mono";
interactive?: boolean;
}
export function AvatarCluster({
speed = 1,
intensity = 0.6,
interactive = true,
}: AvatarClusterProps) {
const progress = useSharedValue(0);
const frame = useMemo(() => createFrame(speed), [speed]);
useEffect(() => {
// …

Код доступен по подпискеPro

Исходник «Кластер аватаров» открывается с подпиской Pro. Уже оформили? Войдите в аккаунт.

Оформить ProВойти

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

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

usage.tsx
import { useEffect, useMemo } from "react";
import Animated, { useSharedValue } from "react-native-reanimated";
import { StyleSheet, View } from "react-native";
// Полный исходник открывается с подпиской Pro
export interface AvatarClusterProps {
speed?: number;
intensity?: number;
palette?: "aurora" | "mono";
interactive?: boolean;
}
export function AvatarCluster({
speed = 1,
intensity = 0.6,
interactive = true,
}: AvatarClusterProps) {
const progress = useSharedValue(0);
const frame = useMemo(() => createFrame(speed), [speed]);
useEffect(() => {
// …

Код доступен по подпискеPro

Исходник «Кластер аватаров» открывается с подпиской Pro. Уже оформили? Войдите в аккаунт.

Оформить ProВойти

images принимает адреса, require(...) или объекты { src, alt }.

Пропсы

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

Тип readonly (TAvatarSource | IAvatarClusterImage)[]

layout?

Тип "rosette" | "ring"

size?

Тип number

avatarSize?

Тип number

ringRadius?

Тип number

overlap?

Тип number

centerGap?

Тип number

centerScale?

Тип number

startAngle?

Тип number

scatterSpread?

Тип number

scatterSeed?

Тип number

scatterBlur?

Тип number

scatterScale?

Тип number

scatterOpacity?

Тип number

spring?

Тип IAvatarClusterSpring

stagger?

Тип number

delay?

Тип number

orbit?

Тип number | false

glare?

Тип boolean

autoReplay?

Тип number | false

replayKey?

Тип Key

ringColor?

Тип string

children?

Тип ReactNode

style?

Тип StyleProp<ViewStyle>