Blending Colors Tutorial

Radial Gradients Introduction Blending Colors Introduction HTML5 Markup Function loadColors() Function createColors() Create a Gradient Particle Function drawColors() Summary

Blending Colors Introduction

Learn to create beautiful blending colors with HTML5. This tutorial demonstrates one technique to render a set of colors with the global composite operation, lighter. Lighter causes colors to become brighter as they overlap.

If you're unfamiliar with radial gradients see the introduction to radial gradients tutorial.

HTML5 Markup

In the Web page declare a canvas element with id equals cv. Default width and height equal three hundred. However media queries, with style sheets, resize the canvas width to fit the display screen. The resize event handler assigns canvas height and saves the new dimensions.

The Blending Colors example also includes a button users tap to see new colors. Assign an onclick event listener for the button with function, newColors(). Later in this tutorial, JavaScript assigns newColors() to click events on the canvas. Whenever the user taps the canvas, a set of new colors display as well.

<canvas 
 id="cv" 
 width="300" 
 height="300"
>

Your browser doesn't 
support the canvas element.

</canvas>

<button>

 onclick="newColors()" 
 
 title="Tap for New Colors">
 
 Tap for New Colors
 
</button>

The body of the Web page calls JavaScript function loadColors() after the Web page loads, as follows.

<body 
 onload="loadColors()"
>

Declare Variables

The following listing declares an array which maintains colors for a set of radial gradients. Array, A_COLORS, is an array of eight colors. Each color's declared with a red, green, and blue color channel. Color channel values range between zero and two hundred fifty five.

For example the first color displays a red value of 255, green value of 0, and blue value of 0. The first color renders red. The red channel value is at the maximum of 255. The green and blue channels are a the minimum value of 0.

The last color declares red, green, and blue channels as, 128, 255, 64. The last color renders about 50% red, 100% green, and about 25% blue. The last color's a bright green.

The last line, in the following listing, saves the number of colors, to Number N_COLOR_LENGTH. Eight colors within array, A_COLORS, are declared with three color channels per color. Divide the number of entries in array, A_COLORS, which equals 24, by 3 color channels each. 24/3 = 8. The number of colors equals eight.

// Array of color
// channels: 
// red, green, blue
var A_COLORS = [
 255, 0, 0,
 0,255,0,
 0, 0, 255,
 0, 255, 255,
 255,0,255,
 255,255,0,
 255, 0, 255,
 128, 255, 64,
];

// 24 channels divided
// by 3 channels each color:
var N_COLOR_LENGTH = new Number(8); 

Next declare the following set of variables. Number, nDim represents dimensions of the canvas. The canvas resizes, with media queries, in response to screen dimension changes. However function resizeHandler() keeps the canvas square.

Number, nRadiusMax, represents the largest radius per particle of color. Number CIRCUM maintains the circumference of a circle. Variable, canvas, references an HTML5 canvas. Variable, context, references a 2D rendering context. Variable, eDebug, is simply an HTML5 element useful for displaying output during debugging. Variable, eDebug can reference a div, span, p, or any HTML element which displays text. Array, arrayParticles, maintains a set of radial gradients. Number N_PARTICLE_LENGTH declares the number of particles to render and save to array, arrayParticles.

// Default dimensions.
var nDim = new Number(300);
var nRadiusMax = new Number(64);

// Calculate circle
// circumference once.
var CIRCUM = new Number(Math.PI*2);

// 24 channels divided
// by 3 channels each color:
var N_COLOR_LENGTH = new Number(8); 
          
var canvas, context, eDebug = null;

// color particle array:
var arrayParticles = [];
var N_PARTICLE_LENGTH = new Number(64);

Function loadColors()

When the Web page loads save references to the HTML5 canvas, a 2D rendering context, and the debugging element named, eDebug, as follows.

/**
 * Save local variables.
 * Assign event listeners.
 */
function loadColors(){
 
 canvas = document.getElementById("cv");
 
 context = canvas.getContext("2d");
 
 eDebug = document.getElementById("eDebug");

Assign two event listeners. When the user taps the canvas, call function newColors(). When the user rotates a mobile device or resizes the Web browser window, function resizeHandler() activates. Functions newColors() and resizeHandler() are covered later.

canvas.addEventListener(
 'click',
 function () {
 newColors();
 },
 false
);

window.addEventListener(
 'resize',
 function () {
  resizeHandler();
 },
 false
);

Last initialize an empty array of particles and call resizeHandler(). Function resizeHandler() calls newColors() to fill and draw the array with colorful radial gradients. See function newColors() next.

// color particle
// array.
arrayParticles = new Array(
 N_PARTICLE_LENGTH
);

// Save current
// canvas dimension.
// resizeHandler();
resizeHandler();
} 

Function newColors()

Function newColors() calls functions, createColors() and drawColors(), covered next.

function newColors(){
 // Some browsers might
 // not implement the
 // HTML5 2D context.
 if (context == null) return;

 createColors();

 drawColors();

}

Function createColors()

Function createColors() calls particleColors() to a create new radial gradient particle, for each entry in the array named, arrayParticles. Function createColors() iterates over array, arrayParticles. Number, N_PARTICLE_LENGTH, maintains the length of the array of radial gradient particles. Number, N_COLOR_LENGTH, maintains the length of the array of colors.

Function createColors() assigns local variable, j, values corresponding to entries in array, ARRAY_COLORS. Reuse colors for a number of particles. Number, j, is an index into the color array. Pass an index into the color array as the only parameter to particleColor(). Read about function particleColor(), next.

/**
 * Create an array
 * of radial gradient
 * 'particles'.
 */
