Optimizacion de Canvas/WebGL con Claude Code
Aprende sobre la optimizacion de Canvas/WebGL usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
El atractivo y los desafios del desarrollo con Canvas/WebGL
Canvas se puede utilizar en una amplia variedad de aplicaciones como juegos, visualizacion de datos, edicion de imagenes y arte interactivo. Sin embargo, dado que la API es de bajo nivel, el codigo tiende a ser extenso. Con Claude Code, puedes generar rapidamente la logica de renderizado y el codigo de shaders, mejorando significativamente la velocidad de desarrollo.
Sistema basico de renderizado con Canvas 2D
> Crea una clase que gestione el renderizado con Canvas 2D.
> Incluye bucle de animacion, adaptacion al redimensionamiento y visualizacion 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;
// Calculo 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);
// Visualizacion 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 particulas
> Implementa un efecto de particulas. Crea particulas que sigan al cursor del raton.
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 purpura
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; // Gravedad
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
> Crea un shader de degradado simple con 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) || 'Error de compilacion del shader');
}
return shader;
}
Integracion con 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" />;
}
Resumen
Con Claude Code, puedes desarrollar eficientemente desde sistemas de renderizado Canvas 2D hasta efectos de particulas y shaders WebGL. Para la integracion con audio, consulta Web Audio API, y para la visualizacion de datos, consulta el articulo sobre visualizacion de datos.
Para mas detalles sobre la API de Canvas, visita MDN Web Docs - Canvas API, y sobre WebGL, consulta WebGL Fundamentals.
Related Posts
10 consejos para triplicar tu productividad con Claude Code
Descubre 10 consejos prácticos para sacar más provecho de Claude Code. Desde estrategias de prompts hasta atajos de flujo de trabajo, estas técnicas mejorarán tu eficiencia desde hoy.
Implementacion de Markdown con Claude Code
Aprenda sobre la implementacion de Markdown usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
Programacion en pareja con Claude Code
Aprenda sobre programacion en pareja usando Claude Code. Incluye ejemplos practicos de codigo.