Canvas Styles and Colours

Add different colors, line styles, gradients, patterns and shadows to canvas elements.

15th August 2022

Time to read: 3 mins

Logo

Colors

If we want to apply colors to a shape, there are two important properties we can use: fillStyle and strokeStyle.

fillStyle = color Sets the style used when filling shapes.

strokeStyle = color Sets the style for shapes' outlines.

color is a string representing a CSS color, a gradient object, or a pattern object. By default, the stroke and fill color are set to black (CSS color value #000000).

// these all set the fillStyle to 'orange'

ctx.fillStyle = 'orange';
ctx.fillStyle = '#FFA500';
ctx.fillStyle = 'rgb(255, 165, 0)';
ctx.fillStyle = 'rgba(255, 165, 0, 1)';

Transparency

We can also draw semi-transparent (or translucent) shapes. This is done by either setting the globalAlpha property or by assigning a semi-transparent color to the stroke and/or fill style.

globalAlpha = transparencyValue

Applies the specified transparency value to all future shapes drawn on the canvas. The value must be between 0.0 (fully transparent) to 1.0 (fully opaque). This value is 1.0 (fully opaque) by default.

The globalAlpha property can be useful if you want to draw a lot of shapes on the canvas with similar transparency, but otherwise it's generally more useful to set the transparency on individual shapes when setting their colors.

// Assigning transparent colors to stroke and fill style

ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';

Line styles

There are several properties which allow us to style lines.

lineWidth = value This property sets the current line thickness. Values must be positive numbers. By default this value is set to 1.0 units.

lineCap = type The lineCap property determines how the end points of every line are drawn. There are three possible values for this property and those are: butt, round and square. By default this property is set to butt.

butt The ends of lines are squared off at the endpoints.

round The ends of lines are rounded.

square The ends of lines are squared off by adding a box with an equal width and half the height of the line's thickness.

lineJoin = type The lineJoin property determines how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are joined together (degenerate segments with zero lengths, whose specified endpoints and control points are exactly at the same position, are skipped). There are three possible values for this property: round, bevel and miter. By default this property is set to miter.

round Rounds off the corners of a shape by filling an additional sector of disc centered at the common endpoint of connected segments. The radius for these rounded corners is equal to half the line width.

bevel Fills an additional triangular area between the common endpoint of connected segments, and the separate outside rectangular corners of each segment.

miter Connected segments are joined by extending their outside edges to connect at a single point, with the effect of filling an additional lozenge-shaped area. This setting is effected by the miterLimit property.

miterLimit = value Establishes a limit on the miter when two lines join at a sharp angle, to let you control how thick the junction becomes. Default value is 10.0.

getLineDash() Returns the current line dash pattern array containing an even number of non-negative numbers.

setLineDash(segments) Sets the current line dash pattern.

lineDashOffset = value Specifies where to start a dash array on a line.

The setLineDash method and the lineDashOffset property specify the dash pattern for lines. The setLineDash method accepts a list of numbers that specifies distances to alternately draw a line and a gap and the lineDashOffset property sets an offset where to start the pattern.


Gradients

We can fill and stroke shapes using linear, radial and conic gradients. We create a CanvasGradient object by using one of the following methods. We can then assign this object to the fillStyle or strokeStyle properties.

createLinearGradient(x1, y1, x2, y2) Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).

createRadialGradient(x1, y1, r1, x2, y2, r2) Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.

createLinearGradient(x1, y1, x2, y2) Creates a conic gradient object with a starting angle of angle in radians, at the position (x, y).

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

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

gradient.addColorStop(position, color) Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS color, indicating the color the gradient should reach at that offset into the transition.

Linear Gradient Example

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

  // Create gradients
  const 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');

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

  // assign gradients to fill and stroke styles
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;

  // draw shapes
  ctx.fillRect(10, 10, 130, 130);
  ctx.strokeRect(50, 50, 50, 50);

}

canvas lineargradient

Radial Gradient Example

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

  // Create gradients
  const 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)');

  const 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)');

  const 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)');

  const 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)');

  // draw shapes
  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);
}

canvas radialgradient

Conic Gradient Example

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

  // Create gradients
  const conicGrad1 = ctx.createConicGradient(2, 62, 75);
  conicGrad1.addColorStop(0, '#A7D30C');
  conicGrad1.addColorStop(1, '#fff');

  const conicGrad2 = ctx.createConicGradient(0, 187, 75);
  // we multiple our values by Math.PI/180 to convert degrees to radians
  conicGrad2.addColorStop(0, 'black');
  conicGrad2.addColorStop(0.25, 'black');
  conicGrad2.addColorStop(0.25, 'white');
  conicGrad2.addColorStop(0.5, 'white');
  conicGrad2.addColorStop(0.5, 'black');
  conicGrad2.addColorStop(0.75, 'black');
  conicGrad2.addColorStop(0.75, 'white');
  conicGrad2.addColorStop(1, 'white');

  // draw shapes
  ctx.fillStyle = conicGrad1;
  ctx.fillRect(12, 25, 100, 100);
  ctx.fillStyle = conicGrad2;
  ctx.fillRect(137, 25, 100, 100);
}

canvas conicgrad


Patterns

We can use the createPattern() method to create a pattern of images.

createPattern(image, type) Creates and returns a new canvas pattern object. image is a the source of the image (that is, an HTMLImageElement, a SVGImageElement, another HTMLCanvasElement or a OffscreenCanvas, an HTMLVideoElement or a VideoFrame, or an ImageBitmap). type is a string indicating how to use the image.

The type specifies how to use the image in order to create the pattern, and must be one of the following string values:

repeat Tiles the image in both vertical and horizontal directions.

repeat-x Tiles the image horizontally but not vertically.

repeat-y Tiles the image vertically but not horizontally.

no-repeat Doesn't tile the image. It's used only once.

Create Pattern Example

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

  // create new image object to use as pattern
  const img = new Image();
  img.src = 'canvas_createpattern.png';
  img.onload = () => {

    // create pattern
    const ptrn = ctx.createPattern(img, 'repeat');
    ctx.fillStyle = ptrn;
    ctx.fillRect(0, 0, 150, 150);

  }
}

pattern


Shadows

Using shadows involves just four properties:

shadowOffsetX = float Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.

shadowOffsetY = float Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.

shadowBlur = float Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

shadowColor = color A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

This example draws a text string with a shadowing effect.

function draw() {
  const 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);
}

shadowed-string