Компоненты/Радарный луч

Радарный луч

28 сентября 2026

Радар со светящимся лучом, который подсвечивает отметки при проходе и оставляет расходящиеся кольца.

Установка

npx astra-rn add radar-sweep
pnpm dlx astra-rn add radar-sweep
yarn dlx astra-rn add radar-sweep
bunx --bun astra-rn add radar-sweep

Файлы

index.tsx
НазадQR-кодДалееРадиальная схема

Круглый экран радара с кольцами, перекрестием и делениями по краю. По кругу непрерывно идёт луч с мягким веерным шлейфом, и каждая отметка, над которой он проходит, вспыхивает, выпускает кольцо и медленно гаснет до следующего оборота.

Радар рисуется в Skia, угол луча считается на UI-потоке Reanimated, размер подстраивается под ширину контейнера. Анимация останавливается, когда приложение свёрнуто или передан paused, а при «Уменьшении движения» показывается статичный кадр с подсвеченными отметками. Работает на iOS, Android и в вебе.

Вручную

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

npm install @shopify/react-native-skia react-native-reanimated
pnpm add @shopify/react-native-skia react-native-reanimated
yarn add @shopify/react-native-skia react-native-reanimated
bun add @shopify/react-native-skia react-native-reanimated

Скопируйте эти файлы в src/shared/components/organisms/radar-sweep/:

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

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

import React from "react";
import { StyleSheet, View } from "react-native";
import { DEFAULT_BLIPS, RadarSweep } from "@/shared/components/organisms/radar-sweep";
import { Showcase, useCustomize } from "~/showcase";

const BRAND = "#66d9e8";

const CUSTOMIZE = [
  { key: "speed", label: "Скорость луча", type: "slider", min: 0.2, max: 5, step: 0.1, default: 1.4 },
  { key: "rings", label: "Кольца", type: "slider", min: 1, max: 8, step: 1, default: 3 },
  { key: "blips", label: "Отметок", type: "slider", min: 0, max: 6, step: 1, default: 6 },
  { key: "trail", label: "Длина шлейфа", type: "slider", min: 0.05, max: 0.9, step: 0.01, default: 0.28 },
  { key: "trailOpacity", label: "Яркость шлейфа", type: "slider", min: 0.05, max: 0.8, step: 0.01, default: 0.26 },
  { key: "color", label: "Цвет луча", type: "color", default: BRAND },
  { key: "size", label: "Размер радара", type: "slider", min: 200, max: 560, step: 4, unit: "px", default: 384 },
] as const;

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

  return (
    <Showcase>
      <View style={styles.container}>
        <View style={[styles.stage, { maxWidth: custom.size }]}>
          <RadarSweep
            blips={DEFAULT_BLIPS.slice(0, custom.blips)}
            speed={custom.speed}
            rings={custom.rings}
            trail={custom.trail}
            trailOpacity={custom.trailOpacity}
            color={custom.color}
          />
        </View>
      </View>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#0a0a0a",
    alignItems: "center",
    justifyContent: "center",
    paddingHorizontal: 20,
    paddingVertical: 24,
  },
  stage: {
    width: "100%",
  },
});

Отметки задаются углом в градусах и расстоянием от центра от 0 до 1.

Пропсы

Пропс
Описание
blips?

Тип readonly RadarBlip[]

color?

Тип string

speed?

Тип number

rings?

Тип number

trail?

Тип number

trailOpacity?

Тип number

paused?

Тип boolean

style?

Тип StyleProp<ViewStyle>