Una guía para la API de Canvas, una forma que ofrecen los navegadores para dibujar en la pantalla
Consejo: consulte también mis tutoriales sobre cómo imprimir un lienzo en una URL de datos, cómo escribir texto en un lienzo HTML, cómo cargar una imagen en un lienzo HTML y cómo crear y guardar una imagen con Node.js y Canvas.
El lienzo HTML es una etiqueta HTML, canvas
que es un elemento donde podemos dibujar utilizando la API Canvas.
Crear un lienzo
Crear un lienzo es tan sencillo como colocar un canvas/canvas
en un archivo HTML en blanco:
No se ve nada en la página porque el lienzo es un elemento invisible. Agreguemos un borde:
Chrome agrega automáticamente un margen de 8 px al body
elemento. Por eso nuestro borde parece un marco, y puedes eliminar ese margen configurando
body { margin: 0;}
Dejaremos el valor predeterminado por ahora.
Ahora se puede acceder a nuestro lienzo desde JavaScript usando la API de selectores DOM, por lo que podemos usar document.querySelector()
:
const canvas = document.querySelector('canvas')
Cambiar el color de fondo de un lienzo
Esto es lo que hace CSS:
canvas { background-color: lightblue;}
Cambiar el tamaño de un lienzo
Puede configurar el ancho y la altura en CSS:
canvas { border: 1px solid black; width: 100%; height: 100%;}
y de esta manera el lienzo se expandirá para llenar todo el tamaño del elemento exterior.
Si coloca el lienzo como un elemento de primer nivel en el HTML, el código anterior expandirá el lienzo para que se ajuste a todo el cuerpo.
El cuerpo no ocupa todo el tamaño de la ventana. Para ocupar toda la página, necesitamos usar JavaScript:
canvas.width = window.innerWidthcanvas.height = window.innerHeight
Si ahora eliminamos el margen del cuerpo y configuramos el fondo del lienzo usando CSS, podemos llenar toda nuestra página con el lienzo y podemos comenzar a dibujar en él:
Si la ventana cambia de tamaño, también debemos recalcular el ancho del lienzo, utilizando un rebote para evitar llamar demasiadas veces a nuestro cambio de tamaño del lienzo (el resize
evento se puede llamar cientos de veces mientras mueves la ventana con el mouse, por ejemplo) :
const debounce = (func) = { let timer return (event) = { if (timer) { clearTimeout(timer) } timer = setTimeout(func, 100, event) }}window.addEventListener('resize', debounce(() = { canvas.width = window.innerWidth canvas.height = window.innerHeight}))
Obtener un contexto desde el lienzo
Queremos dibujar en el lienzo.
Para hacer esto, necesitamos obtener un contexto:
const c = canvas.getContext('2d')
Algunos asignan el contexto a una llamada variable
c
, algunosctx
– es una forma común de abreviar “contexto”
El getContext()
método devuelve un contexto de dibujo en el lienzo, de acuerdo con el tipo que pasa como parámetro.
Los valores son válidos
2d
, el que usaremoswebgl
Para utilizar la versión 1 de WebGLwebgl2
Para utilizar la versión 2 de WebGLbitmaprenderer
Para usar con ImageBitmap
Según el tipo de contexto, puede pasar un segundo parámetro para getContext()
especificar opciones adicionales.
En el caso del 2d
contexto, básicamente tenemos un parámetro que podemos usar en todos los navegadores, y es alpha
, un booleano que tiene como valor predeterminado verdadero. Si se establece como falso, el navegador sabe que el lienzo no tiene un fondo transparente y puede acelerar la representación.
Dibujar elementos en un lienzo
Con el contexto ahora podemos dibujar elementos.
Para ello tenemos varios métodos. Podemos dibujar:
- texto
- pauta
- rectángulos
- caminos
- imágenes
y para cada uno de esos elementos podemos alterar el relleno, el trazo, el degradado, el patrón, la sombra, rotarlos, escalarlos y realizar un montón de operaciones.
Empecemos por lo más sencillo: un rectángulo.
El fillRect(x, y, width, height)
método sirve para este propósito:
c.fillRect(100, 100, 100, 100)
Esto dibujará un rectángulo negro de 100 x 100 píxeles, comenzando desde la posición x 100 ey 100:
Puedes colorear el rectángulo utilizando el fillStyle()
método, pasando cualquier cadena de color CSS válida:
c.fillStyle = 'white'c.fillRect(100, 100, 100, 100)
Ahora puedes ser creativo y dibujar muchas cosas de esta manera:
for (let i = 0; i 60; i++) { for (let j = 0; j 60; j++) { c.fillStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})` c.fillRect(j * 20, i * 20, 10, 10) }}
o
for (let i = 0; i 60; i++) { for (let j = 0; j 60; j++) { c.fillStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})` c.fillRect(j * 20, i * 20, 20, 20) }}
Elementos de dibujo
Como ya hemos mencionado, puedes dibujar muchas cosas:
- texto
- pauta
- rectángulos
- caminos
- imágenes
Veamos algunos de ellos, rectángulos y texto, para entender cómo funcionan. Puedes encontrar la API para todo lo demás que necesites aquí.Te recomendamos Todo sobre Apple, Mac e Iphone
Cambiando los colores
Utilice las propiedades fillStyle
y strokeStyle
para cambiar los colores de relleno y trazo de cualquier figura. Aceptan cualquier color CSS válido, incluidas cadenas y cálculos RGB:
c.strokeStyle = `rgb(255, 255, 255)`c.fillStyle = `white`
Rectángulos
Tienes 3 métodos:
- clearRect(x, y, ancho, alto)
- fillRect(x, y, ancho, alto)
- strokeRect(x, y, ancho, alto)
Vimos fillRect()
en la sección anterior. strokeRect()
es similar en cómo se llama, pero en lugar de rellenar un rectángulo, simplemente dibuja el trazo usando el estilo de trazo actual (que se puede cambiar usando la strokeStyle
propiedad de contexto):
const c = canvas.getContext('2d')for (let i = 0; i 61; i++) { for (let j = 0; j 61; j++) { c.strokeStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})` c.strokeRect(j * 20, i * 20, 20, 20) }}
clearRect()
Establezca un área como transparente:
Texto
Dibujar texto es similar a dibujar rectángulos. Tienes 2 métodos
- fillText(texto, x, y)
- strokeText(texto, x, y)
que te permiten escribir texto en el lienzo.
x
y y
consulte la esquina inferior izquierda.
Cambia la familia y el tamaño de la fuente utilizando la font
propiedad del lienzo:
c.font = '148px Courier New'
Hay otras propiedades que puedes cambiar, relacionadas con el texto (* = predeterminado):
textAlign
(inicio*, fin, izquierda, derecha, centro)textBaseline
(arriba, colgante, medio, alfabético*, ideográfico, abajo)direction
(izquierda, derecha, derecha*)
Pauta
Para dibujar una línea, primero se llama al beginPath()
método, luego se proporciona un punto de partida con moveTo(x, y)
y luego se llama lineTo(x, y)
para crear la línea hasta ese nuevo conjunto de coordenadas. Finalmente se llama a stroke()
:
c.beginPath()c.moveTo(10, 10)c.lineTo(300, 300)c.stroke()
La línea se coloreará según el c.strokeStyle
valor de la propiedad.
Un ejemplo más complejo
Este código crea un lienzo que genera 800 círculos:
Cada círculo está perfectamente contenido en el lienzo y su radio es aleatorio.
Cada vez que cambia el tamaño de la ventana, los elementos se regeneran.
Puedes jugar con él en Codepen.
const canvas = document.querySelector('canvas')canvas.width = window.innerWidthcanvas.height = window.innerHeightconst c = canvas.getContext('2d')const circlesCount = 800const colorArray = [ '#046975', '#2EA1D4', '#3BCC2A', '#FFDF59', '#FF1D47']const debounce = (func) = { let timer return (event) = { if (timer) { clearTimeout(timer) } timer = setTimeout(func, 100, event) }}window.addEventListener('resize', debounce(() = { canvas.width = window.innerWidth canvas.height = window.innerHeight init()}))const init = () = { for (let i = 0; i circlesCount; i++) { const radius = Math.random() * 20 + 1 const x = Math.random() * (innerWidth - radius * 2) + radius const y = Math.random() * (innerHeight - radius * 2) + radius const dx = (Math.random() - 0.5) * 2 const dy = (Math.random() - 0.5) * 2 const circle = new Circle(x, y, dx, dy, radius) circle.draw() }}const Circle = function(x, y, dx, dy, radius) { this.x = x this.y = y this.dx = dx this.dy = dy this.radius = radius this.minRadius = radius this.color = colorArray[Math.floor(Math.random() * colorArray.length)] this.draw = function() { c.beginPath() c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false) c.strokeStyle = 'black' c.stroke() c.fillStyle = this.color c.fill() }}init()
Otro ejemplo: animar elementos en el lienzo
Basándonos en el ejemplo anterior, animamos los elementos mediante un bucle. Cada círculo tiene su propia “vida” y se mueve dentro de los límites del lienzo. Cuando se alcance el límite, rebota:
Logramos esto utilizando requestAnimationFrame()
y moviendo ligeramente la imagen en cada iteración de renderizado de fotogramas.
Interactuar con los elementos del lienzo.
Aquí se muestra el ejemplo anterior ampliado para permitirle interactuar con los círculos usando el mouse.
Cuando pasa el mouse sobre el lienzo, los elementos cercanos aumentarán de tamaño y volverán a la normalidad cuando te muevas a otro lugar:
¿Cómo funciona? Bueno, primero hago un seguimiento de la posición del ratón mediante dos variables:
let mousex = undefinedlet mousey = undefinedwindow.addEventListener('mousemove', (e) = { mousex = e.x mousey = e.y})
Luego usamos esas variables dentro del método update() de Circle, para determinar si la radio debe aumentar (o disminuir):
if (mousex - this.x distanceFromMouse mousex - this.x -distanceFromMouse mousey - this.y distanceFromMouse mousey - this.y -distanceFromMouse) { if (this.radius maxRadius) this.radius += 1} else { if (this.radius this.minRadius) this.radius -= 1}
distanceFromMouse
es un valor expresado en píxeles (establecido en 200) que definen hasta qué punto queremos que reaccionen los círculos al mouse.
Accionamiento
Si intentas editar los proyectos anteriores y agregas más círculos y partes móviles, probablemente notarás problemas de rendimiento. Los navegadores consumen mucha energía para representar el lienzo con animaciones e interacciones, así que presta atención para que la experiencia no se arruine en máquinas con un rendimiento menor al tuyo.
En particular, tuve problemas al intentar crear una experiencia similar con emojis en lugar de círculos, y descubrí que el texto requiere mucha más energía para procesarse, por lo que se regresó lento bastante rápido.
Esta página en MDN enumera muchos consejos de rendimiento.
Palabras de cierre
Esta fue solo una introducción a las posibilidades de Canvas, una increíble herramienta que puedes usar para crear experiencias increíbles en tus páginas web.
Tips para principiantes de JavaScript
Tal vez te puede interesar:
- La etiqueta HTML `iframe`
- Cómo cargar una imagen en un lienzo HTML
- Cómo utilizar insertAdjacentHTML
- Cómo cambiar la URL de una imagen HTML en modo oscuro
Tutorial de la API de Canvas en HTML
Crear un lienzoCambiar el color de fondo de un lienzoCambiar el tamaño de un lienzoObtener un contexto desde el lienzoDibujar elementos en un lienzoElementos
programar
es
2025-01-16

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente