Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(balloons): improving balloons performance #32

Merged
merged 3 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/src/components/Examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function Examples() {
style={styles.pressable}
>
<Canvas style={styles.canvas}>
<Balloon x={50} y={50} color={'blue'} depth={0.4} />
<Balloon x={50} y={50} depth={0.4} autoPlay={false} />
</Canvas>
<Text style={[styles.pressableText, styles.textColor]}>
Balloons (using Fiesta context)
Expand Down
109 changes: 58 additions & 51 deletions src/components/Balloon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,84 @@ import {
Group,
Oval,
Path,
Shadow,
processTransform2d,
useComputedValue,
useTiming,
Easing,
useSpring,
} from '@shopify/react-native-skia';
import { baseColors } from '../constants/theming';
import { singleItemFadeSpeed } from '../constants/speed';

export interface BalloonProps {
x?: number;
y?: number;
color?: string;
r?: number;
depth?: number;
autoPlay?: boolean;
}

export const Balloon = memo(
({ x = 0, y = 0, color = 'blue', r = 40, depth = 1 }: BalloonProps) => {
const stringRotation = useTiming({
to: 0.05,
from: -0.05,
yoyo: true,
loop: true,
});
({
x = 0,
y = 0,
color = '#A555EC',
r = 40,
depth = 1,
autoPlay = true,
}: BalloonProps) => {
const opacity = useSpring(
{ to: autoPlay ? 0 : 1, from: 1 },
singleItemFadeSpeed
);

const stringRotation = useTiming(
{
to: 0.05,
from: -0.05,
yoyo: true,
loop: true,
},
{ easing: Easing.linear }
);

const stringRotationTransform = useComputedValue(
() => [
{
rotate: stringRotation.current,
},
],
[stringRotation]
const matrix = useComputedValue(
() =>
processTransform2d([
{ scale: depth },
{ translateX: x },
{ translateY: y },
{ rotate: stringRotation.current },
]),
[stringRotation, x, y, depth, opacity]
);

return (
// @TODO: this can be optimised by using a matrix instead of multiple transforms
<Group transform={[{ scale: depth }]}>
<Group transform={[{ translateX: x }]}>
<Group
transform={[
{
translateY: y,
},
]}
>
<Group transform={stringRotationTransform}>
<Group transform={[{ translateX: -55 }]}>
<Path
path={`M 100 22 C 90 10, 110 80, 100 100 S 100 170, 100 150`}
color={baseColors.golden}
style="stroke"
strokeJoin="round"
strokeWidth={5}
/>
</Group>
</Group>
<Group matrix={matrix} opacity={opacity}>
<Path
path={`M 100 22 C 90 10, 110 80, 100 100 S 100 170, 100 150`}
color={baseColors.golden}
style="stroke"
strokeJoin="round"
strokeWidth={5}
transform={[{ translateX: -55 }]}
/>

<Group transform={[{ translateY: -50 }]}>
<Group>
<Oval height={r * 2.3} width={r * 2} color={color} />
<Shadow dx={-12} dy={-12} blur={40} color="#fff" inner />
</Group>
</Group>
<Oval
height={r * 2.3}
width={r * 2}
color={color}
transform={[{ translateY: -50 }]}
/>

<Circle
cx={r / 0.8}
cy={-25}
r={r / 4}
color={baseColors.gray}
opacity={0.3}
/>
</Group>
</Group>
<Circle
cx={r / 0.8}
cy={-25}
r={r / 4}
color={baseColors.gray}
opacity={0.3}
/>
</Group>
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Confettis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const Confettis = memo(
numberOfConfettis = optimalNumberOfConfettis,
duration = DEFAULT_ANIMATION_DURATION,
}: ConfettisProps) => {
const [displayConfettis, setDisplayConfettis] = useState(true);
const [displayCanvas, setDisplayCanvas] = useState(true);

const confettisToRender = useMemo(
() => [...Array(numberOfConfettis)],
Expand All @@ -47,13 +47,13 @@ export const Confettis = memo(
// Hide confettis after the animation is done
useEffect(() => {
const timeout = setTimeout(() => {
setDisplayConfettis(false);
setDisplayCanvas(false);
}, duration * 1.5);

return () => clearTimeout(timeout);
}, [duration]);

if (!displayConfettis) return null;
if (!displayCanvas) return null;

return (
<Canvas style={styles.canvas} pointerEvents="none">
Expand Down