Aplicación de estilos y colores

  • Enlace amigable (slug) de la revisión: Canvas_tutorial/Aplicación_de_estilos_y_colores
  • Título de la revisión: Aplicación de estilos y colores
  • Id de la revisión: 270197
  • Creada:
  • Creador: StripTM
  • ¿Es la revisión actual?
  • Comentario 1 words added, 1 words removed

Contenido de la revisión

 

En el capítulo dedicado a dibujar formas usé sólo los estilos de línea y relleno predeterminados. En este capítulo vamos a explorar todas las opciones de canvas que tenemos a nuestra disposición para hacer que nuestros dibujos sean un poco más atractivos.

Colores

Hasta ahora sólo hemos visto métodos del contexto de dibujo. Si queremos aplicar colores a una forma, hay dos características importantes que podemos utilizar: fillStyle y strokeStyle .

fillStyle = color
strokeStyle = color

strokeStyle se utiliza para configurar el color del contorno de la forma y fillStyle es para el color de relleno. color puede ser una cadena que representa un valor de color CSS, un objeto degradado o un objeto modelo. Prestaremos atención a los objetos degradados y modelos más tarde. De forma predeterminada, el trazo y el color de relleno se establecen en negro (valor de color CSS #000000).

Las cadenas válidas que puedes introducir deben ser, de acuerdo con la especificación, los valores de color CSS3 . Cada uno de los ejemplos siguientes describen el mismo color.

// todos ellos configuran fillStyle a 'naranja' (orange)
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255,165,0)";
ctx.fillStyle = "rgba(255,165,0,1)";

Nota: En la actualidad no todos los valores de color CSS 3 son compatibles con el motor Gecko. Por ejemplo, los valores de color hsl(100%,25%,0) o rgb(0,100%,0) no están permitidos. Si te atienes estrictamente a los valores de arriba, no te surgirá ningún problema.

Nota: Si estableces la propiedad strokeStyle o fillStyle, el nuevo valor se convierte en el valor predeterminado para todas las formas que se dibujen a partir de entonces. Para cada forma que desees en un color diferente, tendrás que volver a asignar la propiedad fillStyle o strokeStyle.

Un ejemplo de fillStyle

En este ejemplo, una vez más, utilizo dos bucles for para dibujar una cuadrícula de rectángulos, cada uno en un color diferente. La imagen resultante debe parecerse a la imagen de la derecha. No hay nada excesivamente espectacular en este caso. Uso las dos variables i y j para generar un único color RGB para cada cuadrado. Sólo modifico los valores de rojo y verde. El canal azul tiene un valor fijo. Mediante la modificación de los canales, puedes generar todo tipo de paletas. Al aumentar los pasos, puedes lograr algo que se parece a las paletas de color que utiliza Photoshop.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i=0;i<6;i++){
    for (var j=0;j<6;j++){
      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + 
                       Math.floor(255-42.5*j) + ',0)';
      ctx.fillRect(j*25,i*25,25,25);
    }
  }
}

 

Un ejemplo de strokeStyle

Este ejemplo es similar al anterior pero ahora con la propiedad strokeStyle. Aquí utilizo el método arc para dibujar círculos en lugar de cuadrados.

Ver este ejemplo

   function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    for (var i=0;i<6;i++){
      for (var j=0;j<6;j++){
        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' + 
                         Math.floor(255-42.5*j) + ')';
        ctx.beginPath();
        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
        ctx.stroke();
      }
    }
  }

Transparencias

Además de dibujar formas opacas en el lienzo, también podemos dibujar formas semitransparentes. Esto se hace mediante el establecimiento de la propiedad globalAlpha o podríamos asignar un color semitransparente al trazo y/o al estilo de relleno.

globalAlpha = transparency value

Esta propiedad aplica un valor de transparencia a todas las formas dibujadas en el lienzo. El rango válido de valores es de 0.0 (totalmente transparente) a 1.0 (totalmente opaco). De forma predeterminada, esta propiedad se establece en 1.0 (totalmente opaco).

La propiedad globalAlpha puede ser útil si deseas dibujar un montón de formas en el lienzo con una transparencia similar. Creo, sin embargo, que la siguiente opción es un poco más práctica.

Debido a que las propiedades strokeStyle y fillStyle aceptan valores de color CSS 3, podemos utilizar la siguiente notación para asignarles un color transparente.

/ / Asignación de colores transparentes para trazo y estilo de relleno
ctx.strokeStyle = "rgba (255,0,0,0.5)";
ctx.fillStyle = "rgba (255,0,0,0.5)";

La función rgba() es similar a la función rgb(), pero tiene un parámetro adicional. El último parámetro establece el valor de transparencia de este color en particular. El rango válido es de nuevo entre 0.0 (totalmente transparente) y 1.0 (totalmente opaco).

Un ejemplo de globalAlpha

En este ejemplo he dibujado un fondo de cuatro cuadrados de colores diferentes. En la parte superior de estos, he dibujado un conjunto de círculos semitransparentes. La propiedad globalAlpha se establece en 0.2, que se utilizará para todas las formas a partir de ese momento. Cada paso en el bucle for dibuja una serie de círculos con un radio cada vez mayor. El resultado final es un degradado radial. Mediante la superposición de más círculos unos encima de otros, reducimos eficazmente la transparencia de los círculos que ya se han dibujado. Al aumentar el número de pasos y, de hecho, dibujar más círculos, el fondo desaparecería completamente del centro de la imagen.

Ten en cuenta:
  • Este ejemplo no funciona en Firefox 1.5 beta 1. Tendrás que crear una binario diario de una rama estable (como
    mozilla1.9.2) o esperar a una nueva versión para ver esto en acción.
  • Este ejemplo se rompe en Safari ya que el color no se especifica correctamente. El color del ejemplo se especifica como '#09F) ', que no es válido de acuerdo con las especificaciones. Firefox, sin embargo, acepta la definición de color con formato incorrecto.

Ver este ejemplo


function draw() { var ctx = document.getElementById('canvas').getContext('2d'); // dibujar fondo ctx.fillStyle = '#FD0'; ctx.fillRect(0,0,75,75); ctx.fillStyle = '#6C0'; ctx.fillRect(75,0,75,75); ctx.fillStyle = '#09F'; ctx.fillRect(0,75,75,75); ctx.fillStyle = '#F30'; ctx.fillRect(75,75,150,150); ctx.fillStyle = '#FFF'; // establecer valor de transparencia ctx.globalAlpha = 0.2; // Dibujar círculos semitransparentes for (var i=0;i<7;i++){ ctx.beginPath(); ctx.arc(75,75,10+10*i,0,Math.PI*2,true); ctx.fill(); } }

Un ejemplo usando rgba()

 En este segundo ejemplo he hecho algo similar a lo anterior, pero en vez de dibujar círculos unos encima de otros, he dibujado pequeños rectángulos con una opacidad creciente. El uso de rgba() te da un poco de más control y flexibilidad, ya que puedes establecer el estilo de relleno y de trazo de manera individual.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Dibujar fondo
  ctx.fillStyle = 'rgb(255,221,0)';
  ctx.fillRect(0,0,150,37.5);
  ctx.fillStyle = 'rgb(102,204,0)';
  ctx.fillRect(0,37.5,150,37.5);
  ctx.fillStyle = 'rgb(0,153,255)';
  ctx.fillRect(0,75,150,37.5);
  ctx.fillStyle = 'rgb(255,51,0)';
  ctx.fillRect(0,112.5,150,37.5);

  // Dibujar rectángulos semitransparentes
  for (var i=0;i<10;i++){
    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
    for (var j=0;j<4;j++){
      ctx.fillRect(5+i*14,5+j*37.5,14,27.5)
    }
  }
}

