I am writing a pseudo-equalizer on canvas. Link to codepen.io .
<canvas id="equalizer"></canvas> (function ($) { var methods = { init: function (options) { var p = { bar_width: 18, bar_heigth: 11, row_spacing: 15, col_spasing: 23, row:7, //кол-во столбцов col:6, //кол-во колонок speed:100, //скорость подсветки кубиков freq:100, //частота сигнала on:true //включено по умолчанию (true,false) }; if (options) { $.extend(p, options); } var canvas = $(this)[0], ctx = canvas.getContext('2d'), stepOld = [], stepNew = []; ctx.canvas.width = window.innerWidth; ctx.canvas.height = 250; ctx.fillStyle = "rgba(255, 255, 255, 0.6)"; var randomNumber = function (m,n){ m = parseInt(m); n = parseInt(n); return Math.floor( Math.random() * (n - m + 1) ) + m; }, drawCanvas = function(){ var countDrawRows = Math.floor(p.freq/p.speed), drawCount = countDrawRows, exchange = Math.floor(p.row/(countDrawRows>0?countDrawRows:0)), drawRow = function(){ //console.log('draw '+(countDrawRows-drawCount)); ctx.beginPath(); for (var col = 0; col < p.col; col++) { var blocks = exchange*(stepOld[col]-stepNew[col]), rowsNeed = Math.floor(stepOld[col]+(blocks*drawCount)); for (var row = 0; row < rowsNeed; row++) { ctx.rect(col * p.col_spasing, row * p.row_spacing, p.bar_width, p.bar_heigth); } } ctx.closePath(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fill(); drawCount--; if(drawCount>0){ setTimeout(drawRow, p.speed); }else{ stepOld = stepNew; } } drawRow(); }, eqInterval = function(){ for (var col = 0; col < p.col; col++) { stepNew[col] = randomNumber(0,p.row); } drawCanvas(); } if(p.on){ for (var col = 0; col < p.col; col++) { stepOld[col] = randomNumber(0,p.row); } drawCanvas(); eqIntervalId = setInterval(eqInterval,p.freq+10) $(this).data({ 'eqIntId':eqIntervalId, 'eqInt':eqInterval, 'freq':p.freq, 'on':p.on }) }else{ $(this).data({ 'eqIntId':eqIntervalId, 'eqInt':eqInterval, 'freq':p.freq, 'on':p.on }) } }, start: function () { if(!$(this).data('on')){ $(this).data('eqInt')(); var eqIntervalId = setInterval($(this).data('eqInt'),$(this).data('freq')); $(this).data({ 'eqIntId':eqIntervalId, 'on':true }) } }, stop: function () { if($(this).data('on')){ clearInterval($(this).data('eqIntId')); $(this).data({ 'on':false }) var canvas = $(this)[0], ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); } } }; $.fn.liEqualizer = function (method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Метод ' + method + ' в jQuery.liEqualizer не существует'); } }; })(jQuery); $('#equalizer').liEqualizer({ row:13, //кол-во столбцов col: Math.round(window.innerWidth/22), //кол-во колонок speed: 300, //скорость подсветки кубиков freq: 600, //частота сигнала on: true //включено по умолчанию (true,false) }); I can not figure out at what point the variable stepOld = stepNew is assigned.
Now at the beginning of the equalizer rendering, the old values (stepOld) are overwritten by the new ones (stepNew). Because of this, it is impossible to get cuts between the old position and the new one.
How to make the replacement of new values at the right time?