Rotating Square
Four squares that rotates
Last updated on
Manual
Install the following dependencies:
npm install react-native-reanimated react-native-svgCopy and paste the following code into your project.
component/molecules/rotating-square
import React, { useEffect } from "react";import { View, StyleSheet, ViewStyle } from "react-native";import Animated, { useSharedValue, useAnimatedStyle, withRepeat, withTiming, Easing,} from "react-native-reanimated";import Svg, { Rect } from "react-native-svg";const AnimatedSvg = Animated.createAnimatedComponent(Svg);interface RotatingSquaresSpinnerProps { color?: string; squareSize?: number; spacing?: number; size?: number; duration?: number; repeatCount?: number; style?: ViewStyle;}export const RotatingSquaresSpinner: React.FC<RotatingSquaresSpinnerProps> = ({ color = "#FF5722", squareSize = 10, spacing = 20, size = 60, duration = 1000, repeatCount = -1, style,}) => { const rotation = useSharedValue<number>(0); useEffect(() => { rotation.value = withRepeat( withTiming(360, { duration, easing: Easing.linear, }), repeatCount, ); }, [duration, repeatCount]); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ rotate: `${rotation.value}deg` }], })); const half = size / 2; const offset = squareSize / 2; return ( <View style={[styles.container, style]}> <AnimatedSvg width={size} height={size} style={animatedStyle}> <Rect x={half - spacing - offset} y={half - spacing - offset} width={squareSize} height={squareSize} fill={color} /> <Rect x={half + spacing - offset} y={half - spacing - offset} width={squareSize} height={squareSize} fill={color} /> <Rect x={half - spacing - offset} y={half + spacing - offset} width={squareSize} height={squareSize} fill={color} /> <Rect x={half + spacing - offset} y={half + spacing - offset} width={squareSize} height={squareSize} fill={color} /> </AnimatedSvg> </View> );};const styles = StyleSheet.create({ container: { justifyContent: "center", alignItems: "center", },});Usage
import { View, Text, StyleSheet } from "react-native";import { GestureHandlerRootView } from "react-native-gesture-handler";import { StatusBar } from "expo-status-bar";import { useFonts } from "expo-font";import { SymbolView } from "expo-symbols";import { DisclosureGroup } from "@/components/molecules/disclosure-group";import DynamicText from "@/components/molecules/dynamic-text";import { DynamicTextItem } from "@/components/molecules/dynamic-text/types";import GooeyText from "@/components/molecules/gooey-text";import { CircleLoadingIndicator, OrbitDotLoader, PulsingDots, RotatingSquaresSpinner, SpinnerArc,} from "@/components";import { CircularLoader } from "@/components/molecules/Loaders/circular";export default function App() { const [fontLoaded] = useFonts({ SfProRounded: require("@/assets/fonts/sf-pro-rounded.ttf"), HelveticaNowDisplay: require("@/assets/fonts/HelveticaNowDisplayMedium.ttf"), }); const OPTIONS = [ { label: "Edit", icon: "pencil" }, { label: "Duplicate", icon: "doc.on.doc" }, { label: "Share", icon: "square.and.arrow.up" }, { label: "Delete", icon: "trash", destructive: true }, ]; const GOOEY_TEXTS: string[] = ["REACTICX", "IS", "AWESOME!"]; return ( <GestureHandlerRootView style={styles.container}> <StatusBar style="light" /> <View style={styles.content}> <RotatingSquaresSpinner spacing={12} color="#fff" /> </View> </GestureHandlerRootView> );}const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#0a0a0a", }, content: { paddingHorizontal: 20, paddingTop: 90, justifyContent: "center", alignItems: "center", gap: 0, }, title: { fontSize: 28, fontWeight: "700", color: "#fff", }, subtitle: { fontSize: 15, color: "#555", }, card: { backgroundColor: "#141414", borderRadius: 16, overflow: "hidden", marginTop: 20, }, triggerContent: { padding: 16, }, triggerLeft: { flexDirection: "row", alignItems: "center", gap: 12, }, triggerText: { fontSize: 16, fontWeight: "500", color: "#fff", }, item: { flexDirection: "row", alignItems: "center", gap: 12, padding: 14, backgroundColor: "#1a1a1a", borderRadius: 12, marginBottom: 6, }, itemText: { fontSize: 15, color: "#fff", }, destructiveText: { color: "#ff453a", },});Props
React Native Reanimated
React Native Svg