Estilos de línea

Hay varias propiedades que nos permiten aplicar estilo a las líneas.

lineWidth = value
lineCap = type
lineJoin = type
miterLimit = value

Podría describirlas en detalle, pero probablemente se resultará más claro con sólo mirar los ejemplos a continuación.

Un ejemplo de lineWidth

Esta propiedad establece el grosor de la línea actual. Los valores deben ser números positivos. Por defecto, este valor se establece en 1.0 unidades.

El ancho de línea es el espesor del trazo centrado en la ruta dada. En otras palabras, el área que se dibuja se extiende hasta la mitad del ancho de la línea a cada lado de la ruta. Debido a que las coordenadas del lienzo no hacen referencia directamente a los píxeles, se debe prestar especial atención para obtener líneas horizontales y verticales nítidas.

En el siguiente ejemplo, se dibujan 10 líneas rectas con anchos de línea cada vez mayores. La línea en el extremo izquierdo es de 1.0 unidades de ancho. Sin embargo, la línea más a la izquierda y todas las demás cuyo grosor tiene un ancho impar no tienen un borde nítido debido al posicionamiento de la ruta.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i = 0; i < 10; i++){
    ctx.lineWidth = 1+i;
    ctx.beginPath();
    ctx.moveTo(5+i*14,5);
    ctx.lineTo(5+i*14,140);
    ctx.stroke();
  }
}

Para obtener líneas nítidas se necesita comprender cómo se trazan las rutas. En las imágenes de abajo, la cuadrícula representa la cuadrícula de las coordinadas del lienzo. Los cuadrados entre las líneas de división son en píxeles reales en pantalla. En la primera imagen de la cuadrícula de abajo, está relleno un rectángulo desde (2,1) hasta (5,5). Toda la zona entre ellos (rojo claro) se encuentre dentro de los límites del píxel, por lo que el rectángulo relleno resultante tendrá bordes nítidos.

Si consideras una ruta desde (3,1) hasta (3,5) con un grosor de línea de 1.0, obtendrás el resultado que se muestra en la segunda imagen. El área real que se va a rellenar (azul oscuro), sólo se extiende hasta la mitad de los píxeles situados a cada lado de la ruta. Se tiene que representar una aproximación de esto, lo que significa que dichos píxeles se sombrean sólo parcialmente, dando como resultado que toda la zona (azul claro y azul oscuro) se rellene con un color sólo la mitad de oscuro que el color del trazo actual. Esto es lo que sucede con la línea de ancho de 1.0 en el código del ejemplo anterior.

Para solucionar este problema, tienes que ser muy preciso a la hora de crear la ruta. Sabiendo que una línea de ancho 1.0 se extenderá la mitad de una unidad a cada lado de la ruta, la creación de la ruta desde (3.5,1) hasta (3.5,5) da como resultado lo que vemos en la tercera imagen: el ancho de línea 1.0 termina rellenando por completo y con precisión una sola línea vertical de píxeles.

Para las líneas de ancho par, cada mitad termina siendo una cantidad entera de píxeles, por lo que es mejor una ruta que esté entre los píxeles (es decir, (3,1) a (3,5)), en lugar de por debajo de la mitad de los píxeles. Además, ten en cuenta que en nuestro ejemplo de línea vertical, la posición Y todavía hacía referencia a una posición de línea de cuadrícula entera; de no haber sido así, veríamos píxeles con la mitad de la cobertura en los extremos.

A pesar de que resulta un tanto difícil empezar a trabajar con los gráficos 2D escalables, si prestas atención a la cuadrícula de píxeles y a la posición de las rutas, te asegurarás de que tus dibujos queden correctos, independientemente de la escala o de otras transformaciones que se tengan que hacer. Una línea vertical de 1.0 de ancho trazada en la posición correcta se convertirá en una línea nítida de 2 píxeles cuando se escale a 2, y aparecerá en la posición correcta.

Un ejemplo de lineCap

La propiedad lineCap determina cómo se dibujan los puntos finales de cada línea. Hay tres posibles valores para esta propiedad y son los siguientes: butt , round y square . De manera predeterminada, esta propiedad se establece a butt .

En este ejemplo, he dibujado tres líneas, cada una con un valor diferente para la propiedad lineCap. También he añadido dos guías para ver las diferencias exactas entre las tres. Cada una de estas líneas empieza y termina exactamente en estas guías.

La línea de la izquierda utiliza la opción predeterminada butt. Te darás cuenta de que está dibujado totalmente nivelado con las guías. La segunda está configurada para que use la opción round. Esto añade un semicírculo hasta el final que tiene un radio la mitad del ancho de la línea. La línea de la derecha utiliza la opción square. Esto añade una caja con un ancho igual y la mitad de la altura del grosor de la línea.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var lineCap = ['butt','round','square'];

  // Dibujar guías
  ctx.strokeStyle = '#09f';
  ctx.beginPath();
  ctx.moveTo(10,10);
  ctx.lineTo(140,10);
  ctx.moveTo(10,140);
  ctx.lineTo(140,140);
  ctx.stroke();

  // Dibujar líneas
  ctx.strokeStyle = 'black';
  for (var i=0;i<lineCap.length;i++){
    ctx.lineWidth = 15;
    ctx.lineCap = lineCap[i];
    ctx.beginPath();
    ctx.moveTo(25+i*50,10);
    ctx.lineTo(25+i*50,140);
    ctx.stroke();
  }
}

Un ejemplo de lineJoin

La propiedad lineJoin determina cómo dos líneas conectadas de una forma se unen entre sí. Hay tres posibles valores para esta propiedad: round , bevel y miter . De manera predeterminada esta propiedad se establece en miter .

Una vez más he dibujado tres rutas diferentes, cada una con una configuración de la propiedad lineJoin diferente. La ruta superior utiliza la opción round. Esta configuración redondea las esquinas de una forma. El radio de estas esquinas redondeadas es igual a la anchura de la línea. La segunda línea utiliza la opción bevel y la línea en la parte inferior utiliza la opción miter. Cuando se establecen en miter , las líneas se unen mediante la extensión de los bordes exteriores para conectarse a un solo punto. Esta configuración se efectuará mediante la propiedad miterLimit que se explica a continuación.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var lineJoin = ['round','bevel','miter'];
  ctx.lineWidth = 10;
  for (var i=0;i<lineJoin.length;i++){
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(-5,5+i*40);
    ctx.lineTo(35,45+i*40);
    ctx.lineTo(75,5+i*40);
    ctx.lineTo(115,45+i*40);
    ctx.lineTo(155,5+i*40);
    ctx.stroke();
  }
}

Una demostración de la propiedad miterLimit

Como hemos visto en el ejemplo anterior, cuando se unen dos líneas con la opción miter, los bordes exteriores de estas dos líneas se extienden hasta el punto donde se encuentran. Para las líneas que forman un ángulo grande con las demás, este punto no está lejos del punto de conexión interior. Sin embargo, cuando los ángulos entre cada línea disminuyen, la distancia (longitud de miter) entre estos puntos aumenta de manera exponencial.

La propiedad miterLimit determina hasta qué distancia se puede colocar el punto de conexión exterior a partir del punto de conexión interior. Si dos líneas superan este valor, se dibujará una unión biselada.

He hecho una pequeña demostración en la que puedes establecer miterLimit de manera dinámica y ver cómo esto afecta a las formas del lienzo. Las líneas azules muestran donde están el inicio y los puntos finales para cada una de las líneas del diseño en zig-zag.

Vea esta demostración

