Skia
What It Demonstrates
- SkiaCanvas — off-screen texture rendering and screen-space overlay modes
- Drawing nodes —
SkiaRect,SkiaCircle,SkiaLine,SkiaPathNode,SkiaTextNode,SkiaGroup - SkiaPaint — custom gradient shaders applied to drawing nodes
- SkiaPath — programmatic paths with boolean operations (difference, intersect, union, xor)
- SkiaTypeface / SkiaFontLoader — font loading with
useLoader, sized fonts viaatSize() - attachSkiaTexture — R3F attach helper for compositing Skia output onto 3D mesh materials
- useFrame phases —
{ before: 'render' }and{ after: 'render' }for render pipeline control
Key Patterns
Texture Mode
Render Skia shapes to a texture and apply it to a 3D mesh:
import { Skia, SkiaPaint } from '@three-flatland/skia'import { SkiaCanvas, SkiaRect, SkiaGroup } from '@three-flatland/skia/three'
const skia = await Skia.init(renderer)const canvas = new SkiaCanvas({ renderer, width: 1024, height: 880 })canvas.add(new SkiaRect()) // add shapes
// In animation loop:canvas.render()material.map = canvas.textureimport { SkiaCanvas, SkiaRect, attachSkiaTexture } from '@three-flatland/skia/react'
<mesh> <meshBasicMaterial transparent premultipliedAlpha> <SkiaCanvas attach={attachSkiaTexture} renderer={renderer} width={1024} height={880}> <skiaRect x={0} y={0} width={100} height={100} fill={[1, 0, 0, 1]} /> </SkiaCanvas> </meshBasicMaterial></mesh>Overlay Mode
Draw directly on top of the 3D scene (HUD, debug text):
const overlay = new SkiaCanvas({ renderer, width: window.innerWidth * dpr, height: window.innerHeight * dpr, overlay: true,})
// Render AFTER the 3D scene:renderer.render(scene, camera)overlay.render()// SkiaCanvas with overlay renders to the screen framebuffer.// Use useFrame with { after: 'render' } to draw after the 3D scene.const overlayRef = useRef<SkiaCanvasRef>(null)
useFrame(() => { overlayRef.current?.render()}, { after: 'render' })
<SkiaCanvas ref={overlayRef} renderer={renderer} width={pw} height={ph} overlay> <skiaTextNode text="Hello" font={font} fill={[1, 1, 1, 1]} x={10} y={30} /></SkiaCanvas>Custom Paints (Gradients, Shaders)
For effects beyond flat fill/stroke, create a SkiaPaint and assign it to a node’s paint prop:
import { SkiaPaint } from '@three-flatland/skia'
const paint = new SkiaPaint(skia).setFill()paint.setLinearGradient(0, 0, 200, 0, [0xFFFF0000, 0xFF0000FF], [0, 1])
rect.paint = paintimport { SkiaPaint } from '@three-flatland/skia'import { useSkiaContext } from '@three-flatland/skia/react'
function GradientRect() { const skia = useSkiaContext()! const [paint] = useState(() => new SkiaPaint(skia).setFill())
useFrame(({ elapsed }) => { paint.setLinearGradient(0, 0, 200, 0, [0xFFFF0000, 0xFF0000FF], [0, 1]) })
return <skiaRect paint={paint} x={0} y={0} width={200} height={50} />}Next Steps
- Skia Guide — Concepts and API reference
- Basic Sprite — Three-flatland sprites
- TSL Nodes — Shader nodes