Эффект волны на Canvas

Хотите создать интересный Эффект волны на Canvas, демо которого можно посмотреть здесь? Тогда читайте инструкцию ниже. Создаем блок canvas:


<canvas id="c"></canvas>

Прописываем ему необходимые стили:

canvas {
   display: block; 
}

Дальше пишем скрипт, который запустит нашу волну:

var c = document.getElementById('c'),
ctx = c.getContext('2d'),
cw = c.width = window.innerWidth,
ch = c.height = window.innerHeight,
points = [],
tick = 0,
opt = {
    count: 5,
    range: {
        x: 20,
        y: 80
    },
    duration: {
        min: 20,
        max: 40
    },
    thickness: 10,
    strokeColor: '#444',
    level: .35,
    curved: true
},
rand = function(min, max){
    return Math.floor( (Math.random() * (max - min + 1) ) + min);
},
ease = function (t, b, c, d) {
    if ((t/=d/2) < 1) return c/2*t*t + b; 
    return -c/2 * ((--t)*(t-2) - 1) + b;
};

ctx.lineJoin = 'round';
ctx.lineWidth = opt.thickness;
ctx.strokeStyle = opt.strokeColor;

var Point = function(config){
   this.anchorX = config.x;
   this.anchorY = config.y;
   this.x = config.x;
   this.y = config.y;
   this.setTarget(); 
};

Point.prototype.setTarget = function(){
   this.initialX = this.x;
   this.initialY = this.y;
   this.targetX = this.anchorX + rand(0, opt.range.x * 2) - opt.range.x;
   this.targetY = this.anchorY + rand(0, opt.range.y * 2) - opt.range.y;
   this.tick = 0;
   this.duration = rand(opt.duration.min, opt.duration.max);
}

Point.prototype.update = function(){
   var dx = this.targetX - this.x;
   var dy = this.targetY - this.y;
   var dist = Math.sqrt(dx * dx + dy * dy);
 
   if(Math.abs(dist) <= 0){
       this.setTarget();
   } else { 
       var t = this.tick;
       var b = this.initialY;
       var c = this.targetY - this.initialY;
       var d = this.duration;
       this.y = ease(t, b, c, d);
 
       b = this.initialX;
       c = this.targetX - this.initialX;
       d = this.duration;
       this.x = ease(t, b, c, d);
 
       this.tick++;
   }
};

Point.prototype.render = function(){
   ctx.beginPath();
   ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false);
   ctx.fillStyle = '#000';
   ctx.fill();
};

var updatePoints = function(){
   var i = points.length;
   while(i--){
       points[i].update();
   }
};

var renderPoints = function(){
   var renderPoints = function(){
       var i = points.length;
       while(i--){
           points[i].render();
       }
   };
var renderShape = function(){
   ctx.beginPath();
   var pointCount = points.length;
   ctx.moveTo(points[0].x, points[0].y);
   var i;
   for (i = 0; i < pointCount - 1; i++) {
       var c = (points[i].x + points[i + 1].x) / 2;
       var d = (points[i].y + points[i + 1].y) / 2;
       ctx.quadraticCurveTo(points[i].x, points[i].y, c, d);
   }
   ctx.lineTo(-opt.range.x - opt.thickness, ch + opt.thickness);
   ctx.lineTo(cw + opt.range.x + opt.thickness, ch + opt.thickness);
   ctx.closePath();
   ctx.fillStyle = 'hsl('+(tick/2)+', 80%, 60%)';
   ctx.fill();
   ctx.stroke();
};

var loop = function(){
   window.requestAnimFrame(loop, c);
   tick++;
   clear();
   updatePoints();
   renderShape();
   //renderPoints();
};

var i = opt.count + 2;
var spacing = (cw + (opt.range.x * 2)) / (opt.count-1);
while(i--){
   points.push(
       new Point({
           x: (spacing * (i - 1)) - opt.range.x,
           y: ch - (ch * opt.level)
       })
   );
}

window.requestAnimFrame=function(){
   return window.requestAnimationFrame||window.webkitRequestAnimationFrame||
   window.mozRequestAnimationFrame||window.oRequestAnimationFrame||
   window.msRequestAnimationFrame||function(a){
       window.setTimeout(a,1E3/60)
   }
}();

loop();

Весь скрипт я объянснять не буду, опишу только некоторые визуальные настройки:

  • count — количество точек в волне, на которых будут происходить колебания;
  • range — амплитуды колебаний по оси x и y;
  • duration — скорость колебаний;
  • thickness — толщина верхней линии волны;
  • strokeColor — цвет верхней линии волны;
  • level — насколько волна заполнит собой высоту блока;
  • строка ctx.fillStyle = ‘hsl(‘+(tick/2)+’, 80%, 60%)’; — задает изменение цвета в цветовой модели HSL. Чтобы цвет не менялся, измените строку например на такую — ctx.fillStyle = ‘hsl(0, 80%, 60%)’, тогда волна будет всегда красного цвета.

 

Оцените нашу статью
😡
☹️
😐
☺️
😍
5/5😍1
Комментарии (0)
Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *