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?

  • It is not clear what behavior is now and what needs to be changed. the value of stepOld, changes in the drawRow function when everything is drawn, for example in question it is 1 iteration - Grundy
  • The fact of the matter is that stepOld is changing earlier than planned. The equalizer itself is updated by the variable freq, and the columns by the variable speed. - Tyuk Goberg
  • no one except you knows when the change is planned . In the code there are still places where this variable changes. Without understanding what the current behavior is different from what you want, you can hardly guess what needs to be corrected. - Grundy
  • freq / speed - The number of updates of the slider itself. The problem is: If you output the eqInterval () function in the stepOld, before receiving stepNew and after, but before drawing drawCanvas (), then the data is immediately replaced. Even before the end of the drawing. The problem is in setInterval as I understand it, but I can not find it. - Tyuk Goberg

1 answer 1

It seems the problem was that both variables are in the same visibility of the variables and at the time of receiving stepOld, I received an updated stepNew.

The question was solved by transferring the stepOld assignment to stepNew, via the var variable stepEx.

PS On codepen.io everything is already fixed and changed.