Skip to content

Instantly share code, notes, and snippets.

@piaskowyk
Created January 16, 2025 18:25
Show Gist options
  • Save piaskowyk/b4f891151cd0e53f39f063c4b662f278 to your computer and use it in GitHub Desktop.
Save piaskowyk/b4f891151cd0e53f39f063c4b662f278 to your computer and use it in GitHub Desktop.
import React, { useState } from 'react';
import { Pressable, View } from 'react-native';
import Animated, { css } from 'react-native-reanimated';
export default function Wave() {
const [clickLocation, setClickLocation] = useState({ x: -1, y: -1 });
const dots = Array.from({ length: 323 });
const size = 19;
const color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`
return (
<View style={styles.container}>
{dots.map((_state, index) => (
<Dot
key={index}
position={{x: index % size, y: Math.floor(index / size)}}
onClick={setClickLocation}
clickLocation={clickLocation}
color={color}
/>
))}
</View>
);
}
function Dot(
{ position, onClick, clickLocation, color }:
{
position: {x: number, y: number},
clickLocation: { x: number, y: number },
onClick: (location: { x: number, y: number }) => void,
color: string
}
) {
const distance = Math.sqrt(
Math.pow(position.x - clickLocation?.x, 2) +
Math.pow(position.y - clickLocation?.y, 2)
);
const animation = {
animationTimingFunction: 'easeInOut',
animationDuration: 500,
animationDelay: distance * 100,
animationName: css.keyframes({
'0%,100%': {
transform: [{ scale: 1 }],
},
'50%': {
backgroundColor: color,
transform: [{ scale: 1.2 }],
},
}),
};
return (
<Pressable onPress={() => onClick(position)}>
<Animated.View
style={[
styles.dot,
{ backgroundColor: 'rgb(61, 67, 66)' },
clickLocation.x >= 0 ? animation as any : null,
]}
/>
</Pressable>
);
}
const styles = css.create({
container: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
alignItems: 'center',
},
dot: {
width: 15,
height: 15,
borderRadius: 10,
margin: 3,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment