W3docs

Gradientes no Canvas

Gradientes no HTML5 Canvas são padrões de cores usados para preencher círculos, retângulos, linhas, texto e muito mais. Conheça os gradientes linear e radial.

Um gradiente, em geral, é um padrão de cores que muda suavemente de uma cor para outra. Os gradientes do HTML5 Canvas permitem preencher ou contornar formas — círculos, retângulos, linhas, texto, caminhos arbitrários — com esse tipo de mistura multicolorida em vez de uma única cor sólida.

Este capítulo aborda os três tipos de gradiente que podem ser criados em um contexto de canvas 2D, como os parâmetros de coordenadas controlam a direção e o tamanho, como addColorStop() posiciona as cores ao longo do gradiente, e vários exemplos executáveis (vertical, diagonal, preenchimentos de texto/caminho e um brilho radial). Se você é novo na API do canvas, comece com a introdução ao HTML5 Canvas, depois com desenho de formas e caminhos, e revise como o sistema de coordenadas do canvas funciona.

Como os gradientes do canvas funcionam

Trabalhar com um gradiente sempre segue os mesmos quatro passos:

  1. Criar um objeto de gradiente com um dos métodos de fábrica do contexto:
    • ctx.createLinearGradient(x0, y0, x1, y1) — um gradiente linear (direcional).
    • ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) — um gradiente radial (circular).
    • ctx.createConicGradient(startAngle, x, y) — um gradiente cônico (varredura angular).
  2. Adicionar dois ou mais pontos de cor com gradient.addColorStop(offset, color).
  3. Atribuir o gradiente a ctx.fillStyle ou ctx.strokeStyle.
  4. Desenhar uma forma (fillRect, fill, stroke, fillText, …). O gradiente é amostrado em todo lugar onde você pinta.

Um ponto importante a entender: as coordenadas do gradiente estão no espaço do canvas (absoluto), não relativas à forma que você preenche. Um gradiente criado de (0, 0) a (300, 0) sempre abrange essa região do canvas. Se você desenhar um retângulo fora desse intervalo, ele receberá a primeira ou a última cor do gradiente (a mais próxima), porque as cores antes do offset 0 e depois do offset 1 são limitadas.

addColorStop(): posicionando as cores

gradient.addColorStop(offset, color) adiciona um ponto de cor ao gradiente.

  • offset — um número entre 0.0 (o início do gradiente) e 1.0 (o fim). Valores fora desse intervalo geram um erro.
  • color — qualquer string de cor CSS: um nome ("green"), hexadecimal ("#14389c"), rgb()/rgba(), ou hsl(). Use o canal alfa (rgba(...)) para pontos de cor transparentes.

São necessários pelo menos dois pontos para uma mistura visível. O offset de cada ponto controla onde a transição ocorre — quanto menor a diferença entre dois offsets, mais abrupta é a mudança de cor entre eles. Espaçamento uniforme resulta em uma mistura suave; agrupamento de offsets cria faixas nítidas.

