Skip to content

Instantly share code, notes, and snippets.

@syaau
Last active January 31, 2024 03:31
Show Gist options
  • Save syaau/ea8dcf1541276aef70aae0d68ef6f8b7 to your computer and use it in GitHub Desktop.
Save syaau/ea8dcf1541276aef70aae0d68ef6f8b7 to your computer and use it in GitHub Desktop.
Demo Canvas App to re-render multple times which uses the UI thread completely in few seconds.
import React, { useEffect, useState } from 'react';
import { Canvas, RoundedRect } from '@shopify/react-native-skia';
import { useSharedValue, withRepeat, withSequence, withTiming } from "react-native-reanimated";
import { Dimensions } from 'react-native';
// Number of cards to render
const items = 50;
// Array of cards with unique id
const cards = new Array(items).fill(null).map((_, idx) => `k-${idx}`)
export function CanvasApp() {
const [allCards, setCards] = useState(cards);
useEffect(() => {
// Sort the cards randomly in high frequency to change the
// order, and trigger render
setInterval(() => {
const newCards = cards.slice(0);
newCards.sort(() => Math.random() - 0.5);
setCards(newCards);
}, 100);
}, []);
return (
<Canvas style={{flex: 1}} renderToHardwareTextureAndroid shouldRasterizeIOS>
{allCards.map((k, idx) => <Card key={k} />)}
{/* {allCards.map((k) => <RoundedRect key={k} x={0} y={0} width={70} height={120} color='red' r={4} />)} */}
</Canvas>
)
}
let { width, height } = Dimensions.get('screen');
width = width - 70;
height = height - 120;
/**
* A card component rendered a simple RoundedRect canvas shape. An animation has
* been played just to make the things look playful.
* @returns
*/
export function Card() {
const [color] = useState(Math.floor((Math.random() * 0xffffff)) + 0xff000000);
const x = useSharedValue(Math.random() * width)
const y = useSharedValue(Math.random() * height);
useEffect(() => {
const speed = 0.1 + (Math.random()) / 10;
const widthDuration = width / speed;
const heightDuration = height / speed;
const toX = x.value > width / 2 ? 1 : 0;
const toY = y.value > height / 2 ? 1 : 0;
const xDuration = Math.abs(toX - x.value) / speed;
const yDuration = Math.abs(toY - y.value) / speed;
x.value = withSequence(withTiming(toX * width, { duration: xDuration }), withRepeat(
withSequence(
withTiming((1 - toX) * width, { duration: widthDuration }),
withTiming(toX * width, { duration: widthDuration })
), -1
));
y.value = withSequence(withTiming(toY * height, { duration: yDuration }), withRepeat(
withSequence(
withTiming((1 - toY) * height , { duration: heightDuration }),
withTiming(toY * height, { duration: heightDuration })
), -1
));
}, [])
return (
<RoundedRect x={x} y={y} width={70} height={120} color={color} r={4}/>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment