Introduction


Creating a Canvas


HTML5 Canvas is used to draw graphics on a webpage via scripting in JavaScript. It can be used to draw graphs and animations.

To create a canvas we just use the <canvas> element as shown below:

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <!-- Create a fixed-size drawing surface -->
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Description of content
    </canvas>
  </body>
</html>

It's always a good idea to provide fallback content for browsers that do not support canvas. In the example above we have provided a text description of the canvas content but we could have also provided a static image of the dynamically rendered content.

Result

To use the canvas we have to access it via JavaScript as shown below:

<script>
  var canvas = document.getElementById('c');
  // Check for canvas support
  if (canvas.getContext) {
    // Access the rendering context
    var context = canvas.getContext("2d");
  }
</script>

To display something on the canvas, we first need to access the rendering context. In this tutorial, we focus on the 2D rendering context but there are other contexts available. An if statement is included to check support programmatically.

The 2d rendering context in canvas uses a Cartesian coordinate system, with the origin point (0, 0) at the top left:

2D grid

Draw images onto Canvas


Example 1

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <!-- Create a fixed-size drawing surface -->
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Draw images
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {
        // Access the rendering context
        var context = canvas.getContext('2d');
        // Create image
        var img = new Image();
        // Set the image source
        img.src = '../images/400x400.png';
        // When the resource is loaded
        img.onload = function () {
          console.log('Image has been loaded');
          // Draw image onto canvas
          context.drawImage(img, 0, 0, canvas.width, canvas.height);
        }
      }
    </script>
  </body>
</html>

Result

Example 2

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <!-- Create a fixed-size drawing surface -->
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Draw images
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {
        // Access the rendering context
        var context = canvas.getContext('2d');
        // Create image
        var img = new Image();
        // Set the image source
        img.src = '../images/400x400.png';
        // When the resource is loaded
        img.onload = function () {
          console.log('Image has been loaded');
          // Draw images onto canvas
          context.drawImage(img, 0, 0, canvas.width/2, canvas.height/2);
          context.drawImage(img, canvas.width/2, 0, canvas.width/2, canvas.height/2);
          context.drawImage(img, 0, canvas.height/2, canvas.width/2, canvas.height/2);
          context.drawImage(img, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2);
        }
      }
    </script>
  </body>
</html>

Result

Drawing rectangles


fillRect(x, y, width, height)
Draw a filled rectangle.
strokeRect(x, y, width, height)
Draw a rectangular outline.
clearRect(x, y, width, height)
Clear the specified rectangular area, making it fully transparent.
context.fillStyle = color;
context.fillStyle = gradient;
context.fillStyle = pattern;
Specify the color or style to use inside shapes.
context.strokeStyle = color;
context.strokeStyle = gradient;
context.strokeStyle = pattern;
Specify the color or style to use for the lines around shapes.

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Rectangles using fillRect() & strokeRect()
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {
        // Access the rendering context
        var context = canvas.getContext('2d');
        // Specify the color or style to use inside shapes
        context.fillStyle = "#007f7f";
        // Draw a filled rectangle
        context.fillRect(0, 0, 200, 200);
        // Clear the specified rectangular area (left eye)
        context.clearRect(35, 35, 50, 50);
        // Draw a rectangular outline (left eye)
        context.strokeRect(45, 45, 30, 30);
        // Clear the specified rectangular area (right eye)
        context.clearRect(115, 35, 50, 50);
        // Draw a rectangular outline (right eye)
        context.strokeRect(125, 45, 30, 30);
        // Clear the specified rectangular area (mouth)
        context.clearRect(35, 140, 130, 30);
      }
    </script>
  </body>
</html>

Note: To erase the entire canvas, you could call: context.clearRect(0, 0, c.width, c.height);

Result

Drawing paths


context.beginPath()
Create a new path for future drawing commands.
context.closePath()
Create a path from the current point back to the starting point.
context.moveTo()
Move the starting point of a new sub-path to the (x, y) coordinates.
context.lineTo()
Connect the last point in the sub-path to the x, y coordinates with a straight line.
context.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
Add an arc to the path which is centered at (x, y) position with radius r starting at startAngle and ending at endAngle. Angles area measured in radians (radians = (PI/180)*degrees).
context.fill()
Draw a solid shape by filling the path's content area.
context.stroke()
Draw the shape by stroking its outline.