Degradados

Al igual que cualquier programa de dibujo normal, podemos rellenar y trazar formas mediante degradados lineales y radiales. Creamos un objeto canvasGradient utilizando uno de los métodos siguientes. Usamos este objeto para asignarlo a las propiedades fillStyle o strokeStyle.

createLinearGradient(x1,y1,x2,y2)
createRadialGradient(x1,y1,r1,x2,y2,r2)

El método createLinearGradient toma cuatro argumentos que representan el punto de partida (x1, y1) y el punto final (x2, y2) del degradado.
El método createRadialGradient tiene seis argumentos. Los tres primeros argumentos definen un círculo con las coordenadas (x1, y1) y radio r1 y el segundo, un círculo con las coordenadas (x2, y2) y el radio r2.

var lineargradient = ctx.createLinearGradient(0,0,150,150);
var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);

Una vez que hemos creado un objeto canvasGradient, podemos asignarle colores utilizando el método addColorStop.

addColorStop(position, color)

Este método toma dos argumentos. El argumento position (posición) debe ser un número entre 0.0 y 1.0 y define la posición relativa de los colores en el degradado. Si se configurara a 0.5, por ejemplo, pondría el color, precisamente, en el centro del degradado. El argumento color debe ser una cadena que represente un color CSS (es decir, #FFF, rgba (0,0,0,1), etc.)

Puedes agregar tantas paradas de color a un degradado como necesites. A continuación se muestra un degradado lineal muy simple de blanco a negro.

var lineargradient = ctx.createLinearGradient(0,0,150,150);
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(1,'black');

Un ejemplo de createLinearGradient

En este ejemplo, he creado dos degradados diferentes. En el primero, creo el degradado de fondo. Como puedes ver, he asignado dos colores en la misma posición. Lo hacemos así para realizar transiciones de color muy fuertes: en este caso del blanco al verde. Normalmente, no importa en qué orden se definen las paradas de color, pero en este caso especial, sí que importa de manera significativa. Si mantienes la asignación en el orden que deseas que aparezcan, no supondrá un problema.

En el segundo degradado, no asigné el color inicial (en la posición 0.0) ya que no era estrictamente necesario. Asignar el color negro en la posición 0.5 automáticamente convierte en negro el degradado, desde el principio hasta esta parada.

Como puedes ver aquí, tanto la propiedad strokeStyle como la fillStyle pueden aceptar un objeto canvasGradient como entrada válida.

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Crear degradados
  var lingrad = ctx.createLinearGradient(0,0,0,150);
  lingrad.addColorStop(0, '#00ABEB');
  lingrad.addColorStop(0.5, '#fff');
  //lingrad.addColorStop(0.5, '#26C000');
  //lingrad.addColorStop(1, '#fff');

  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
  lingrad2.addColorStop(0.5, '#000');
  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');

  // asignar degradados a estilos de relleno y trazo
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;
  
  // dibujar formas
  ctx.fillRect(10,10,130,130);
  ctx.strokeRect(50,50,50,50);

}

Un ejemplo de createRadialGradient

En este ejemplo, he definido cuatro degradados radiales diferentes. Como tenemos el control sobre los puntos de inicio y cierre de la degradados, podemos lograr efectos más complejos de lo que normalmente se tienen en degradados radiales 'clásicos' que vemos en, por ejemplo, Photoshop. (Es decir, un degradado con un punto central único donde aquél (el degradado) se expande hacia afuera en forma circular.)

En este caso, he desplazado el punto de partida un poco desde el punto final para lograr un efecto 3D esférico. Es mejor tratar de evitar que los círculos interiores y exteriores se solapen, porque esto da lugar a efectos extraños que son difíciles de predecir.

La última parada de color en cada uno de los cuatro degradados utiliza un color totalmente transparente. Si deseas tener una buena transición de ésta a la parada de color anterior, ambos colores deben ser iguales. Esto no resulta muy evidente a partir del código porque he utilizado dos métodos de color CSS diferentes, excepto en el primer degradado #019F62 = rgba(1,159,98,1)

Ver este ejemplo

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Crear degradados
  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
  radgrad.addColorStop(0, '#A7D30C');
  radgrad.addColorStop(0.9, '#019F62');
  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
  
  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
  radgrad2.addColorStop(0, '#FF5F98');
  radgrad2.addColorStop(0.75, '#FF0188');
  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
  radgrad3.addColorStop(0, '#00C9FF');
  radgrad3.addColorStop(0.8, '#00B5E2');
  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
  radgrad4.addColorStop(0, '#F4F201');
  radgrad4.addColorStop(0.8, '#E4C700');
  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
  
  // dibujar formas
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0,0,150,150);
}

Diseños

En uno de los ejemplos de la página anterior, he utilizado una serie de bucles para crear un patrón de imágenes. Hay, sin embargo, un método mucho más simple: el método createPattern.

createPattern(image,type)

Este método toma dos argumentos. "Image" es una referencia a un objeto Image o a un elemento canvas diferente. "Type" debe ser una cadena que contenga uno de los siguientes valores: repeat , repeat-x , repeat-y y no-repeat .

Nota : En Firefox 1.5 (Gecko 1.8) no funciona usar un elemento canvas como el argumento Image.

Usamos este método para crear un objeto Pattern que es muy similar a los métodos de degradado que hemos visto anteriormente. Una vez que hayamos creado un patrón, podemos asignarlo a las propiedades fillStyle o strokeStyle.

var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img,'repeat');

Nota: A diferencia del método drawImage, debes asegurarte de que la imagen que usas se carga antes de llamar a este método o el diseño se dibujará de forma incorrecta.

Nota: Firefox en la actualidad sólo admite la propiedad repeat. Si asignas cualquier otra, no verás ningún cambio.

Un ejemplo de createPattern

En este último ejemplo, he creado un patrón que he asignado a la propiedad fillStyle. Lo único a destacar es el uso del controlador onload de objeto Image. Esto es para asegurarse de que la imagen se carga antes de que se le asigne al patrón.

Ver este ejemplo

Source image

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // crear objeto de imagen para usar como diseño
  var img = new Image();
  img.src = 'images/wallpaper.png';
  img.onload = function(){

    // crear diseño
    var ptrn = ctx.createPattern(img,'repeat');
    ctx.fillStyle = ptrn;
    ctx.fillRect(0,0,150,150);

  }
}

Sombras

{{ gecko_callout_heading ("1.9.1") }}

Firefox 3.5 (Gecko 1.9.1) introdujo la compatibilidad para las sombras en los lienzos.  El uso de sombras implica sólo cuatro propiedades:

shadowOffsetX = float
shadowOffsetY = float
shadowBlur = float
shadowColor = color

shadowOffsetX y shadowOffsetY indican hasta qué punto se extendería la sombra desde el objeto en las direcciones X e Y, estos valores no se ven afectados por la matriz actual de transformación.  Utiliza valores negativos para que la sombra se extienda hacia arriba o hacia la izquierda, y los valores positivos para que la sombra se extienda hacia abajo o hacia la derecha.  Estos son 0 por defecto.

shadowBlur indica el tamaño del efecto borroso, este valor no se corresponde con un número de píxeles y no se ve afectado por la matriz actual de transformación.  El valor predeterminado es 0.

shadowColor es un valor de color CSS estándar que indica el color del efecto de sombra; de manera predeterminada, es negro totalmente transparente.

Un ejemplo de texto sombreado

Este ejemplo dibuja una cadena de texto con un efecto de sombreado.

Ver este ejemplo

Source image

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
 
  ctx.font = "20px Times New Roman";
  ctx.fillStyle = "Black";
  ctx.fillText("Sample String", 5, 30);
}

