Skip to content

EXAMPLE: react-native-skia #66

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions app/(app)/(authorized)/(tabs)/example/skia-components.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { SkiaComponentsScreen } from '@baca/screens'

export default SkiaComponentsScreen
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.17",
"@react-navigation/stack": "^6.3.20",
"@shopify/react-native-skia": "^1.3.6",
"@tanstack/react-query": "^4.29.19",
"axios": "^1.7.2",
"core-js": "^3.37.1",
Expand Down
78 changes: 78 additions & 0 deletions src/components/skia/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
Canvas,
LinearGradient,
Path,
Skia,
Text,
useFont,
useTouchHandler,
vec,
} from '@shopify/react-native-skia'
import { useEffect } from 'react'
import { useDerivedValue, useSharedValue, withTiming } from 'react-native-reanimated'

type ProgressBarProps = {
initialProgress: number
height?: number
width?: number
}

const FONT_SIZE = 24

export const ProgressBar = ({ height = 32, initialProgress, width = 200 }: ProgressBarProps) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const font = useFont(require('@baca/assets/fonts/Inter-Bold.ttf'), FONT_SIZE)

const path = Skia.Path.Make()
path.moveTo(0, height / 2)
path.lineTo(width, height / 2)

const progress = useSharedValue(0)

useEffect(() => {
progress.value = withTiming(initialProgress / 100, { duration: 1000 })
}, [initialProgress])

const onTouch = useTouchHandler({
onStart: ({ x }) => setNewProgress(x),
onActive: ({ x }) => setNewProgress(x),
})

const setNewProgress = (x: number) => {
let newProgress
if (x >= width) {
newProgress = 1
} else if (x <= 0) {
newProgress = 0
} else {
newProgress = x / width
}
progress.value = newProgress
}

const text = useDerivedValue(() => `${Math.floor(progress.value * 100)}%`)

const textX = useDerivedValue(() => {
const size = font?.measureText(text.value)?.width

return width / 2 - size! / 2
})

return (
<>
<Canvas style={{ height: FONT_SIZE + 12, width }}>
<Text x={textX} y={FONT_SIZE} text={text} font={font} />
</Canvas>
<Canvas style={{ height, width }} onTouch={onTouch}>
<Path color="black" path={path} style="stroke" strokeWidth={height} start={0} end={1} />
<Path color="red" path={path} style="stroke" strokeWidth={height} start={0} end={progress}>
<LinearGradient
start={vec(width, 0)}
end={vec(width, height)}
colors={['yellow', 'red']}
/>
</Path>
</Canvas>
</>
)
}
1 change: 1 addition & 0 deletions src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"go_to_screen_test_form": "Go to test form",
"go_to_screen_with_BEdata": "Go to screen with data from BE",
"go_to_settings": "Go to Settings",
"go_to_skia_components": "Go to skia components",
"go_to_typography": "Go to Typography",
"go_to_user_session": "Go to user session",
"header": "This is Example screen"
Expand Down
1 change: 1 addition & 0 deletions src/i18n/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"go_to_screen_test_form": "Idź do formularza testowego",
"go_to_screen_with_BEdata": "Idź do widoku z danymi z backend-u",
"go_to_settings": "Idź do Ustawień",
"go_to_skia_components": "Idź do Komponentów Skia",
"go_to_typography": "Idź do Typografii",
"go_to_user_session": "Idź do sesji użytkowania",
"header": "To jest przykładowy widok"
Expand Down
5 changes: 5 additions & 0 deletions src/screens/ExamplesScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const ExamplesScreen = () => {

const goToHomeStackDetails = useCallback(() => push('/home/details'), [push])

const goToSkiaComponents = useCallback(() => push('/example/skia-components'), [push])

return (
<ScrollView p={4}>
<Button mb={2} onPress={goToApplicationInfo}>
Expand Down Expand Up @@ -54,6 +56,9 @@ export const ExamplesScreen = () => {
<Button mb={2} onPress={goToUserSession}>
{t('examples_screen.go_to_user_session')}
</Button>
<Button mb={2} onPress={goToSkiaComponents}>
{t('examples_screen.go_to_skia_components')}
</Button>
</ScrollView>
)
}
18 changes: 18 additions & 0 deletions src/screens/SkiaComponentsScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ProgressBar } from '@baca/components/skia/ProgressBar'
import { StyleSheet, View } from 'react-native'

export const SkiaComponentsScreen = (): JSX.Element => {
return (
<View style={style.container}>
<ProgressBar initialProgress={50} />
</View>
)
}

const style = StyleSheet.create({
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
},
})
1 change: 1 addition & 0 deletions src/screens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './NotFoundScreen'
export * from './ProfileScreen'
export * from './PushNotificationsHelpersScreen'
export * from './SettingsScreen'
export * from './SkiaComponentsScreen'
export * from './TestFormScreen'
export * from './TypographyScreen'
export * from './UserSessionScreen'
35 changes: 35 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2645,6 +2645,14 @@
component-type "^1.2.1"
join-component "^1.1.0"

"@shopify/react-native-skia@^1.3.6":
version "1.3.6"
resolved "https://registry.yarnpkg.com/@shopify/react-native-skia/-/react-native-skia-1.3.6.tgz#074c419e87a1bfb65310b3ebfa74a342c2a07e06"
integrity sha512-AT+yxt0UiAakcqUzbaLCL4kj/9cDlerhuUw2z/U+K7xeudLcox6mbLse98i9E+fUdIctxNFa50ltCo+9hQOPkg==
dependencies:
canvaskit-wasm "0.39.1"
react-reconciler "0.27.0"

"@sideway/address@^4.1.5":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5"
Expand Down Expand Up @@ -3625,6 +3633,11 @@
"@webassemblyjs/ast" "1.12.1"
"@xtuc/long" "4.2.2"

"@webgpu/[email protected]":
version "0.1.21"
resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.21.tgz#b181202daec30d66ccd67264de23814cfd176d3a"
integrity sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==

"@welldone-software/why-did-you-render@^7.0.1":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@welldone-software/why-did-you-render/-/why-did-you-render-7.0.1.tgz#09f487d84844bd8e66435843c2e0305702e61efb"
Expand Down Expand Up @@ -4530,6 +4543,13 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz#4adcb443c8b9c8303e04498318f987616b8fea2e"
integrity sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==

[email protected]:
version "0.39.1"
resolved "https://registry.yarnpkg.com/canvaskit-wasm/-/canvaskit-wasm-0.39.1.tgz#c3c8f3962cbabbedf246f7bcf90e859013c7eae9"
integrity sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A==
dependencies:
"@webgpu/types" "0.1.21"

[email protected]:
version "5.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385"
Expand Down Expand Up @@ -11125,6 +11145,14 @@ [email protected]:
ws "^6.2.2"
yargs "^17.6.2"

[email protected]:
version "0.27.0"
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.27.0.tgz#360124fdf2d76447c7491ee5f0e04503ed9acf5b"
integrity sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.21.0"

react-refresh@^0.14.0, react-refresh@^0.14.2:
version "0.14.2"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
Expand Down Expand Up @@ -11584,6 +11612,13 @@ [email protected]:
dependencies:
loose-envify "^1.1.0"

scheduler@^0.21.0:
version "0.21.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820"
integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==
dependencies:
loose-envify "^1.1.0"

scheduler@^0.23.0, scheduler@^0.23.2:
version "0.23.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
Expand Down