HTML5 Water Ripple Tutorial
Interactive Water Ripples Where You Tap
Introduction
This HTML5 canvas tutorial explains how to create a water ripple effect which responds when you tap the canvas. Use a series of radial gradients to simulate small waves of water.
The water effect draws concentric circles on the canvas, in response to user taps. The circles are composed of radial gradients with alpha transparency. Draw the largest circles first and then the smaller circles. Transparency maximizes the color from the smaller circles in the center.
The water example doesn't take into account scroll
events. If users scroll the window up or down, tap locations are incorrect.
Learn to respond to
scroll
events with the Drag a Sprite
series of tutorials.
If you're unfamiliar with radial gradients see the
Introduction to Radial Gradients Tutorial
.
Coordinates in Response to Taps
When the user taps the canvas calculate the
offset. onclick
event parameters
provide the X and Y coordinates of the browser
window, not the canvas. Therefore
use the canvas' bounding box to
calculate offsets.
Save offsets to the bounding client rectangle
to variable, bb
, representing bounding box.
var bb = canvas.getBoundingClientRect(); nXOffset = bb.left; nYOffset = bb.top;
When the user taps the canvas, calculate the X and Y position within the canvas:
nX = e.pageX - nXOffset; nY = e.pageY - nYOffset;
Use the nX
and nY
coordinates when drawing each gradient circle.
The variable CIRCUM
equals
the circumference of a full circle
calculated with
Math.PI*2
.
gradient = context.createRadialGradient( nX, nY, 0, nX, nY, p.nRadius ); ... context.arc( nX, nY, p.nRadius, 0, CIRCUM );
Particles
Each particle includes properties to draw one radial gradient. The radial gradient looks like one ripple of water with blue concentric circles.
When the Web page loads,
function radWater(n)
executes
for each gradient in an array of gradients.
The array is named arrayWater
.
Number N_PARTICLE_LENGTH
,
determines the number
of water ripples to create.
The following listing creates an array
filled with radial gradients representing
water.
for(var i = 0; i < N_PARTICLE_LENGTH; i++) { arrayWater.push( new radWater( i ) ); }
Each particle includes properties,
rgbEnd,rgbMid
and nRadius
.
String rgbEnd
maintains the ending stop
color and opacity for the gradient.
String rgbMid
represents the middle stop
color and opacity for the gradient.
Number nRadius
is the radius of the
circle.
Property nRadius
increases gradually
as the animation runs.
The function radWater(n)
creates
one radial gradient, as follows.
Function radWater(n)
is listed below.
function radWater( n ) { var j = n % 2; // The starting radius // for the gradient: this.nRadius = new Number( aCircleDimensions[n] ); switch(j){ // The lighter color // for a radial gradient: case 0: // The end stop: this.rgbEnd = new String( "rgba(64, 64, 255, 0.1)" ); // The middle stop: this.rgbMid = new String( "rgba(64, 64, 255, 0.8)" ); break; case 1: // The darker color // for the radial gradient: this.rgbEnd = new String( "rgba(0, 0, 34, 0.1)" ); this.rgbMid = new String( "rgba(0, 0, 34, 0.8)" ); break; } }
Draw Gradients
The function drawConcentricCircles()
iterates
over the Array
of radial gradient ripples
.
drawConcentricCircles()
creates a gradient
from the rgbEnd
and rgbMid
stop color properties of each particle.
Function drawConcentricCircles()
draws an arc with the nRadius
property
of each particle, then increments nRadius
,
for the next loop of the animation.
See the drawConcentricCircles() source code.
Tips
The water ripple effect looks great on personal computers, however it runs rather slowly on older Androids. Decrease the number of gradients for faster playback.
Reducing the number of water ripples
displays the most dramatic performance improvement.
Unfortunately the water looks less realistic
with too few ripples.
However with modifications to the colors, timing, and gradient diameters,
the effect could look good with fewer gradients, as well.
Stop Programmatically
Code stops the animation after a specified number of loops. It's important to have a stopping point on any loop with JavaScript. It's especially important to run short loops, with processor intensive animation. Alpha values require processing power to calculate transparency with color.
If code is going to stop the timer in a function, it's usually best to stop the timer first. Then perform any other clean up operations. Running the timer, can use up processing time.
Photoshop
Color values for the Interactive Water Ripple Example were selected with Photoshop. It's easier to pick colors by eye. It's also faster to run code with prepared colors. You can calculate colors dynamically with code, but animation might slow down noticeably, especially with mobile devices.
Summary
This tutorial explained how to create a water ripple effect which responds when the user taps the canvas. Use a series of radial gradients to simulate small waves of water.
The water effect draws concentric circles on the canvas in response to taps on the canvas. The circles are composed of radial gradients with alpha transparency. Draw the largest circles first and then the smaller circles. Transparency maximizes the color on smaller circles in the center. See the Interactive Water Ripple Source code for more details.
The water example doesn't take into account scroll
events.
If users scroll the window up or down, tap locations are incorrect.
Learn to respond to
scroll
events with the Drag a Sprite
series of tutorials.
tutorial.
If you're unfamiliar with radial gradients see the
Introduction to Radial Gradients Tutorial
.
Web Development Company
Seven Thunder Software's Web programming skills include HTML5, CSS3, JavaScript, WebGL, GLSL and some PHP with MySQL and Python 3. Web design skills include Web graphics with Photoshop, animation with After Effects and 3ds Max.