Example 1

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Rectangles using paths
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');
        // Specify the color or style to use inside shapes
        context.fillStyle = "#007f7f";

        // Create a new path
        context.beginPath();
        // Path
        context.moveTo(10, 10);
        context.lineTo(110, 10);
        context.lineTo(110, 60);
        context.lineTo(10, 60);
        // Create a path from the current point back to the starting point from (10, 60) to (10, 10)
        context.closePath();
        // Draw
        context.stroke();

        // Create a new path
        context.beginPath();
        // Path
        context.moveTo(10, 70);
        context.lineTo(110, 70);
        context.lineTo(110, 120);
        context.lineTo(10, 120);
        // Create a path from the current point back to the starting point from (10, 120) to (10, 70)
        context.closePath();
        // Draw
        context.fill();

        // Create a new path
        context.beginPath();
        // Clockwise arc (default)
        context.arc(40, 160, 30, 0, Math.PI);
        // Draw semicircle
        context.fill();
        // Anticlockwise arc
        var anticlockwise = true;
        context.arc(100, 160, 30, 0, Math.PI, anticlockwise);
        // Draw semicircle
        context.stroke();
      }
    </script>
  </body>
</html>

Result

Example 2

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Smiley face using arc()
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');
        // Specify the color or style to use inside shapes
        context.fillStyle = "#007f7f";

        // Create a new path
        context.beginPath();
        // Head
        context.arc(100, 100, 75, 0, Math.PI * 2);
        context.moveTo(150, 100);
        // Mouth
        context.arc(100, 100, 50, 0, Math.PI);
        context.moveTo(140, 80);
        // Right eye
        context.arc(130, 80, 10, 0, Math.PI * 2);
        context.moveTo(80, 80);
        // Left eye
        context.arc(70, 80, 10, 0, Math.PI * 2);
        context.stroke();
      }
    </script>
  </body>
</html>

Result

Canvas drawing state


context.save()
Save the entire state of the canvas.
context.restore()
Restore the most recently saved canvas state.

Canvas drawing states are stored on a stack. A drawing state consists of translate, rotate, scale, strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled.

Example

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      save() and restore()
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Specify the color or style to use inside shapes.
        context.fillStyle = "blue";
        // Draw a filled rectangle.
        context.fillRect(0,0,50,50);

        // Specify the color or style to use inside shapes.
        context.fillStyle = "green"
        // Draw a filled rectangle.
        context.fillRect(50,50,50,50);

        // Specify the color or style to use inside shapes.
        context.fillStyle = "blue"
        // Draw a filled rectangle.
        context.fillRect(100,100,50,50);
      }
    </script>
  </body>
</html>

HTML (Save & restore state)

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      save() and restore()
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Specify the color or style to use inside shapes.
        context.fillStyle = "blue";
        // Draw a filled rectangle.
        context.fillRect(0,0,50,50);
        // Save state with blue fill
        context.save();

        // Specify the color or style to use inside shapes.
        context.fillStyle = "green"
        // Draw a filled rectangle.
        context.fillRect(50,50,50,50);

        // Restore to blue fill
        context.restore();
        // Draw a filled rectangle.
        context.fillRect(100,100,50,50);
      }
    </script>
  </body>
</html>

Result

Transformations


context.scale(x, y)
Scale the canvas horizontally and vertically by a given factor.
context.translate(x, y)
Move the canvas and its origin on the grid.
context.rotate(angle)
Rotate the canvas clockwise around the current origin by the angle number of radians.

Note: Transformations apply on all subsequent objects unless the drawing state is restored. It's a good idea to save the canvas state before doing any transformations.

