Canvas
WebF supports the Canvas API for custom drawing and painting operations. This allows you to create custom graphics, charts, visualizations, games, and more using pixel-based rendering.
Canvas 2D API Reference
WebF provides comprehensive support for the Canvas 2D Context API. Below is the complete list of supported properties and methods:
Properties
| Property | Type | Description |
|---|---|---|
globalAlpha | number | Global transparency value (0.0 to 1.0) |
globalCompositeOperation | string | Type of compositing operation to apply |
fillStyle | string | CanvasGradient | CanvasPattern | Color, gradient, or pattern for fill operations |
strokeStyle | string | CanvasGradient | CanvasPattern | Color, gradient, or pattern for stroke operations |
lineWidth | number | Width of lines |
lineCap | string | Style of line caps ('butt', 'round', 'square') |
lineJoin | string | Style of line joins ('miter', 'round', 'bevel') |
lineDashOffset | number | Offset for line dashes |
miterLimit | number | Miter limit ratio |
shadowOffsetX | number | Horizontal shadow offset |
shadowOffsetY | number | Vertical shadow offset |
shadowBlur | number | Blur level for shadows |
shadowColor | string | Color of shadows |
font | string | Current text font |
textAlign | string | Text alignment ('left', 'right', 'center', 'start', 'end') |
textBaseline | string | Text baseline ('top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom') |
direction | string | Text direction ('ltr', 'rtl', 'inherit') |
Drawing Methods
Rectangle Methods
| Method | Description |
|---|---|
fillRect(x, y, w, h) | Draws a filled rectangle |
strokeRect(x, y, w, h) | Draws a rectangular outline |
clearRect(x, y, w, h) | Clears a rectangular area |
Path Methods
| Method | Description |
|---|---|
beginPath() | Starts a new path |
closePath() | Closes the current path |
moveTo(x, y) | Moves the pen to a point |
lineTo(x, y) | Draws a line to a point |
arc(x, y, radius, startAngle, endAngle, anticlockwise?) | Draws a circular arc |
arcTo(x1, y1, x2, y2, radius) | Draws an arc with control points |
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise?) | Draws an elliptical arc |
rect(x, y, w, h) | Adds a rectangle to the path |
roundRect(x, y, w, h, radii) | Adds a rounded rectangle to the path |
quadraticCurveTo(cpx, cpy, x, y) | Draws a quadratic Bézier curve |
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) | Draws a cubic Bézier curve |
Path Drawing
| Method | Description |
|---|---|
fill(path?, fillRule?) | Fills the current path |
stroke(path?) | Strokes the current path |
clip(path?, fillRule?) | Creates a clipping region |
isPointInPath(path | x, x | y, y?, fillRule?) | Tests if a point is in the path |
isPointInStroke(path | x, x | y, y?) | Tests if a point is in the stroke |
Line Styles
| Method | Description |
|---|---|
setLineDash(segments) | Sets line dash pattern |
getLineDash() | Gets current line dash pattern |
Text Methods
| Method | Description |
|---|---|
fillText(text, x, y, maxWidth?) | Draws filled text |
strokeText(text, x, y, maxWidth?) | Draws text outline |
measureText(text) | Returns text metrics |
Image Methods
| Method | Description |
|---|---|
drawImage(image, dx, dy) | Draws an image at position |
drawImage(image, dx, dy, dw, dh) | Draws and scales an image |
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) | Draws a portion of an image |
Pixel Manipulation
| Method | Description |
|---|---|
createImageData(sw, sh) | Creates a new ImageData object |
createImageData(imagedata) | Creates ImageData from existing data |
getImageData(sx, sy, sw, sh) | Gets pixel data from canvas |
putImageData(imagedata, dx, dy, dirtyX?, dirtyY?, dirtyWidth?, dirtyHeight?) | Puts pixel data onto canvas |
Transform Methods
| Method | Description |
|---|---|
translate(x, y) | Translates the coordinate system |
rotate(angle) | Rotates the coordinate system |
scale(x, y) | Scales the coordinate system |
transform(a, b, c, d, e, f) | Applies a transformation matrix |
setTransform(a, b, c, d, e, f) | Resets and applies transformation |
resetTransform() | Resets to identity transformation |
State Methods
| Method | Description |
|---|---|
save() | Saves the current drawing state |
restore() | Restores the saved drawing state |
reset() | Resets the canvas to initial state |
Gradient & Pattern Methods
| Method | Description |
|---|---|
createLinearGradient(x0, y0, x1, y1) | Creates a linear gradient |
createRadialGradient(x0, y0, r0, x1, y1, r1) | Creates a radial gradient |
createPattern(image, repetition) | Creates a pattern from an image |
Using Canvas 2D Context
import { useEffect, useRef } from 'react';
function CustomCanvas() {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw a circle
ctx.beginPath();
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fillStyle = '#4F46E5';
ctx.fill();
// Draw text
ctx.font = '20px sans-serif';
ctx.fillStyle = '#000';
ctx.fillText('Hello WebF', 50, 200);
// Draw a line
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(200, 200);
ctx.strokeStyle = '#EF4444';
ctx.lineWidth = 2;
ctx.stroke();
}, []);
return <canvas ref={canvasRef} width={300} height={300} />;
}Creating Interactive Canvas Elements
function InteractiveCanvas() {
const canvasRef = useRef(null);
const [points, setPoints] = useState([]);
const handleClick = (e) => {
const canvas = canvasRef.current;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
setPoints([...points, { x, y }]);
};
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw all points
points.forEach(point => {
ctx.beginPath();
ctx.arc(point.x, point.y, 5, 0, 2 * Math.PI);
ctx.fillStyle = '#4F46E5';
ctx.fill();
});
}, [points]);
return (
<canvas
ref={canvasRef}
width={400}
height={400}
onClick={handleClick}
style={{ border: '1px solid #ccc' }}
/>
);
}Canvas vs SVG
Choose the right tool for your use case:
Use Canvas when:
- You need to render many elements (thousands of objects)
- You’re creating pixel-based graphics or effects
- You need high-performance real-time rendering
- You’re building games or complex data visualizations
- You need to manipulate pixels directly
Use SVG when:
- You need scalable, resolution-independent graphics
- You want DOM-based interactivity (hover, click on individual elements)
- You have a moderate number of elements (up to hundreds)
- You need accessibility features (screen readers can access SVG content)
- You want to style elements with CSS
Best Practices
Performance Tips
- Batch operations: Minimize context state changes
- Use requestAnimationFrame: For smooth animations
- Cache complex drawings: Reuse pre-rendered content when possible
- Clear only what changed: Don’t redraw the entire canvas unnecessarily
Example: Optimized Animation
function AnimatedCanvas() {
const canvasRef = useRef(null);
const animationRef = useRef(null);
const ballRef = useRef({ x: 50, y: 50, dx: 2, dy: 2 });
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const ball = ballRef.current;
const animate = () => {
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update position
ball.x += ball.dx;
ball.y += ball.dy;
// Bounce off walls
if (ball.x + 10 > canvas.width || ball.x - 10 < 0) {
ball.dx *= -1;
}
if (ball.y + 10 > canvas.height || ball.y - 10 < 0) {
ball.dy *= -1;
}
// Draw ball
ctx.beginPath();
ctx.arc(ball.x, ball.y, 10, 0, 2 * Math.PI);
ctx.fillStyle = '#4F46E5';
ctx.fill();
animationRef.current = requestAnimationFrame(animate);
};
animate();
return () => {
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
}
};
}, []);
return <canvas ref={canvasRef} width={400} height={400} />;
}Next Steps
- Learn about SVG for scalable vector graphics
- Explore Animations for CSS-based animations
- Check out Performance optimization
- Explore charting libraries like Chart.js or D3.js that work with WebF