{{ PreviousNext("Canvas_tutorial/Usar_imágenes", "Tutorial de Canvas/Transformaciones") }}

{{ languages( { "en": "en/Canvas_tutorial/Applying_styles_and_colors",  "zh-tw": "zh_tw/Canvas_教學/套用樣式和色彩", "fr": "fr/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs", "ja": "ja/Canvas_tutorial/Applying_styles_and_colors", "pl": "pl/Przewodnik_po_canvas/Zastosowanie_styl\u00f3w_i_kolor\u00f3w" } ) }}

Fuente de la revisión

<p> </p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-2"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En el capítulo dedicado a <a href="/es/Canvas_tutorial/Dibujar_formas" title="es/Canvas tutorial/Dibujar formas">dibujar formas</a> usé sólo los estilos de línea y relleno predeterminados.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-3"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En este capítulo vamos a explorar <em>todas</em> las opciones de canvas que tenemos a nuestra disposición para hacer que nuestros dibujos sean un poco más atractivos.</span></span></p>
<h2 id="Colors" name="Colors"><span class="goog-gtc-unit" id="goog-gtc-unit-4"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Colores</span></span></h2>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-5"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Hasta ahora sólo hemos visto métodos del contexto de dibujo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-6"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Si queremos aplicar colores a una forma, hay dos características importantes que podemos utilizar: <code>fillStyle</code> y <code>strokeStyle</code> .</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>fillStyle</strong> = color</code><br>
<code><strong>strokeStyle</strong> = color</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-7"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr"><code>strokeStyle</code> se utiliza para configurar el color del contorno de la forma y <code>fillStyle</code> es para el color de relleno. <code>color</code> puede ser una cadena que representa un valor de color CSS, un objeto degradado o un objeto modelo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-8"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Prestaremos atención a los objetos degradados y modelos más tarde.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-9"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">De forma predeterminada, el trazo y el color de relleno se establecen en negro (valor de color CSS #000000).</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-10"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Las cadenas válidas que puedes introducir deben ser, de acuerdo con la especificación, <a class="external" href="http://www.w3.org/TR/2003/CR-css3-color-20030514/#numerical" title="http://www.w3.org/TR/2003/CR-css3-color-20030514/#numerical">los valores de color CSS3</a> .</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-11"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Cada uno de los ejemplos siguientes describen el mismo color.</span></span></p>
<pre class="deki-transform">// todos ellos configuran fillStyle a 'naranja' (orange)
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255,165,0)";
ctx.fillStyle = "rgba(255,165,0,1)";</pre>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-17"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr"><strong>Nota:</strong> En la actualidad no todos los valores de color CSS 3 son compatibles con el motor Gecko.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-18"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Por ejemplo, los valores de color <code>hsl(100%,25%,0)</code> o <code>rgb(0,100%,0)</code> no están permitidos.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-19"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Si te atienes estrictamente a los valores de arriba, no te surgirá ningún problema.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-20"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr"><strong>Nota:</strong> Si estableces la propiedad <code>strokeStyle</code> o <code>fillStyle</code>, el nuevo valor se convierte en el valor predeterminado para todas las formas que se dibujen a partir de entonces.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-21"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Para cada forma que desees en un color diferente, tendrás que volver a asignar la propiedad <code>fillStyle</code> o <code>strokeStyle</code>.</span></span></p>
<h4 id="A_fillStyle_example" name="A_fillStyle_example"><span class="goog-gtc-unit" id="goog-gtc-unit-22"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Un ejemplo de <code>fillStyle</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-23"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En este ejemplo, una vez más, utilizo dos bucles <code>for</code> para dibujar una cuadrícula </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/82/=Canvas_fillstyle.png"><span class="goog-gtc-unit" id="goog-gtc-unit-23"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">de rectángulos, cada uno en un color diferente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-24"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">La imagen resultante debe parecerse a la imagen de la derecha.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-25"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">No hay nada excesivamente espectacular en este caso.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-26"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Uso las dos variables <code>i</code> y <code>j</code> para generar un único color RGB para cada cuadrado.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-27"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Sólo modifico los valores de rojo y verde.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-28"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">El canal azul tiene un valor fijo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-29"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Mediante la modificación de los canales, puedes generar todo tipo de paletas.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-30"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Al aumentar los pasos, puedes lograr algo que se parece a las paletas de color que utiliza Photoshop.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_1_canvas_fillstyle.html" title="samples/canvas-tutorial/4 1 canvas fillstyle.html"><span class="goog-gtc-unit" id="goog-gtc-unit-31"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i=0;i&lt;6;i++){
    for (var j=0;j&lt;6;j++){
      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + 
                       Math.floor(255-42.5*j) + ',0)';
      ctx.fillRect(j*25,i*25,25,25);
    }
  }
}</pre>
<p> </p>
<h4 id="A_strokeStyle_example" name="A_strokeStyle_example"><span class="goog-gtc-unit" id="goog-gtc-unit-42"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Un ejemplo de <code>strokeStyle</code> </span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-43"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Este ejemplo es similar al anterior pero ahora con la propiedad <code>strokeStyle</code>.</span></span><img align="right" alt="" class="internal" src="/@api/deki/files/109/=Canvas_strokestyle.png"> <span class="goog-gtc-unit" id="goog-gtc-unit-44"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Aquí utilizo el método <code>arc</code> para dibujar círculos en lugar de cuadrados.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_2_canvas_strokestyle.html" title="samples/canvas-tutorial/4 2 canvas strokestyle.html"><span class="goog-gtc-unit" id="goog-gtc-unit-45"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">   function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    for (var i=0;i&lt;6;i++){
      for (var j=0;j&lt;6;j++){
        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' + 
                         Math.floor(255-42.5*j) + ')';
        ctx.beginPath();
        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
        ctx.stroke();
      }
    }
  }</pre><h2 id="Transparency" name="Transparency"><span class="goog-gtc-unit" id="goog-gtc-unit-59"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Transparencias</span></span></h2>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-60"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Además de dibujar formas opacas en el lienzo, también podemos dibujar formas semitransparentes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-61"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Esto se hace mediante el establecimiento de la propiedad <code>globalAlpha</code> o podríamos asignar un color semitransparente al trazo y/o al estilo de relleno.</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>globalAlpha</strong> = transparency value</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-62"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Esta propiedad aplica un valor de transparencia a todas las formas dibujadas en el lienzo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-63"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">El rango válido de valores es de 0.0 (totalmente transparente) a 1.0 (totalmente opaco).</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-64"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">De forma predeterminada, esta propiedad se establece en 1.0 (totalmente opaco).</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-65"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">La propiedad <code>globalAlpha</code> puede ser útil si deseas dibujar un montón de formas en el lienzo con una transparencia similar.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-66"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Creo, sin embargo, que la siguiente opción es un poco más práctica.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-67"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Debido a que las propiedades <code>strokeStyle</code> y <code>fillStyle</code> aceptan valores de color CSS 3, podemos utilizar la siguiente notación para asignarles un color transparente.</span></span></p>