function createColors(){

var j = Number(0);

for(var i = 0; i <  N_PARTICLE_LENGTH; i++)
{ 
  arrayParticles[i] = new particleColor(j);
  j++;
  if (j > N_COLOR_LENGTH){
   j = Number(0);
  }
 }
}

Create a Gradient Particle

Function particleColor() creates a new particle representing a colorful radial gradient. The only parameter to, particleColor(), is a number which indexes into the array of colors. The color array's described in the section titled Declare Variables.

First create random X and Y coordinates for the center of this particle. Values returned from built in JavaScript API method, Math.random(), range between 0.0 and 1.0. Multiply each random value by canvas dimensions, as follows.

/**
 * @param {Number} n:
 * index into array of 
 * color channels.
 */
function particleColor(n)
{
 
// Random X and Y
// circle coordinates
// Limited to maximum diameter.
this.nX = Math.random() * nDim;
this.nY = Math.random() * nDim;

Generate a random radius for the radial gradient. The radius won't exceed variable nRadiusMax.

// Random radius 
// limited to maximum radius.
this.radius = Math.random() * nRadiusMax; 

Create a radial gradient. Center both circles of the gradient at X and Y coordinates, (this.nX,this.nY). The inner radius equals zero. Use the random radius value, this.radius, for the outer radius.

 
// inner circle: X,Y coordinate 
// plus radius.
// outter cirlce: X,Y coordinate
// plus radius.
this.gradient = context.createRadialGradient(
 this.nX, 
 this.nY, 
 0, 
 this.nX, 
 this.nY, 
 this.radius
);

Use colors from the array of colors for the red, green, and blue values of this particular gradient. Number, n, indexes into the array of colors. A_COLORS[n] is the red channel. A_COLORS[n + 1] is the green channel. A_COLORS[n + 2] is the blue channel.

// Red, green, and
// blue color channels
// from predefined array
// of colors.
var nR = A_COLORS[n];
var nG = A_COLORS[n + 1];
var nB = A_COLORS[n + 2];

Create an rgba color string with the following line.

var sColor = "rgba("+nR+","+nG+","+nB;

Add three color stops. The first color stop, for the center of the radial gradient, has an alpha value of 1.0, or completely opaque. The second color stop, has an alpha value of 0.6, or partially transparent.

The second color stop's located about one quarter of the radius, away from the origin of the gradient's circle. The first parameter to addColorStop() represents distance from the radial gradient's origin. The second color stop's first parameter equals, 0.25, or one quarter.

The first and second color stops, use color prepared from the color array, A_COLORS. The third color stop, for the perimeter of the gradient, is black with completely transparent alpha. Color stops increase in transparency from 1.0 to 0.6 and finally, 0.0. Gradients appear to feather toward the edges, with increased transparency toward the edges.

Last return the particle colored radial gradient.

 
// alpha 1.0 for
// circle in center.
this.gradient.addColorStop(
 0,
 sColor+ ",1.0)"
);

// Alpha 0.6 at
// starts at
// one quarter of
// the diameter.
this.gradient.addColorStop(
 0.25,sColor+ ",0.6)"
); 

// Alpha 0 at
// circle's perimeter.
this.gradient.addColorStop(
 1,sColor+ ",0.0)"
); 

// Alpha 0 at
// circle's perimeter.
this.gradient.addColorStop(
 1,sColor+ ",0.0)"
); 

return this;
}

See the entire particleColor() function.

Function drawColors()

Function drawColors() renders each radial gradient to the canvas. As gradients overlap, colors become brighter. First, drawColors() assigns the default global composite operation before drawing. The default value equals source-over.

context.globalCompositeOperation = "source-over";

Second fill the canvas with black, as follows.

context.fillStyle = "black"; 
 context.fillRect(
  0,
  0,
  nDim,
  nDim
 ); 

Assign the global composite operation, lighter, before drawing every radial gradient in the array. Lighter adds together, overlapping color channels.

context.globalCompositeOperation = "lighter";

Last iterate over every radial gradient in array, arrayParticles. Draw each radial gradient using the particle's gradient, X and Y coordinates, and radius. Reuse shared variable, CIRCUM, to draw an entire circle. Number, CIRCUM, maintains the length of the circumference of circle.

 for (var i = 0; i < N_PARTICLE_LENGTH; i++){ 
  var p = arrayParticles[i];
  context.beginPath(); 
  context.fillStyle = p.gradient;
  context.arc(
   p.nX, 
   p.nY, 
   p.radius, 
   0, 
   CIRCUM
  );
  context.fill();    
 } 

See the entire drawColors() function.

Function resizeHandler()

Style sheets with media queries adjust canvas width based on orientation and screen width. Function resizeHandler() adjusts canvas height and saves the new dimension to number, nDim, as follows.

function resizeHandler(){

 nDim = canvas.clientWidth;
 
 canvas.width = nDim;
 
 canvas.height = nDim;
 
 newColors();
 
}

Optimize

This example could benefit from a few optimization techniques. For example, prepare each set of radial gradients a little faster. Store the array of colors as strings, where each color's ready to assign as a radial gradient stop color. For example, the first entry in the array follows.

"rgba(255,0,0"

Perhaps create just one array of radial gradients. When the user taps the canvas, simply change the radius and coordinates of each gradient.

Summary

You learned to create beautiful blending colors with HTML5. This tutorial demonstrated one technique to render a set of colors with the global composite operation, lighter. Lighter causes colors to become brighter as they overlap. Enjoy more visual effects examples and tutorials. See the blending colors source code.

Ad for 3D Marketing Learn 3D Programming Ad
Copyright © 2015 Seven Thunder Software. All Rights Reserved.