<!DOCTYPE html>
<html>
  <head>
    <title>Three color stops</title>
    <style>
      canvas { border: 1px solid #cccccc; }
    </style>
  </head>
  <body>
    <canvas id="stopsCanvas" width="300" height="120"></canvas>
    <script>
      const ctx = document.getElementById("stopsCanvas").getContext("2d");
      const grd = ctx.createLinearGradient(0, 0, 300, 0);
      grd.addColorStop(0, "red");      // start
      grd.addColorStop(0.5, "yellow"); // exact middle
      grd.addColorStop(1, "green");    // end
      ctx.fillStyle = grd;
      ctx.fillRect(0, 0, 300, 120);
    </script>
  </body>
</html>

Mova o ponto do meio de 0.5 para 0.85 e a faixa amarela se desloca para a direita, deixando a maior parte da barra como uma mistura de vermelho para amarelo — é o offset controlando o posicionamento.

Gradiente Linear

ctx.createLinearGradient(x0, y0, x1, y1) retorna um gradiente cujas cores mudam ao longo de uma linha reta — o vetor do gradiente que vai do ponto inicial (x0, y0) ao ponto final (x1, y1):

  • x0, y0 — o ponto inicial do gradiente. O ponto de cor no offset 0 é pintado aqui.
  • x1, y1 — o ponto final do gradiente. O ponto de cor no offset 1 é pintado aqui.

A direção da linha entre esses dois pontos define a direção do gradiente, e a distância entre eles define o alcance da mistura. Linhas perpendiculares ao vetor têm uma única cor sólida.

  • Um gradiente horizontal mantém y igual: createLinearGradient(0, 0, 300, 0).
  • Um gradiente vertical mantém x igual: createLinearGradient(0, 0, 0, 200).
  • Um gradiente diagonal altera ambos: createLinearGradient(0, 0, 300, 200).

Lembre-se do sistema de coordenadas do canvas: (0, 0) é o canto superior esquerdo, x aumenta para a direita e y aumenta para baixo.

Exemplo de gradiente linear horizontal usando fillStyle

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      canvas {
        border: 1px solid #cccccc;
      }
    </style>
  </head>
  <body>
    <canvas id="exampleCanvas" width="300" height="150">
      Your browser doesn't support the HTML5 canvas tag.
    </canvas>
    <script>
      var c = document.getElementById("exampleCanvas");
      var ctx = c.getContext("2d");
      var grd = ctx.createLinearGradient(0, 0, 300, 0);
      grd.addColorStop(0, "green");
      grd.addColorStop(1, "whitesmoke");
      ctx.fillStyle = grd;
      ctx.fillRect(20, 20, 260, 110);
    </script>
  </body>
</html>

Como o vetor vai de (0, 0) a (300, 0), a mistura é puramente horizontal: a borda esquerda é verde e a borda direita é whitesmoke.

Exemplo de gradiente linear vertical

Mantenha x igual em ambos os pontos (aqui 0) e altere apenas y para misturar de cima para baixo:

<!DOCTYPE html>
<html>
  <head>
    <title>Vertical gradient</title>
    <style>
      canvas { border: 1px solid #cccccc; }
    </style>
  </head>
  <body>
    <canvas id="verticalCanvas" width="300" height="200"></canvas>
    <script>
      const ctx = document.getElementById("verticalCanvas").getContext("2d");
      // Same x (0), different y → top-to-bottom blend.
      const grd = ctx.createLinearGradient(0, 0, 0, 200);
      grd.addColorStop(0, "#1e3c72"); // top
      grd.addColorStop(1, "#2a5298"); // bottom
      ctx.fillStyle = grd;
      ctx.fillRect(0, 0, 300, 200);
    </script>
  </body>
</html>

Exemplo de gradiente linear diagonal

Altere tanto x quanto y para que o vetor vá de canto a canto:

<!DOCTYPE html>
<html>
  <head>
    <title>Diagonal gradient</title>
    <style>
      canvas { border: 1px solid #cccccc; }
    </style>
  </head>
  <body>
    <canvas id="diagonalCanvas" width="300" height="200"></canvas>
    <script>
      const ctx = document.getElementById("diagonalCanvas").getContext("2d");
      // Vector from the top-left corner to the bottom-right corner.
      const grd = ctx.createLinearGradient(0, 0, 300, 200);
      grd.addColorStop(0, "#ff512f");
      grd.addColorStop(0.5, "#f09819");
      grd.addColorStop(1, "#ffd452");
      ctx.fillStyle = grd;
      ctx.fillRect(0, 0, 300, 200);
    </script>
  </body>
</html>

Exemplo de gradiente linear usando fillStyle com cores diferentes:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      canvas {
        border: 2px solid #202131;
      }
    </style>
  </head>
  <body>
    <canvas id="exampleCanvas" width="500" height="200"></canvas>
    <script>
      var canvas = document.getElementById('exampleCanvas');
      var context = canvas.getContext('2d');
      context.rect(0, 0, 500, 200);
      var linear = context.createLinearGradient(0, 0, 500, 200);
      linear.addColorStop(0, '#297979');
      linear.addColorStop(1, '#2ee035');
      context.fillStyle = linear;
      context.fill();
    </script>
  </body>
</html>

Exemplo de gradiente linear usando fillStyle e strokeStyle:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      canvas {
        border: 5px solid #cccccc;
      }
    </style>
    <script>
      function drawShape() {
        var canvas = document.getElementById('canvasGradient');
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
          var lgrad1 = ctx.createLinearGradient(0, 0, 0, 300);
          lgrad1.addColorStop(0, 'blue');
          lgrad1.addColorStop(0.4, 'lightpink');
          lgrad1.addColorStop(0.5, 'purple');
          lgrad1.addColorStop(1, 'lightsalmon');
          var lgrad2 = ctx.createLinearGradient(0, 50, 0, 150);
          lgrad2.addColorStop(0, '#7afff3');
          lgrad2.addColorStop(0.5, '#191918');
          lgrad2.addColorStop(1, '#7afff3');
          ctx.fillStyle = lgrad1;
          ctx.strokeStyle = lgrad2;
          ctx.fillRect(15, 15, 120, 120);
          ctx.strokeRect(100, 50, 100, 50);
        } else {
          alert('Your browser does not support');
        }
      }
    </script>
  </head>
  <body onload="drawShape();">
    <canvas id="canvasGradient" width="300" height="300"></canvas>
  </body>
</html>

Exemplo de gradiente em texto e em um caminho

Um gradiente não se limita a retângulos — funciona com qualquer preenchimento ou contorno, incluindo texto e caminhos personalizados. Defina-o como fillStyle antes de fillText() (veja desenho de texto no canvas), ou antes de fill()/stroke() em um caminho criado por você (veja desenho no canvas).

<!DOCTYPE html>
<html>
  <head>
    <title>Gradient text and path</title>
    <style>
      canvas { border: 1px solid #cccccc; }
    </style>
  </head>
  <body>
    <canvas id="textCanvas" width="400" height="160"></canvas>
    <script>
      const ctx = document.getElementById("textCanvas").getContext("2d");

      // A gradient spanning the canvas width.
      const grd = ctx.createLinearGradient(0, 0, 400, 0);
      grd.addColorStop(0, "#8e2de2");
      grd.addColorStop(1, "#4a00e0");

      // Fill text with the gradient.
      ctx.font = "bold 48px sans-serif";
      ctx.fillStyle = grd;
      ctx.fillText("Gradient", 30, 70);

      // Stroke a triangular path with the same gradient.
      ctx.beginPath();
      ctx.moveTo(40, 100);
      ctx.lineTo(360, 100);
      ctx.lineTo(200, 145);
      ctx.closePath();
      ctx.lineWidth = 6;
      ctx.strokeStyle = grd;
      ctx.stroke();
    </script>
  </body>
</html>

Gradiente Radial

ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) define um gradiente entre dois círculos. A cor se mistura de fora para dentro do círculo inicial para o círculo final:

  • x0, y0, r0 — o centro (x0, y0) e o raio r0 do círculo inicial (interno). O ponto de cor no offset 0 preenche esse círculo.
  • x1, y1, r1 — o centro (x1, y1) e o raio r1 do círculo final (externo). O ponto de cor no offset 1 é alcançado na borda desse círculo.

Quando ambos os círculos compartilham o mesmo centro, você obtém um brilho perfeitamente concêntrico. Quando o centro do círculo interno é deslocado em relação ao externo, o ponto brilhante se move para um lado — é exatamente assim que se simula uma fonte de luz ou um reflexo brilhante (o exemplo abaixo usa centros deslocados). Fazer r0 maior que 0 produz um núcleo sólido da primeira cor antes de a mistura começar.

Exemplo de gradiente radial com centros deslocados

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      canvas {
        border: 2px solid #cccccc;
      }
    </style>
  </head>
  <body>
    <canvas id="exampleCanvas" width="300" height="150">
      Your browser doesn't support the HTML5 canvas tag.
    </canvas>
    <script>
      var c = document.getElementById("exampleCanvas");
      var ctx = c.getContext("2d");
      var grd = ctx.createRadialGradient(155, 80, 20, 130, 40, 190);
      grd.addColorStop(0, "#14389c");
      grd.addColorStop(1, "white");
      ctx.fillStyle = grd;
      ctx.fillRect(15, 15, 270, 120);
    </script>
  </body>
</html>

Aqui o círculo interno está centrado em (155, 80) com raio 20, enquanto o círculo externo está centrado em (130, 40) com raio 190. Como os centros diferem, o núcleo azul-escuro fica em direção ao canto inferior direito e desvanece para branco fora do centro, dando ao preenchimento uma aparência tridimensional iluminada por um lado.

Exemplo de brilho radial

Um ponto externo totalmente transparente sobre uma região transparente do canvas cria um brilho suave que pode ser sobreposto a outros desenhos. Observe o uso de rgba() para que a borda desvaneça até o nada em vez de até o branco:

<!DOCTYPE html>
<html>
  <head>
    <title>Radial glow</title>
    <style>
      canvas { border: 1px solid #cccccc; background: #11131f; }
    </style>
  </head>
  <body>
    <canvas id="glowCanvas" width="300" height="200"></canvas>
    <script>
      const ctx = document.getElementById("glowCanvas").getContext("2d");
      // Concentric circles: solid core at (150,100), fading out to radius 110.
      const grd = ctx.createRadialGradient(150, 100, 5, 150, 100, 110);
      grd.addColorStop(0, "rgba(255, 214, 102, 1)");   // bright core
      grd.addColorStop(0.4, "rgba(255, 154, 0, 0.6)"); // warm mid
      grd.addColorStop(1, "rgba(255, 154, 0, 0)");     // transparent edge
      ctx.fillStyle = grd;
      ctx.fillRect(0, 0, 300, 200);
    </script>
  </body>
</html>

Gradiente Cônico

ctx.createConicGradient(startAngle, x, y) cria um gradiente que varre as cores em torno de um ponto central, como uma roda de cores ou um gráfico de pizza, em vez de ao longo de uma linha ou entre círculos:

  • startAngle — o ângulo em radianos no qual o offset 0 começa, medido no sentido horário a partir do eixo x positivo.
  • x, y — o ponto central da rotação.

Os pontos de cor são distribuídos ao longo da volta completa, de modo que o offset 0 e o offset 1 se encontram novamente em startAngle. Para evitar uma emenda visível, atribua a mesma cor ao primeiro e ao último ponto.

<!DOCTYPE html>
<html>
  <head>
    <title>Conic gradient</title>
    <style>
      canvas { border: 1px solid #cccccc; }
    </style>
  </head>
  <body>
    <canvas id="conicCanvas" width="200" height="200"></canvas>
    <script>
      const ctx = document.getElementById("conicCanvas").getContext("2d");
      // Sweep starting at the top (-90° = -Math.PI/2), centered at (100,100).
      const grd = ctx.createConicGradient(-Math.PI / 2, 100, 100);
      grd.addColorStop(0, "red");
      grd.addColorStop(0.25, "yellow");
      grd.addColorStop(0.5, "lime");
      grd.addColorStop(0.75, "blue");
      grd.addColorStop(1, "red"); // matches stop 0 → seamless wheel
      ctx.fillStyle = grd;
      ctx.fillRect(0, 0, 200, 200);
    </script>
  </body>
</html>

createConicGradient() é compatível com as versões atuais de todos os principais navegadores (Chrome, Edge, Firefox e Safari). Forneça uma cor sólida de fallback para navegadores muito antigos, caso precise dar suporte a eles.

Prática

Prática
Quais desses métodos são usados para aplicar cores, padrões e gradientes às formas desenhadas no HTML5 Canvas?
Quais desses métodos são usados para aplicar cores, padrões e gradientes às formas desenhadas no HTML5 Canvas?
Prática
O que o argumento offset de addColorStop(offset, color) representa?
O que o argumento offset de addColorStop(offset, color) representa?
Prática
Para fazer um gradiente linear misturar diretamente de cima para baixo, como devem ser definidos os pontos em createLinearGradient(x0, y0, x1, y1)?
Para fazer um gradiente linear misturar diretamente de cima para baixo, como devem ser definidos os pontos em createLinearGradient(x0, y0, x1, y1)?

Capítulos relacionados do canvas

Was this page helpful?