Skip to content
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
20 changes: 20 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const fontStyle = {
const font = matchFont(fontStyle)

function CanvasContent() {
const { width, height } = useCanvasSize()
const {
size: { width, height },
} = useCanvasSize()

const label = `${Math.round(width)} × ${Math.round(height)}`
const textX = width / 2 - (font?.getTextWidth(label) ?? 0) / 2
Expand Down
4 changes: 3 additions & 1 deletion evals/skia/08-rn-skia-text-rendering/reference/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const font = matchFont(fontStyle)
const LABEL = 'Hello, Skia!'

function CenteredText() {
const { width, height } = useCanvasSize()
const {
size: { width, height },
} = useCanvasSize()
const textWidth = font?.getTextWidth(LABEL) ?? 0
const x = (width - textWidth) / 2
const y = height / 2 + FONT_SIZE / 2
Expand Down
2 changes: 1 addition & 1 deletion evals/skia/16-rn-skia-clip-rect-and-path/prompt.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Demonstrate two clipping techniques on a Skia canvas: use ClipRect to restrict a gradient fill to a rectangular region, and use ClipPath to clip a solid-color rectangle to a non-rectangular polygon or star shape defined by an SVG path string.
Demonstrate two clipping techniques on a Skia canvas using the `clip` prop on `Group`: clip a gradient fill to a rectangular region, and clip a solid-color rectangle to a non-rectangular polygon or star shape defined by an SVG path string.
13 changes: 5 additions & 8 deletions evals/skia/16-rn-skia-clip-rect-and-path/reference/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {
Canvas,
ClipPath,
ClipRect,
Fill,
Group,
LinearGradient,
Rect,
Skia,
rect,
vec,
} from '@shopify/react-native-skia'

Expand All @@ -19,9 +18,8 @@ export default function App() {
<Canvas style={{ flex: 1 }}>
<Fill color="#0f172a" />

{/* ClipRect: restrict a gradient to a rectangle */}
<Group>
<ClipRect rect={{ x: 20, y: 60, width: 200, height: 140 }} />
{/* Clip a gradient to a rectangular region via Group's clip prop */}
<Group clip={rect(20, 60, 200, 140)}>
<Rect x={0} y={0} width={320} height={320} color="transparent">
<LinearGradient
start={vec(0, 60)}
Expand All @@ -31,9 +29,8 @@ export default function App() {
</Rect>
</Group>

{/* ClipPath: clip a solid block to a star shape */}
<Group>
<ClipPath path={starPath} />
{/* Clip a solid block to a star shape via Group's clip prop */}
<Group clip={starPath}>
<Rect x={0} y={240} width={320} height={320} color="#38bdf8" />
</Group>
</Canvas>
Expand Down
8 changes: 4 additions & 4 deletions evals/skia/16-rn-skia-clip-rect-and-path/requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ requirements:
description: Must render all drawing content inside a Canvas component from @shopify/react-native-skia.
weight: 0.1
- id: uses-clip-rect
description: Must use the ClipRect component from @shopify/react-native-skia to clip a drawing to a rectangular region.
description: Must use the `clip` prop on a Group component with a rectangle (e.g. from `rect()` or an `{ x, y, width, height }` object) to clip a drawing to a rectangular region.
- id: uses-clip-path
description: Must use the ClipPath component from @shopify/react-native-skia with a path or SVG path string.
description: Must use the `clip` prop on a Group component with a path (an SkPath or SVG path string) to clip a drawing to a non-rectangular shape.
- id: clip-path-is-non-rectangular
description: The ClipPath shape must be a non-rectangular polygon, star, or curve — not just a simple rectangle.
description: The path-based clip shape must be a non-rectangular polygon, star, or curve — not just a simple rectangle.
- id: both-clips-applied-to-distinct-drawings
description: ClipRect and ClipPath must each be applied to a different visual element so both clipping techniques are demonstrated independently.
description: The rectangular clip and the path clip must each be applied to a different visual element (separate Group components) so both clipping techniques are demonstrated independently.
4 changes: 2 additions & 2 deletions evals/skia/24-rn-skia-picture-save-restore/reference/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function App() {
paint.setColor(Skia.Color(FIRST_RECT_COLOR))
canvas.save()
canvas.translate(CX, 90)
canvas.rotate(FIRST_RECT_ROTATION_DEG)
canvas.rotate(FIRST_RECT_ROTATION_DEG, 0, 0)
canvas.drawRect(
{
x: -RECT_WIDTH / 2,
Expand All @@ -41,7 +41,7 @@ export default function App() {
paint.setColor(Skia.Color(THIRD_RECT_COLOR))
canvas.save()
canvas.translate(CX, 230)
canvas.rotate(THIRD_RECT_ROTATION_DEG)
canvas.rotate(THIRD_RECT_ROTATION_DEG, 0, 0)
canvas.drawRect(
{
x: -RECT_WIDTH / 2,
Expand Down
4 changes: 2 additions & 2 deletions evals/skia/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ React Native Skia evals — testing how well LLMs implement high-performance 2D
| 10 | Capture canvas output with `makeImageSnapshot()` via `useCanvasRef`; call `encodeToBytes()` for raw pixel data | canvas/overview |
| 11 | Use `matchFont` with a `fontStyle` object for system font resolution; the Text `y` origin is the text baseline, not the top | text/text |
| 12 | Apply blend modes at the `Group` level with the `blendMode` prop to composite child elements | paint/overview |
| 13 | Use `ClipRect` / `ClipPath` as children of a `Group` or drawing element to mask content | canvas/overview |
| 13 | Use the `clip` prop on `Group` (rect, rrect, or path) to mask content; `invertClip` reverses it | group |
| 14 | Use `SweepGradient` / `TwoPointConicalGradient` for angular and conical fills beyond linear/radial | shaders/gradients |
| 15 | Apply effects to a group composite with the `layer` prop (`<Paint>` + image filters), not per-child filters alone | group |
| 16 | Use `Skia.ParagraphBuilder` + `<Paragraph>` for multi-style text layouts; call `layout(width)` before rendering | text/paragraph |
Expand Down Expand Up @@ -86,7 +86,7 @@ The pack now covers three built-in gradient shaders (linear, radial, sweep). Maj
| Canvas sizing (UI thread) | `onSize` shared value prop | Partially covered by `useCanvasSize` in eval 01 |
| Per-element gestures | `Animated.View` overlay tracking | Documented in rule 4; eval 14 only tests canvas-level pan |
| Nested image shaders | `ImageShader` inside custom `Shader` | Advanced; needs bundled image asset |
| Fitbox / Group clip props | `FitBox`, `Group clip` / `invertClip` | Overlap path/SVG evals; `FitBox` is a strong future add |
| FitBox | `FitBox` | Overlaps path/SVG evals; a strong future add |
| Path / mask filters | `DashPathEffect`, `BlurMask`, morphology | Lower-level paint modifiers; narrow use cases |

## Common issue clusters
Expand Down
1 change: 1 addition & 0 deletions testbench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@react-navigation/native": "^7.1.0",
"@react-navigation/native-stack": "^7.3.0",
"@shopify/flash-list": "2.0.2",
"@shopify/react-native-skia": "^2.11.2",
"@tanstack/react-query": "^5.90.21",
"expo": "~56.0.12",
"expo-audio": "~56.0.12",
Expand Down