Example

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Transformations
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Save state before doing any transformations
        context.save();
        // Specify the color or style to use inside shapes.
        context.fillStyle = "blue";
        // Scale (1 horizontal unit = 2px, 1 vertical unit = 4px)
        context.scale(2, 4);
        // Draw a filled rectangle: pos(20px,40px), 40px(w)x80px(h)
        context.fillRect(10,10,20,20);

        // Restore previous state (undo scale, undo fillStyle)
        context.restore();
        // Save state before doing any transformations
        context.save();
        // Specify the color or style to use for the lines around shapes.
        context.strokeStyle = "red";
        // Move: origin(100px,100px)
        context.translate(100,100);
        // Draw a rectangular outline: pos(0,0), 20px(w)x20px(h)
        context.strokeRect(0,0,20,20);

        // Restore previous state (undo translate, undo strokeStyle)
        context.restore();
        // Save state before doing any transformations
        context.save();
        // Specify the color or style to use inside shapes.
        context.fillStyle = "green";
        // Move: origin((150px, 150px), origin is the rotation center
        context.translate(150,150);
        // Rotate 45 degrees clockwise
        context.rotate(Math.PI/4);
        // Draw a filled rectangle: pos(150px,150px), 30px(w)x30px(h)
        context.fillRect(0,0,30,30);

        // Restore previous state (undo translate, undo strokeStyle)
        context.restore();
        // Save state before doing any transformations
        context.save();
      }
    </script>
  </body>
</html>

Result

Style & colors


Colors

context.fillStyle = color;
Specify the color or style to use inside shapes.
context.strokeStyle = color;
Specify the color or style to use for the lines around shapes.

Just like CSS, there are several ways to specify color:

context.fillStyle = 'blue';
context.fillStyle = '#0000ff';
context.fillStyle = 'rgb(0,0,255)';
context.fillStyle = 'rgba(0,0,255,1)'

Transparency

context.globalAlpha = transparencyValue
Apply the specified transparency value to all future shapes drawn on the canvas. 0.0 means full transparency and 1.0 means full opacity. The default value is 1.0.
context.strokeStyle = 'rgba(255, 0, 0, 0.5)';
context.fillStyle = 'rgba(255, 0, 0, 0.5)';
Assing transparent colors to stroke and fill style

Line styles

context.lineWidth = value
Sets the width of lines drawn in the future.
context.lineCap = type
Sets the appearance of the ends of lines.

Examples

Example 1

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Grid of rectangles with a random color
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Expected output: 0, 1, 2, ..., max-1
        function getRandomInt(max) {
          return Math.floor(Math.random() * Math.floor(max));
        }

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Save state before doing any transformations
        context.save();

        // Grid of rectangles with a random color
        for (let i = 0; i < 10; i++) {
          for (let j = 0; j < 10; j++) {
            context.fillStyle = 'rgb(' + getRandomInt(256) + ',' + getRandomInt(256) + ',' + getRandomInt(256) + ')';
            context.fillRect(j*20,i*20,20,20);
          }
        }
      }
    </script>
  </body>
</html>

Result

Example 2

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Shades of gray
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Save state before doing any transformations
        context.save();

        // Shades of gray
        var transparencyValue = 0.1;
        for (let i = 0; i < 10; i++) {
          context.globalAlpha = transparencyValue;
          context.fillRect(i*20,0,20,200);
          transparencyValue += 0.1;
        }
      }
    </script>
  </body>
</html>

Result

Example 3

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h2><u>Crisp even-width lines</u></h2>
    <canvas style="display:block;" id="c1" width="200", height="200" style="border:1px solid #000;">
      Lines with increasing line widths
    </canvas>
    <h2><u>Crisp odd-width lines</u></h2>
    <canvas style="display:block;" id="c2" width="200", height="200" style="border:1px solid #000;">
      Lines with increasing line widths
    </canvas>
    <h2><u>Crisp lines</u></h2>
    <canvas style="display:block;" id="c3" width="200", height="200" style="border:1px solid #000;">
      Lines with increasing line widths
    </canvas>
    <script>
      var canvas1 = document.getElementById('c1');
      var canvas2 = document.getElementById('c2');
      var canvas3 = document.getElementById('c3');

      // Check for canvas support
      if (canvas1.getContext) {
        // Access the rendering contexts
        var context1 = canvas1.getContext('2d');
        var context2 = canvas2.getContext('2d');
        var context3 = canvas3.getContext('2d');

        // Save states before doing any transformations
        context1.save();
        context2.save();
        context3.save();

        // Draw lines with increasing line widths
        for (let i = 0; i < 10; i++) {

          // Set the current line thickness
          context1.lineWidth = i + 1;
          context2.lineWidth = i + 1;
          context3.lineWidth = i + 1;

          // Create a new path
          context1.beginPath();
          context2.beginPath();
          context3.beginPath();

          // Canvas 1 (only the even-width lines look crisp)
          context1.moveTo(i*20+10,10);
          context1.lineTo(i*20+10,190);

          // Canvas 2 (only the odd-width lines look crisp)
          context2.moveTo(i*20+10.5,10);
          context2.lineTo(i*20+10.5,190);

          // Canvas 3 (every line looks crisp)
          // even-width lines
          if (context3.lineWidth % 2 === 0) {
            context3.moveTo(i*20+10,10);
            context3.lineTo(i*20+10,190);
          }
          // odd-width lines
          else {
            context3.moveTo(i*20+10.5,10);
            context3.lineTo(i*20+10.5,190);
          }

          // Draw
          context1.stroke();
          context2.stroke();
          context3.stroke();
        }
      }
    </script>
  </body>