<pre class="deki-transform"><span class="goog-gtc-unit" id="goog-gtc-unit-68"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">/ / Asignación de colores transparentes para trazo y estilo de relleno</span></span>
<span class="goog-gtc-unit" id="goog-gtc-unit-69"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">ctx.strokeStyle = "rgba (255,0,0,0.5)";</span></span>
<span class="goog-gtc-unit" id="goog-gtc-unit-70"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">ctx.fillStyle = "rgba (255,0,0,0.5)";</span></span>
</pre>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-71"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">La función <code>rgba()</code> es similar a la función <code>rgb()</code>, pero tiene un parámetro adicional.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-72"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">El último parámetro establece el valor de transparencia de este color en particular.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-73"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">El rango válido es de nuevo entre 0.0 (totalmente transparente) y 1.0 (totalmente opaco).</span></span></p>
<h4 id="A_globalAlpha_example" name="A_globalAlpha_example"><span class="goog-gtc-unit" id="goog-gtc-unit-74"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Un ejemplo de <code>globalAlpha</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-75"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">En este ejemplo he dibujado un fondo de cuatro cuadrados de colores diferentes.</span></span><img align="right" alt="" class="internal" src="/@api/deki/files/83/=Canvas_globalalpha.png"> <span class="goog-gtc-unit" id="goog-gtc-unit-76"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En la parte superior de estos, he dibujado un conjunto de círculos semitransparentes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-77"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">La propiedad <code>globalAlpha</code> se establece en 0.2, que se utilizará para todas las formas a partir de ese momento.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-78"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Cada paso en el bucle <code>for</code> dibuja una serie de círculos con un radio cada vez mayor.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-79"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">El resultado final es un degradado radial.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-80"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Mediante la superposición de más círculos unos encima de otros, reducimos eficazmente la transparencia de los círculos que ya se han dibujado.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-81"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Al aumentar el número de pasos y, de hecho, dibujar más círculos, el fondo desaparecería completamente del centro de la imagen.</span></span></p>
<div class="note"><strong><span class="goog-gtc-unit" id="goog-gtc-unit-82"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Ten en cuenta:</span></span></strong>
<ul> <li><span class="goog-gtc-unit" id="goog-gtc-unit-83"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Este ejemplo no funciona en Firefox 1.5 beta 1.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-84"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Tendrás que crear una </span></span>binario diario de una rama estable (como <br> mozilla1.9.2)<span class="goog-gtc-unit" id="goog-gtc-unit-84"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""> o esperar a una nueva versión para ver esto en acción.</span></span></li> <li><span class="goog-gtc-unit" id="goog-gtc-unit-85"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Este ejemplo se rompe en Safari ya que el color no se especifica correctamente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-86"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">El color del ejemplo se especifica como '#09F) ', que no es válido de acuerdo con las especificaciones.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-87"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Firefox, sin embargo, acepta la definición de color con formato incorrecto.</span></span></li>
</ul>
</div>
<p><a href="/samples/canvas-tutorial/4_3_canvas_globalalpha.html" title="samples/canvas-tutorial/4 3 canvas globalalpha.html"><span class="goog-gtc-unit" id="goog-gtc-unit-88"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform"><span class="goog-gtc-unit" id="goog-gtc-unit-89"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr"><br></span></span>function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  // dibujar fondo
  ctx.fillStyle = '#FD0';
  ctx.fillRect(0,0,75,75);
  ctx.fillStyle = '#6C0';
  ctx.fillRect(75,0,75,75);
  ctx.fillStyle = '#09F';
  ctx.fillRect(0,75,75,75);
  ctx.fillStyle = '#F30';
  ctx.fillRect(75,75,150,150);
  ctx.fillStyle = '#FFF';

  // establecer valor de transparencia
  ctx.globalAlpha = 0.2;

  // Dibujar círculos semitransparentes
  for (var i=0;i&lt;7;i++){
      ctx.beginPath();
      ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
      ctx.fill();
  }
}</pre><h4 id="An_example_using_rgba.28.29" name="An_example_using_rgba.28.29"><span class="goog-gtc-unit" id="goog-gtc-unit-111"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Un ejemplo usando <code>rgba()</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-112"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr"> En este segundo ejemplo he hecho algo similar a lo anterior, pero en vez de </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/99/=Canvas_rgba.png"><span class="goog-gtc-unit" id="goog-gtc-unit-112"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">dibujar círculos unos encima de otros, he dibujado pequeños rectángulos con una opacidad creciente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-113"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">El uso de <code>rgba()</code> te da un poco de más control y flexibilidad, ya que puedes establecer el estilo de relleno y de trazo de manera individual.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_4_canvas_rgba.html" title="samples/canvas-tutorial/4 4 canvas rgba.html"><span class="goog-gtc-unit" id="goog-gtc-unit-114"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Dibujar fondo
  ctx.fillStyle = 'rgb(255,221,0)';
  ctx.fillRect(0,0,150,37.5);
  ctx.fillStyle = 'rgb(102,204,0)';
  ctx.fillRect(0,37.5,150,37.5);
  ctx.fillStyle = 'rgb(0,153,255)';
  ctx.fillRect(0,75,150,37.5);
  ctx.fillStyle = 'rgb(255,51,0)';
  ctx.fillRect(0,112.5,150,37.5);

  // Dibujar rectángulos semitransparentes
  for (var i=0;i&lt;10;i++){
    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
    for (var j=0;j&lt;4;j++){
      ctx.fillRect(5+i*14,5+j*37.5,14,27.5)
    }
  }
}</pre>
<h2 id="Line_styles" name="Line_styles"><span class="goog-gtc-unit" id="goog-gtc-unit-134"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Estilos de línea</span></span></h2>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-135"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Hay varias propiedades que nos permiten aplicar estilo a las líneas.</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>lineWidth</strong> = value</code><br>
<code><strong>lineCap</strong> = type</code><br>
<code><strong>lineJoin</strong> = type</code><br>
<code><strong>miterLimit</strong> = value</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-136"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Podría describirlas en detalle, pero probablemente se resultará más claro con sólo mirar los ejemplos a continuación.</span></span></p>
<h4 id="A_lineWidth_example" name="A_lineWidth_example"><span class="goog-gtc-unit" id="goog-gtc-unit-137"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Un ejemplo de <code>lineWidth</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-138"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr"><img align="right" alt="" class="internal" src="http://translate.google.com/@api/deki/files/90/=Canvas_linewidth.png"> Esta propiedad establece el grosor de la línea actual.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-139"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Los valores deben ser </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/90/=Canvas_linewidth.png"><span class="goog-gtc-unit" id="goog-gtc-unit-139"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">números positivos.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-140"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr">Por defecto, este valor se establece en 1.0 unidades.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-141"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">El ancho de línea es el espesor del trazo centrado en la ruta dada.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-142"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En otras palabras, el área que se dibuja se extiende hasta la mitad del ancho de la línea a cada lado de la ruta.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-143"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Debido a que las coordenadas del lienzo no hacen referencia directamente a los píxeles, se debe prestar especial atención para obtener líneas horizontales y verticales nítidas.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-144"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En el siguiente ejemplo, se dibujan 10 líneas rectas con anchos de línea cada vez mayores.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-145"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">La línea en el extremo izquierdo es de 1.0 unidades de ancho.</span></span> Sin embargo, la línea más a la izquierda y todas las demás cuyo grosor tiene un ancho impar no tienen un borde nítido debido al posicionamiento de la ruta.</p>
<p><a href="/samples/canvas-tutorial/4_5_canvas_linewidth.html" title="samples/canvas-tutorial/4 5 canvas linewidth.html"><span class="goog-gtc-unit" id="goog-gtc-unit-147"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i = 0; i &lt; 10; i++){
    ctx.lineWidth = 1+i;
    ctx.beginPath();
    ctx.moveTo(5+i*14,5);
    ctx.lineTo(5+i*14,140);
    ctx.stroke();
  }
}</pre>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-158"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Para obtener líneas nítidas se necesita comprender cómo se trazan las rutas.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-159"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En las imágenes de abajo, la cuadrícula representa la cuadrícula de las coordinadas del lienzo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-160"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Los cuadrados entre las líneas de división son en píxeles reales en pantalla.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-161"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">En la primera imagen de la cuadrícula de abajo, está relleno un rectángulo desde (2,1) hasta (5,5).</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-162"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Toda la zona entre ellos (rojo claro) se encuentre dentro de los límites del píxel, por lo que el rectángulo relleno resultante tendrá bordes nítidos.</span></span></p>
<p><img align="center" alt="" class="internal" src="/@api/deki/files/601/=Canvas-grid.png"></p>
<p><img align="center" alt="" class="internal" src="http://translate.google.com/@api/deki/files/601/=Canvas-grid.png"></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-163"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr">Si consideras una ruta desde (3,1) hasta (3,5) con un grosor de línea de 1.0, obtendrás el resultado que se muestra en la segunda imagen.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-164"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El área real que se va a rellenar (azul oscuro), sólo se extiende hasta la mitad de los píxeles situados a cada lado de la ruta.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-165"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Se tiene que representar una aproximación de esto, lo que significa que dichos píxeles se sombrean sólo parcialmente, dando como resultado que toda la zona (azul claro y azul oscuro) se rellene con un color sólo la mitad de oscuro que el color del trazo actual.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-166"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esto es lo que sucede con la línea de ancho de 1.0 en el código del ejemplo anterior.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-167"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Para solucionar este problema, tienes que ser muy preciso a la hora de crear la ruta.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-168"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Sabiendo que una línea de ancho 1.0 se extenderá la mitad de una unidad a cada lado de la ruta, la creación de la ruta desde (3.5,1) hasta (3.5,5) da como resultado lo que vemos en la tercera imagen: el ancho de línea 1.0 termina rellenando por completo y con precisión una sola línea vertical de píxeles.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-169"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Para las líneas de ancho par, cada mitad termina siendo una cantidad entera de píxeles, por lo que es mejor una ruta que esté entre los píxeles (es decir, (3,1) a (3,5)), en lugar de por debajo de la mitad de los píxeles.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-170"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Además, ten en cuenta que en nuestro ejemplo de línea vertical, la posición Y todavía hacía referencia a una posición de línea de cuadrícula entera; de no haber sido así, veríamos píxeles con la mitad de la cobertura en los extremos.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-171"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">A pesar de que resulta un tanto difícil empezar a trabajar con los gráficos 2D escalables, si prestas atención a la cuadrícula de píxeles y a la posición de las rutas, te asegurarás de que tus dibujos queden correctos, independientemente de la escala o de otras transformaciones que se tengan que hacer.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-172"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Una línea vertical de 1.0 de ancho trazada en la posición correcta se convertirá en una línea nítida de 2 píxeles cuando se escale a 2, y aparecerá en la posición correcta.</span></span></p>
<h4 id="A_lineCap_example" name="A_lineCap_example"><span class="goog-gtc-unit" id="goog-gtc-unit-173"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de <code>lineCap</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-174"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La propiedad <code>lineCap</code> determina cómo se dibujan los puntos finales de cada </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/88/=Canvas_linecap.png"><span class="goog-gtc-unit" id="goog-gtc-unit-174"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">línea.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-175"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Hay tres posibles valores para esta propiedad y son los siguientes: <code>butt</code> , <code>round</code> y <code>square</code> .</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-176"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">De manera predeterminada, esta propiedad se establece a <code>butt</code> .</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-177"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En este ejemplo, he dibujado tres líneas, cada una con un valor diferente para la propiedad <code>lineCap</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-178"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">También he añadido dos guías para ver las diferencias exactas entre las tres.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-179"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Cada una de estas líneas empieza y termina exactamente en estas guías.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-180"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La línea de la izquierda utiliza la opción predeterminada <code>butt</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-181"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Te darás cuenta de que está dibujado totalmente nivelado con las guías.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-182"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La segunda está configurada para que use la opción <code>round</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-183"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esto añade un semicírculo hasta el final que tiene un radio la mitad del ancho de la línea.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-184"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La línea de la derecha utiliza la opción <code>square</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-185"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Esto añade una caja con un ancho igual y la mitad de la altura del grosor de la línea.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_6_canvas_linecap.html" title="samples/canvas-tutorial/4 6 canvas linecap.html"><span class="goog-gtc-unit" id="goog-gtc-unit-186"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var lineCap = ['butt','round','square'];

  // Dibujar guías
  ctx.strokeStyle = '#09f';
  ctx.beginPath();
  ctx.moveTo(10,10);
  ctx.lineTo(140,10);
  ctx.moveTo(10,140);
  ctx.lineTo(140,140);
  ctx.stroke();

  // Dibujar líneas
  ctx.strokeStyle = 'black';
  for (var i=0;i&lt;lineCap.length;i++){
    ctx.lineWidth = 15;
    ctx.lineCap = lineCap[i];
    ctx.beginPath();
    ctx.moveTo(25+i*50,10);
    ctx.lineTo(25+i*50,140);
    ctx.stroke();
  }
}</pre>
<h4 id="A_lineJoin_example" name="A_lineJoin_example"><span class="goog-gtc-unit" id="goog-gtc-unit-209"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de <code>lineJoin</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-210"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La propiedad <code>lineJoin</code> determina cómo dos líneas conectadas de una forma se </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/89/=Canvas_linejoin.png"><span class="goog-gtc-unit" id="goog-gtc-unit-210"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">unen entre sí.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-211"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Hay tres posibles valores para esta propiedad: <code>round</code> , <code>bevel</code> y <code>miter</code> .</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-212"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">De manera predeterminada esta propiedad se establece en <code>miter</code> .</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-213"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Una vez más he dibujado tres rutas diferentes, cada una con una configuración de la propiedad <code>lineJoin</code> diferente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-214"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La ruta superior utiliza la opción <code>round</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-215"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esta configuración redondea las esquinas de una forma.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-216"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">El radio de estas esquinas redondeadas es igual a la anchura de la línea.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-217"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La segunda línea utiliza la opción bevel y la línea en la parte inferior utiliza la opción miter.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-218"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Cuando se establecen en <code>miter</code> , las líneas se unen mediante la extensión de los bordes exteriores para conectarse a un solo punto.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-219"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esta configuración se efectuará mediante la propiedad <code>miterLimit</code> que se explica a continuación.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_7_canvas_linejoin.html" title="samples/canvas-tutorial/4 7 canvas linejoin.html"><span class="goog-gtc-unit" id="goog-gtc-unit-220"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var lineJoin = ['round','bevel','miter'];
  ctx.lineWidth = 10;
  for (var i=0;i&lt;lineJoin.length;i++){
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(-5,5+i*40);
    ctx.lineTo(35,45+i*40);
    ctx.lineTo(75,5+i*40);
    ctx.lineTo(115,45+i*40);
    ctx.lineTo(155,5+i*40);
    ctx.stroke();
  }
}</pre>
<h4 id="A_demo_of_the_miterLimit_property" name="A_demo_of_the_miterLimit_property"><span class="goog-gtc-unit" id="goog-gtc-unit-236"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Una demostración de la propiedad <code>miterLimit</code> </span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-237"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Como hemos visto en el ejemplo anterior, cuando se unen dos líneas con la </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/91/=Canvas_miterlimit.png"><span class="goog-gtc-unit" id="goog-gtc-unit-237"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">opción <code>miter</code>, los bordes exteriores de estas dos líneas se extienden hasta el punto donde se encuentran.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-238"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Para las líneas que forman un ángulo grande con las demás, este punto no está lejos del punto de conexión interior.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-239"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Sin embargo, cuando los ángulos entre cada línea disminuyen, la distancia (longitud de miter) entre estos puntos aumenta de manera exponencial.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-240"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La propiedad <code>miterLimit</code> determina hasta qué distancia se puede colocar el punto de conexión exterior a partir del punto de conexión interior.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-241"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Si dos líneas superan este valor, se dibujará una unión biselada.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-242"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">He hecho una pequeña demostración en la que puedes establecer miterLimit de manera dinámica y ver cómo esto afecta a las formas del lienzo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-243"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Las líneas azules muestran donde están el inicio y los puntos finales para cada una de las líneas del diseño en zig-zag.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_8_canvas_miterlimit.html" title="samples/canvas-tutorial/4 8 canvas miterlimit.html"><span class="goog-gtc-unit" id="goog-gtc-unit-244"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Vea esta demostración</span></span></a></p>
<h2 id="Gradients" name="Gradients"><span class="goog-gtc-unit" id="goog-gtc-unit-245"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Degradados</span></span></h2>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-246"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Al igual que cualquier programa de dibujo normal, podemos rellenar y trazar formas mediante degradados lineales y radiales.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-247"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Creamos un objeto <code>canvasGradient</code> utilizando uno de los métodos siguientes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-248"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Usamos este objeto para asignarlo a las propiedades <code>fillStyle</code> o <code>strokeStyle</code>.</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>createLinearGradient</strong>(x1,y1,x2,y2)</code><br>
<code><strong>createRadialGradient</strong>(x1,y1,r1,x2,y2,r2)</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-249"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El método <code>createLinearGradient</code> toma cuatro argumentos que representan el punto de partida (x1, y1) y el punto final (x2, y2) del degradado.</span></span><br>
<span class="goog-gtc-unit" id="goog-gtc-unit-250"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El método <code>createRadialGradient</code> tiene seis argumentos.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-251"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Los tres primeros argumentos definen un círculo con las coordenadas (x1, y1) y radio r1 y el segundo, un círculo con las coordenadas (x2, y2) y el radio r2.</span></span></p>
<pre class="deki-transform">var lineargradient = ctx.createLinearGradient(0,0,150,150);
var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);</pre>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-254"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Una vez que hemos creado un objeto <code>canvasGradient</code>, podemos asignarle colores utilizando el método <code>addColorStop</code>.</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>addColorStop</strong>(position, color)</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-255"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Este método toma dos argumentos.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-256"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El argumento <code>position</code> (posición) debe ser un número entre 0.0 y 1.0 y define la posición relativa de los colores en el degradado.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-257"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Si se configurara a 0.5, por ejemplo, pondría el color, precisamente, en el centro del degradado.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-258"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El argumento <code>color</code> debe ser una cadena que represente un color CSS (es decir, #FFF, rgba (0,0,0,1), etc.)</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-259"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Puedes agregar tantas paradas de color a un degradado como necesites.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-260"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">A continuación se muestra un degradado lineal muy simple de blanco a negro.</span></span></p>
<pre class="deki-transform">var lineargradient = ctx.createLinearGradient(0,0,150,150);
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(1,'black');</pre>
<h4 id="A_createLinearGradient_example" name="A_createLinearGradient_example"><span class="goog-gtc-unit" id="goog-gtc-unit-264"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de <code>createLinearGradient</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-265"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style=""><img align="right" alt="" class="internal" src="http://translate.google.com/@api/deki/files/87/=Canvas_lineargradient.png"> En este ejemplo, he creado dos degradados diferentes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-266"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En el primero, creo el </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/87/=Canvas_lineargradient.png"><span class="goog-gtc-unit" id="goog-gtc-unit-266"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">degradado de fondo.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-267"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Como puedes ver, he asignado dos colores en la misma posición.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-268"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Lo hacemos así para realizar transiciones de color muy fuertes: en este caso del blanco al verde.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-269"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Normalmente, no importa en qué orden se definen las paradas de color, pero en este caso especial, sí que importa de manera significativa.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-270"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Si mantienes la asignación en el orden que deseas que aparezcan, no supondrá un problema.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-271"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En el segundo degradado, no asigné el color inicial (en la posición 0.0) ya que no era estrictamente necesario.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-272"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Asignar el color negro en la posición 0.5 automáticamente convierte en negro el degradado, desde el principio hasta esta parada.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-273"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Como puedes ver aquí, tanto la propiedad <code>strokeStyle</code> como la <code>fillStyle</code> pueden aceptar un objeto <code>canvasGradient</code> como entrada válida.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_9_canvas_lineargradient.html" title="samples/canvas-tutorial/4 9 canvas lineargradient.html"><span class="goog-gtc-unit" id="goog-gtc-unit-274"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Crear degradados
  var lingrad = ctx.createLinearGradient(0,0,0,150);
  lingrad.addColorStop(0, '#00ABEB');
  lingrad.addColorStop(0.5, '#fff');
  //lingrad.addColorStop(0.5, '#26C000');
  //lingrad.addColorStop(1, '#fff');

  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
  lingrad2.addColorStop(0.5, '#000');
  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');

  // asignar degradados a estilos de relleno y trazo
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;
  
  // dibujar formas
  ctx.fillRect(10,10,130,130);
  ctx.strokeRect(50,50,50,50);

}</pre>
<h4 id="A_createRadialGradient_example" name="A_createRadialGradient_example"><span class="goog-gtc-unit" id="goog-gtc-unit-293"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de <code>createRadialGradient</code> </span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-294"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style=""><img align="right" alt="" class="internal" src="http://translate.google.com/@api/deki/files/96/=Canvas_radialgradient.png"> En este ejemplo, he definido cuatro degradados radiales diferentes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-295"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Como </span></span><img align="right" alt="" class="internal" src="/@api/deki/files/96/=Canvas_radialgradient.png"><span class="goog-gtc-unit" id="goog-gtc-unit-295"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">tenemos el control sobre los puntos de inicio y cierre de la degradados, podemos lograr efectos más complejos de lo que normalmente se tienen en degradados radiales 'clásicos' que vemos en, por ejemplo, Photoshop. (Es decir, un degradado con un punto central único donde aquél (el degradado) se expande hacia afuera en forma circular.)</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-296"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En este caso, he desplazado el punto de partida un poco desde el punto final para lograr un efecto 3D esférico.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-297"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Es mejor tratar de evitar que los círculos interiores y exteriores se solapen, porque esto da lugar a efectos extraños que son difíciles de predecir.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-298"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">La última parada de color en cada uno de los cuatro degradados utiliza un color totalmente transparente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-299"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Si deseas tener una buena transición de ésta a la parada de color anterior, ambos colores deben ser iguales.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-300"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esto no resulta muy evidente a partir del código porque he utilizado dos métodos de color CSS diferentes, excepto en el primer degradado <code>#019F62 = rgba(1,159,98,1)</code></span></span></p>
<p><a href="/samples/canvas-tutorial/4_10_canvas_radialgradient.html" title="samples/canvas-tutorial/4 10 canvas radialgradient.html"><span class="goog-gtc-unit" id="goog-gtc-unit-301"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Crear degradados
  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
  radgrad.addColorStop(0, '#A7D30C');
  radgrad.addColorStop(0.9, '#019F62');
  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
  
  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
  radgrad2.addColorStop(0, '#FF5F98');
  radgrad2.addColorStop(0.75, '#FF0188');
  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
  radgrad3.addColorStop(0, '#00C9FF');
  radgrad3.addColorStop(0.8, '#00B5E2');
  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
  radgrad4.addColorStop(0, '#F4F201');
  radgrad4.addColorStop(0.8, '#E4C700');
  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
  
  // dibujar formas
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0,0,150,150);
}</pre>
<h2 id="Patterns" name="Patterns"><span class="goog-gtc-unit" id="goog-gtc-unit-331"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Diseños</span></span></h2>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-332"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En uno de los ejemplos de la página anterior, he utilizado una serie de bucles para crear un patrón de imágenes.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-333"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Hay, sin embargo, un método mucho más simple: el método <code>createPattern</code>.</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>createPattern</strong>(image,type)</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-334"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Este método toma dos argumentos.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-335"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">"Image" es una referencia a un objeto <code>Image</code> o a un elemento canvas diferente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-336"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">"Type" debe ser una cadena que contenga uno de los siguientes valores: <code>repeat</code> , <code>repeat-x</code> , <code>repeat-y</code> y <code>no-repeat</code> .</span></span></p>
<div class="note"><span class="goog-gtc-unit" id="goog-gtc-unit-337"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><strong>Nota </strong>: En Firefox 1.5 (Gecko 1.8) no funciona usar un elemento canvas como el argumento <code>Image</code>.</span></span></div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-338"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Usamos este método para crear un objeto Pattern que es muy similar a los métodos de degradado que hemos visto anteriormente.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-339"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Una vez que hayamos creado un patrón, podemos asignarlo a las propiedades <code>fillStyle</code> o <code>strokeStyle</code>.</span></span></p>
<pre class="deki-transform">var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img,'repeat');</pre>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-343"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><strong>Nota:</strong> A diferencia del método drawImage, debes asegurarte de que la imagen que usas se carga antes de llamar a este método o el diseño se dibujará de forma incorrecta.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-344"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><strong>Nota:</strong> Firefox en la actualidad sólo admite la propiedad <code>repeat</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-345"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Si asignas cualquier otra, no verás ningún cambio.</span></span></p>
<h4 id="A_createPattern_example" name="A_createPattern_example"><span class="goog-gtc-unit" id="goog-gtc-unit-346"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de <code>createPattern</code></span></span></h4>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-347"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">En este último ejemplo, he creado un patrón que he asignado a la propiedad <code>fillStyle</code>.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-348"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Lo único a destacar es el uso del controlador <code>onload</code> de objeto Image.</span></span> <span class="goog-gtc-unit" id="goog-gtc-unit-349"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Esto es para asegurarse de que la imagen se carga antes de que se le asigne al patrón.</span></span></p>
<p><a href="/samples/canvas-tutorial/4_11_canvas_createpattern.html" title="samples/canvas-tutorial/4 11 canvas createpattern.html"><span class="goog-gtc-unit" id="goog-gtc-unit-350"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<p><img align="right" alt="Source image" class="internal" src="/@api/deki/files/75/=Canvas_createpattern.png"></p>
<p><img align="right" alt="" class="internal" src="http://translate.google.com/@api/deki/files/75/=Canvas_createpattern.png"></p>
<pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // crear objeto de imagen para usar como diseño
  var img = new Image();
  img.src = 'images/wallpaper.png';
  img.onload = function(){

    // crear diseño
    var ptrn = ctx.createPattern(img,'repeat');
    ctx.fillStyle = ptrn;
    ctx.fillRect(0,0,150,150);

  }
}</pre>
<h2 id="Sombras"><span class="goog-gtc-unit" id="goog-gtc-unit-363"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Sombras</span></span></h2>
<div class="geckoVersionNote">
<p><span class="goog-gtc-unit" id="goog-gtc-unit-364"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">{{ gecko_callout_heading ("1.9.1") }}</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-365"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Firefox 3.5 (Gecko 1.9.1) introdujo la compatibilidad para las sombras en los lienzos.</span></span>  <span class="goog-gtc-unit" id="goog-gtc-unit-366"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">El uso de sombras implica sólo cuatro propiedades:</span></span></p>
<div style="border: 1px solid rgb(208, 221, 158); background: none repeat scroll 0% 0% rgb(239, 248, 206); padding-left: 10px;">
<p><code><strong>shadowOffsetX</strong> = float</code><br>
<code><strong>shadowOffsetY</strong> = </code><code>float</code><br>
<code><strong>shadowBlur</strong> = </code><code>float</code><br>
<code><strong>shadowColor</strong> = </code><code>color</code></p>
</div>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-367"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><code>shadowOffsetX</code> y <code>shadowOffsetY</code> indican hasta qué punto se extendería la sombra desde el objeto en las direcciones X e Y, estos valores no se ven afectados por la matriz actual de transformación.</span></span>  <span class="goog-gtc-unit" id="goog-gtc-unit-368"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Utiliza valores negativos para que la sombra se extienda hacia arriba o hacia la izquierda, y los valores positivos para que la sombra se extienda hacia abajo o hacia la derecha.</span></span>  <span class="goog-gtc-unit" id="goog-gtc-unit-369"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">Estos son 0 por defecto.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-370"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><code>shadowBlur</code> indica el tamaño del efecto borroso, este valor no se corresponde con un número de píxeles y no se ve afectado por la matriz actual de transformación.</span></span>  <span class="goog-gtc-unit" id="goog-gtc-unit-371"><span class="goog-gtc-translatable goog-gtc-from-mt" dir="ltr" style="">El valor predeterminado es 0.</span></span></p>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-372"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style=""><code>shadowColor</code> es un valor de color CSS estándar que indica el color del efecto de sombra; de manera predeterminada, es negro totalmente transparente.</span></span></p>
<h3 id="Un_ejemplo_de_texto_sombreado"><span class="goog-gtc-unit" id="goog-gtc-unit-373"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Un ejemplo de texto sombreado</span></span></h3>
<p><span class="goog-gtc-unit" id="goog-gtc-unit-374"><span class="goog-gtc-translatable goog-gtc-from-human" dir="ltr" style="">Este ejemplo dibuja una cadena de texto con un efecto de sombreado.</span></span></p>
<p><a class="internal" href="/@api/deki/files/2906/=shadowed-text.html" title="https://developer.mozilla.org/@api/deki/files/2906/=shadowed-text.html"><span class="goog-gtc-unit" id="goog-gtc-unit-375"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100" dir="ltr" style="">Ver este ejemplo</span></span></a></p>
<p><img align="right" alt="Source image" class="internal" src="/@api/deki/files/2907/=shadowed-string.png"></p>
<p><img align="right" alt="" class="internal" src="http://translate.google.com/@api/deki/files/2907/=shadowed-string.png"></p>
<pre class="deki-transform"><span class="goog-gtc-unit" id="goog-gtc-unit-376"><span class="goog-gtc-translatable goog-gtc-from-tm goog-gtc-from-tm-score-100 goog-gtc-unit-highlight" dir="ltr" style="display: none;">function draw () {</span><div class="gtc-trans-inline-cont goog-inline-block" style="padding: 4px;"><pre class="deki-transform">function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
 
  ctx.font = "20px Times New Roman";
  ctx.fillStyle = "Black";
  ctx.fillText("Sample String", 5, 30);
}</pre>
</div>
</span></pre>
</div>
<p>{{ PreviousNext("Canvas_tutorial/Usar_imágenes", "Tutorial de Canvas/Transformaciones") }}</p>
<p>{{ languages( { "en": "en/Canvas_tutorial/Applying_styles_and_colors",  "zh-tw": "zh_tw/Canvas_教學/套用樣式和色彩", "fr": "fr/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs", "ja": "ja/Canvas_tutorial/Applying_styles_and_colors", "pl": "pl/Przewodnik_po_canvas/Zastosowanie_styl\u00f3w_i_kolor\u00f3w" } ) }}</p>
Revertir a esta revisión