Otimização de Canvas/WebGL com Claude Code
Aprenda sobre otimização de Canvas/WebGL usando o Claude Code. Dicas práticas e exemplos de código incluídos.
O Encanto e os Desafios do Desenvolvimento Canvas/WebGL
O Canvas pode ser usado em uma ampla variedade de aplicações, como jogos, visualização de dados, edição de imagens e arte interativa. Por outro lado, como a API é de baixo nível, o código tende a ficar extenso. Com o Claude Code, você pode gerar rapidamente lógica de renderização e código de shaders, aumentando significativamente a velocidade de desenvolvimento.
Sistema Básico de Renderização Canvas 2D
> Crie uma classe para gerenciar a renderização Canvas 2D.
> Inclua loop de animação, suporte a redimensionamento e exibição de FPS.
class CanvasApp {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
private animationId: number = 0;
private lastTime: number = 0;
private fps: number = 0;
private frameCount: number = 0;
private fpsTime: number = 0;
constructor(container: HTMLElement) {
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d')!;
container.appendChild(this.canvas);
this.resize();
window.addEventListener('resize', () => this.resize());
}
private resize() {
const dpr = window.devicePixelRatio || 1;
const rect = this.canvas.parentElement!.getBoundingClientRect();
this.canvas.width = rect.width * dpr;
this.canvas.height = rect.height * dpr;
this.canvas.style.width = `${rect.width}px`;
this.canvas.style.height = `${rect.height}px`;
this.ctx.scale(dpr, dpr);
}
start(renderFn: (ctx: CanvasRenderingContext2D, dt: number) => void) {
const loop = (time: number) => {
const dt = (time - this.lastTime) / 1000;
this.lastTime = time;
// Cálculo de FPS
this.frameCount++;
if (time - this.fpsTime >= 1000) {
this.fps = this.frameCount;
this.frameCount = 0;
this.fpsTime = time;
}
const { width, height } = this.canvas.getBoundingClientRect();
this.ctx.clearRect(0, 0, width, height);
renderFn(this.ctx, dt);
// Exibição de FPS
this.ctx.fillStyle = '#0f0';
this.ctx.font = '12px monospace';
this.ctx.fillText(`FPS: ${this.fps}`, 10, 20);
this.animationId = requestAnimationFrame(loop);
};
this.animationId = requestAnimationFrame(loop);
}
stop() {
cancelAnimationFrame(this.animationId);
}
}
Sistema de Partículas
> Implemente um efeito de partículas. Crie partículas que seguem o mouse.
interface Particle {
x: number; y: number;
vx: number; vy: number;
life: number; maxLife: number;
size: number;
color: string;
}
class ParticleSystem {
private particles: Particle[] = [];
private maxParticles = 500;
emit(x: number, y: number, count: number = 5) {
for (let i = 0; i < count; i++) {
if (this.particles.length >= this.maxParticles) break;
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 3 + 1;
const hue = Math.random() * 60 + 200; // Azul a roxo
this.particles.push({
x, y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: 1,
maxLife: Math.random() * 1 + 0.5,
size: Math.random() * 4 + 2,
color: `hsl(${hue}, 80%, 60%)`,
});
}
}
update(dt: number) {
this.particles = this.particles.filter((p) => {
p.x += p.vx;
p.y += p.vy;
p.vy += 0.5 * dt; // Gravidade
p.life -= dt / p.maxLife;
return p.life > 0;
});
}
draw(ctx: CanvasRenderingContext2D) {
this.particles.forEach((p) => {
ctx.globalAlpha = p.life;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size * p.life, 0, Math.PI * 2);
ctx.fill();
});
ctx.globalAlpha = 1;
}
}
Shaders WebGL
> Crie um shader de gradiente simples com WebGL.
function createShaderProgram(gl: WebGLRenderingContext) {
const vertexShaderSource = `
attribute vec2 a_position;
varying vec2 v_uv;
void main() {
v_uv = a_position * 0.5 + 0.5;
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
const fragmentShaderSource = `
precision mediump float;
varying vec2 v_uv;
uniform float u_time;
void main() {
vec3 color1 = vec3(0.1, 0.3, 0.8);
vec3 color2 = vec3(0.8, 0.2, 0.5);
float t = sin(v_uv.x * 3.0 + u_time) * 0.5 + 0.5;
vec3 color = mix(color1, color2, t * v_uv.y);
gl_FragColor = vec4(color, 1.0);
}
`;
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram()!;
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
return program;
}
function compileShader(gl: WebGLRenderingContext, type: number, source: string) {
const shader = gl.createShader(type)!;
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader) || 'Erro de compilação do shader');
}
return shader;
}
Integração com React
function CanvasComponent() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!containerRef.current) return;
const app = new CanvasApp(containerRef.current);
const particles = new ParticleSystem();
containerRef.current.addEventListener('mousemove', (e) => {
const rect = containerRef.current!.getBoundingClientRect();
particles.emit(e.clientX - rect.left, e.clientY - rect.top);
});
app.start((ctx, dt) => {
particles.update(dt);
particles.draw(ctx);
});
return () => app.stop();
}, []);
return <div ref={containerRef} className="w-full h-96 bg-gray-900 rounded-lg" />;
}
Resumo
Com o Claude Code, você pode desenvolver eficientemente desde sistemas de renderização Canvas 2D até efeitos de partículas e shaders WebGL. Para integração com áudio, consulte Web Audio API, e para visualização de dados, consulte o artigo sobre visualização de dados.
Para detalhes sobre a Canvas API, consulte MDN Web Docs - Canvas API, e para WebGL, visite WebGL Fundamentals.
Related Posts
10 Dicas para Triplicar Sua Produtividade com o Claude Code
Descubra 10 dicas práticas para aproveitar melhor o Claude Code. De estratégias de prompt a atalhos de workflow, essas técnicas vão aumentar sua eficiência a partir de hoje.
Markdown Implementation with Claude Code
Aprenda sobre markdown implementation usando o Claude Code. Dicas praticas e exemplos de codigo incluidos.
Practicing AI Pair Programming with Claude Code
Learn how to practice AI pair programming using Claude Code. Includes practical tips and workflows.