</html>

Result

Text


Drawing

context.fillText(text, x, y [, maxWidth])
Fill the specified text at the given position.
context.strokeText(text, x, y [, maxWidth])
Stroke the specified text at the given position.

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="200", height="200" style="border:1px solid #000;">
      Drawing text
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {

        // Access the rendering context
        var context = canvas.getContext('2d');

        // Set text style
        context.font = '30px sans-serif';
        // Draw stroke text
        context.strokeText('Hello World', 10, 30);
        // Set text style
        context.font = '30px serif';
        // Draw fill text
        context.fillText('Hello World', 10, 60);
      }
    </script>
  </body>
</html>

Result

Styling

font = value
Set text style.
textAlign = value
Set text alignment. Beware that the alignment is based on the x value of the fillText() method.
textBaseline = value
Set baseline alignment
direction = value
Set directionality

HTML

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="c" width="260", height="450" style="border:1px solid #000;">
      Styling text
    </canvas>
    <script>
      var canvas = document.getElementById('c');
      // Check for canvas support
      if (canvas.getContext) {
        // Access the rendering context
        var context = canvas.getContext('2d');

        /* TEXT STYLING EXAMPLE */

        // Specify the color to use for the lines around shapes.
        context.strokeStyle = '#007f7f';
        // Set text style
        context.font = 'italic small-caps bold 30px Arial, Helvetica, sans-serif';
        // Set text alignment
        context.textAlign = 'center';
        // Draw stroke text
        context.strokeText('Lorem ipsum', canvas.width / 2, 30);

        /* TEXT ALIGNMENT EXAMPLE */

        context.strokeStyle = 'red';
        // Start a new path
        context.beginPath();
        // Move the starting point of a new sub-path to the (x, y) coordinates.
        context.moveTo(canvas.width / 2, 50);
        // Connect the last point in the sub-path to the x, y coordinates with a straight line.
        context.lineTo(canvas.width / 2, 180);
        // Draw the shape by stroking its outline.
        context.stroke();

        context.font = '20px Arial, Helvetica, sans-serif';
        var alignments = ['left', 'center', 'right', 'start', 'end'];
        var startX = canvas.width / 2;
        var startY = 80;
        var margin = 20;
        alignments.forEach(function (alignment) {
          context.textAlign = alignment;
          // Draw fill text
          context.fillText(alignment, startX, startY);
          startY += margin;
        });

        /* BASELINE ALIGNMENT EXAMPLE */

        // Default text alignment
        context.textAlign = 'start';

        var baselines = ['top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'];
        startX = 10;
        startY = 200;
        margin = 40;
        baselines.forEach(function (baseline) {
          // Set baseline alignment
          context.textBaseline = baseline;
          context.beginPath();
          context.moveTo(startX, startY);
          context.lineTo(canvas.width - startX, startY);
          context.stroke();
          context.fillText('Lorem ipsum (' + baseline + ')', startX, startY);
          startY += margin;
        });

        /* ANOTHER STYLING EXAMPLE */

        context.font = '30px Impact';
        context.textAlign = 'center';

        context.strokeStyle = 'black';
        // Sets the width of lines drawn in the future.
        context.lineWidth = 3;
        context.strokeText('LOREM IPSUM', canvas.width / 2, startY);

        context.fillStyle = 'white';
        context.fillText('LOREM IPSUM', canvas.width / 2, startY);
      }
    </script>
  </body>
</html>

Result

Ad1
advertisement
Ad2
advertisement
Ad3
advertisement
Ad4
advertisement
Ad5
advertisement
Ad6
advertisement