Skip to content

Instantly share code, notes, and snippets.

@flunder
Created September 4, 2023 09:24
Show Gist options
  • Save flunder/c88b2dfeb933f860f98d106f9ff57fb4 to your computer and use it in GitHub Desktop.
Save flunder/c88b2dfeb933f860f98d106f9ff57fb4 to your computer and use it in GitHub Desktop.
Ticket MelonEmitter Code ( React Native )
import React, { useRef, useEffect, useCallback } from 'react';
import { Animated, Easing } from 'react-native';
import { pickOne } from '@t/utils/pickOne';
import { MelonHalf, MelonQuarter } from '@t/components/Icons';
const MelonEmitter = ({ runAnimation }) => {
const numberOfMelons = 20;
const driver = useRef(new Animated.Value(0)).current;
const colors = useRef(['#FFA0B4', '#F1DBDF', '#FFE4E9', '#BCFF4F']).current;
const svgs = [MelonQuarter, MelonHalf];
const melons = useRef(
[...Array(numberOfMelons)].map((m) => ({
ref: useRef(),
scale: 0.75,
height: Math.random() * 400 + 150,
rotation: Math.random() * 80 - 40,
angle: Math.random() * 100 - 50,
color: pickOne(colors),
component: pickOne(svgs),
}))
);
useEffect(() => {
driver.addListener(({ value }) => {
melons.current.map((m) =>
animateMelon(m.ref, value, m.height, m.scale, m.rotation, m.angle)
);
});
}, []);
useEffect(() => {
if (!runAnimation) return;
melons.current = melons.current.map((m) => ({
ref: m.ref,
scale: 0.75,
height: Math.random() * 400 + 150,
rotation: Math.random() * 80 - 40,
angle: Math.random() * 100 - 50,
color: pickOne(colors),
component: pickOne(svgs),
}));
driver.setValue(0);
Animated.timing(driver, {
toValue: Math.PI,
duration: 2000,
easing: Easing.ease,
useNativeDriver: true,
}).start();
}, [runAnimation]);
const animateMelon = useCallback(
(melonRef, driverValue, heightVal, scaleVal, rotateVal, angle) => {
if (!melonRef?.current) return;
const translateY = -Math.sin(driverValue * 1) * heightVal;
const translateX = driverValue * angle;
const scale = scaleVal;
const rotation = driverValue * rotateVal;
melonRef.current.setNativeProps({
transform: [
{ translateX },
{ translateY },
{ scale },
{ rotate: `${rotation} deg` },
],
});
},
[]
);
return (
<>
{melons.current.map((melon, i) => {
const Component = melon.component;
return (
<Animated.View
ref={melon.ref}
key={i}
style={{ position: 'absolute', top: 450 }}
>
<Component scale={0.5} fill={melon.color} />
</Animated.View>
);
})}
</>
);
};
export { MelonEmitter };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment