---
id: game-skia-native-2d
title: Skia / Native 2D — Mobile / Cross-platform 그림
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [game, skia, 2d, mobile, vibe-coding]
tech_stack: { language: "TS / Dart", applicable_to: ["Mobile", "Frontend"] }
applied_in: []
aliases: [Skia, react-native-skia, CanvasKit, Flutter, Path, paint, fast 2D]
---
# Skia / Native 2D
> Google Skia = Chrome/Flutter/Android/Firefox 의 그림 엔진. **GPU-accelerated 2D**. RN Skia / CanvasKit / Flutter Canvas 가 wrapper.
## 📖 핵심 개념
- Path: 선 + 곡선.
- Paint: 색 + style.
- Canvas: drawable surface.
- Shader / image filter: Path 위 효과.
## 💻 코드 패턴
### React Native Skia
```bash
yarn add @shopify/react-native-skia
```
```tsx
import { Canvas, Circle, Path, Skia, useClockValue, useComputedValue, useValue } from '@shopify/react-native-skia';
function App() {
const clock = useClockValue();
const cx = useComputedValue(() => 100 + Math.sin(clock.current / 500) * 50, [clock]);
return (
);
}
```
### Path (복잡 도형)
```tsx
const path = Skia.Path.Make();
path.moveTo(50, 50);
path.lineTo(150, 50);
path.quadTo(200, 100, 150, 150);
path.close();
```
### Gradient
```tsx
import { LinearGradient, vec } from '@shopify/react-native-skia';
```
### Image filter (blur, etc)
```tsx
import { Blur, ColorMatrix } from '@shopify/react-native-skia';
```
### Shader (GPU)
```tsx
import { Shader, Skia } from '@shopify/react-native-skia';
const source = Skia.RuntimeEffect.Make(`
uniform float2 iResolution;
uniform float iTime;
half4 main(float2 fragCoord) {
float2 uv = fragCoord / iResolution;
return half4(uv.x, uv.y, sin(iTime), 1.0);
}
`);
const clock = useClockValue();
const uniforms = useComputedValue(() => ({
iResolution: [width, height],
iTime: clock.current / 1000,
}), [clock]);
```
→ Web 의 Three.js shader 같은 power.
### Animation (declarative)
```tsx
import { useSpring, withTiming, withRepeat, withSequence } from '@shopify/react-native-skia';
const x = useSharedValue(0);
useEffect(() => {
x.value = withRepeat(
withSequence(
withTiming(200, { duration: 1000 }),
withTiming(0, { duration: 1000 }),
),
-1
);
}, []);
```
→ Reanimated 통합 — UI thread 60fps.
### Text
```tsx
import { Text, useFont } from '@shopify/react-native-skia';
const font = useFont(require('./Roboto.ttf'), 24);
if (!font) return null;
```
### CanvasKit (web)
```ts
import CanvasKitInit from 'canvaskit-wasm';
const CanvasKit = await CanvasKitInit({ locateFile: f => `/${f}` });
const surface = CanvasKit.MakeWebGLCanvasSurface('canvas')!;
const canvas = surface.getCanvas();
const paint = new CanvasKit.Paint();
paint.setColor(CanvasKit.Color4f(0.9, 0.5, 0.2, 1.0));
paint.setStyle(CanvasKit.PaintStyle.Fill);
canvas.drawCircle(100, 100, 50, paint);
surface.flush();
```
→ Web 에서 Skia 그대로 (Flutter web 이 사용).
### Flutter Canvas
```dart
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
final path = Path()
..moveTo(0, 0)
..quadraticBezierTo(100, 200, 200, 0);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter old) => false;
}
CustomPaint(painter: MyPainter(), size: Size.infinite);
```
### Game-like usage (RN Skia)
```tsx
function Game() {
const clock = useClockValue();
const playerY = useComputedValue(() => 200 + Math.sin(clock.current / 500) * 50, [clock]);
// Bullets — array of values
const bullets = useMemo(() => Array.from({ length: 20 }, () => ({ x: 0, y: 0 })), []);
return (
);
}
```
### Performance
- Path / shape 재사용 (useMemo).
- Reanimated 의 SharedValue 가 UI thread.
- `useComputedValue` 가 derive.
- 큰 image = `Image` component + cache.
- 너무 많은 element = Canvas 가 한 번에 그림.
### Web Canvas API (대안)
```ts
const ctx = canvas.getContext('2d')!;
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 100);
ctx.beginPath();
ctx.arc(150, 150, 50, 0, Math.PI * 2);
ctx.fill();
```
→ Skia 만큼 강력 X. 단순 OK.
### vs WebGL (Three.js)
```
2D = Skia / Canvas API
3D = WebGL / WebGPU / Three.js
Skia 도 GPU 가속 — Canvas API 보다 빠름 (canvaskit).
```
## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| RN custom drawing | RN Skia |
| Flutter | Canvas / CustomPainter |
| Web 2D | Canvas API (간단) / CanvasKit (강력) |
| Game UI | Skia / 자체 canvas |
| 차트 | Recharts / Visx (위 문서) |
| 매우 simple shape | SVG |
## ❌ 안티패턴
- **매 frame Path 새로**: useMemo / 외부.
- **JS thread 에 animation**: reanimated SharedValue.
- **큰 Bitmap 매번 decode**: cache.
- **너무 많은 Element (1000+)**: 한 Canvas 안 묶기.
- **Shader 매 frame compile**: useMemo.
- **CanvasKit web bundle 인지**: 큰 (~3MB). Lazy.
## 🤖 LLM 활용 힌트
- RN = RN Skia (modern).
- Flutter = built-in Canvas.
- Web 2D = Canvas API 보통 충분.
- Reanimated 통합으로 60fps.
## 🔗 관련 문서
- [[RN_Reanimated_3_Patterns]]
- [[Mobile_Flutter_Patterns]]
- [[Game_Shader_Patterns]]