How to create realistic water ripple(s) in html5 canvas using javascript

how to make water ripple(s) effect in html5 canvas using javascript - Nibunan

Html5 canvas is evolving to give the rich graphics on browser without using flash or other plugins. Html5 canvas is being used in many places like games animations and rich user interfaces on web and so on. This article explains how to create the more realistic water ripples effect simulation in html5 canvas using javascript.

Demo

Open with new tab

Source


      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <title>Creating water ripple effect using html5 canvas - Nibunan</title>
      </head>
      <body style="margin: 0px">
      <canvas width="700" height="450" id="drawing-surface"></canvas>
      <script type="text/javascript">
      function Random(range) {
      return Math.floor((Math.random() * range) + 1);
      }
      function RandomFloat(range) {
      return (Math.random() * range) + 1;
      }
      var viewport = new Viewport()
      viewport.init();

      setInterval(function () {
      var wave = new Wave({ x: Random(window.innerWidth - 100) + 100, y: Random(window.innerHeight - 100) + 100 });
      viewport.addObject(wave);
      }, 500);

      window.onmousedown = function (evt) {
      var wave = new Wave({ x: evt.x, y: evt.y });
      viewport.addObject(wave);
      }
      </script>
      </body>
      </html>
    

Viewport


      function Viewport() {
      var me = this;
      me.objects = [];
      var canvas = document.getElementById("drawing-surface");
      function resizeCanvas() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      }
      resizeCanvas();
      window.onresize = function () {
      resizeCanvas();
      }
      var drawingSurface = document.getElementById("drawing-surface").getContext("2d");
      var image = new Image();
      image.src = "background.jpg";
      image.onload = function () {
      me.backgroundImage = image;
      me.doPaint = true;
      }
      me.doPaint = true;
      function drawBackgroundImage() {
      if (me.backgroundImage) {
      drawingSurface.drawImage(me.backgroundImage, 0, 0, canvas.width, canvas.height);
      }
      }
      function drawObjects() {
      for (var i = 0; i < me.objects.length; i++) {
      me.objects[i].paint(drawingSurface);
      }
      }
      me.paintInit = function () {
      me.doPaint = true;
      }
      function paint() {
      me.paintInit();
      if (me.doPaint) {
      drawBackgroundImage();
      drawObjects();
      me.doPaint = false;
      }
      }
      var timer;
      me.init = function () {
      timer = setInterval(function () { paint(); }, 1000 / 30);
      };
      me.repaint = function () {
      me.doPaint = true;
      };
      me.addObject = function (obj) {
      me.objects.push(obj);
      }
      }
    

Wave Particle


      function WaveParticle(source) {
      var me = this;
      var destroyedListeners = [];
      me.radius = 50;
      me.defaultRadius = 50;
      me.reset = function () {
      me.opacity = 100;
      me.speed = 2;
      me.radius = me.defaultRadius;
      me.startAngle = 0;
      me.endAngle = 359;
      };
      me.reset();
      me.destroyed = function (cb) {
      destroyedListeners.push(cb);
      }
      me.move = function () {
      if (me.opacity <= 0) {
      for (var i = 0; i < destroyedListeners.length; i++) {
      destroyedListeners[i]();
      }
      return false;
      }
      me.radius += me.speed;
      me.opacity -= 1;
      return true;
      };
      me.paint = function (context) {
      if (me.move()) {
      me.drawArc(me.location.x, me.location.y,me.radius,me.startAngle, me.endAngle, context);
      }
      };
      me.getRadialGradient = function (drawingSurface, radius) {
      var grdient = drawingSurface.createRadialGradient(me.location.x, me.location.y, radius - 20, me.location.x, me.location.y, radius);
      grdient.addColorStop(0, "rgba(15,54,156,0)");
      grdient.addColorStop(1, "rgba(50,50,50," + me.opacity / 255 + ")");
      return grdient;
      }
      me.drawArc = function (cx, cy, radius, startAngle, endAngle, drawingSurface) {
      drawingSurface.fillStyle = me.getRadialGradient(drawingSurface, radius);
      drawingSurface.beginPath();
      startAngle = startAngle * (2 / 360);
      endAngle = endAngle * (2 / 360);
      drawingSurface.arc(cx, cy, radius, startAngle * Math.PI, endAngle * Math.PI, false);
      drawingSurface.fill();
      drawingSurface.closePath();
      }
      }
    

Wave


      function Wave(location) {
      var me = this;
      me.location = location;
      me.particles = [];
      me.reset = function () {
      me.particles.splice(0, me.particles.length);
      for (var i = 0; i < 3; i++) {
      var p = new WaveParticle();
      p.location = me.location;
      p.destroyed(function () {
      me.particles.splice(0, me.particles.length);
      });
      p.defaultRadius = (i * 20) + 20;
      p.reset();
      me.particles.push(p);
      }
      };
      me.reset();
      me.move = function () {

      };
      me.paint = function (context) {
      for (var i = 0; i < me.particles.length; i++) {
      me.particles[i].paint(context);
      }
      };
      }