HTML5 Canvas - анимация не работает должным образом - PullRequest
0 голосов
/ 18 октября 2018

Я сделал простой генератор фона, который заставляет bg заполняться кубами (блоками) разного размера.Затем я подготовил функцию для анимации некоторого случайного блока на синий, а затем вернулся к начальному цвету.Я установил интервал для запуска случайного блока каждые 5 секунд.Внутренняя функция состоит из двух циклов (2x100 шагов) с тайм-аутом, установленным на 25 мс (всего 5 секунд).Проблема в том, что цвет консоли меняется, но не на холсте.Можете ли вы найти, что не так, пожалуйста?

Код на jsFiddle, это только для того, чтобы я мог задать вопрос:

var blockSize = 20; // Size of one block
var canW = 200; // Size of canvas
var canH = 100;
var cvsName = 'cvsBg'; // Name of canvas
var color = [0, 0, 0]; // container for changing color
var defaultColor = [0, 0, 0] // container for block color given by prepareBG()
var blueColor = [0, 204, 255]; // color to which is default color changing
var rndPositonW = getRandomInt(0, canW); // random point on Canvas, to select actually changing block
var rndPositonH = getRandomInt(0, canH);
var cSteps = 100; // animation steps between default color and blue color
var cChangeInterval = 5000; // run one block animation  each 5s

var can = document.getElementById(cvsName);
can.width = canW;
can.height = canH;
var ctx = can.getContext('2d');

prepareBG(ctx); //prepare bg with gray colored blocks

setInterval(colorAnimation, cChangeInterval, ctx, rndPositonW, rndPositonH);
// in this interval to do animation: 
//    100 steps from default color to blue
//    100 steps from blue back to default color

function colorAnimation(ctx, cBlockX, cBlockY) {
  var pixelData = ctx.getImageData(cBlockX, cBlockY, 1, 1).data; // get default color at randomly selected point
  defaultColor = [pixelData[0], pixelData[1], pixelData[2]];

  var blockX = Math.floor(cBlockX / blockSize) * blockSize; // get zero coordinated of block under randomly selected point 
  var blockY = Math.floor(cBlockY / blockSize) * blockSize;

  var i, j;
  for (i = 0; i <= cSteps; i++) { // coloring from default color to blue: 100 steps, one step each 25ms (color change interval is 5000 divided by total steps 200 )
    for (j = 0; j < 3; j++) { // compute changing RGB e.g. if i is near 100, color will be almost blue
      color[j] = defaultColor[j] + ((blueColor[j] - defaultColor[j]) / cSteps) * i;
    }
    console.log("Drawing: X=%i, Y=%i, Color=%i,%i,%i", blockX, blockY, color[0], color[1], color[2]);
    setTimeout(drawBlock, cChangeInterval / cSteps / 2, ctx, blockX, blockY, color, blockSize);
  }
  for (i = 0; i <= cSteps; i++) { // coloring from blue color to defalut: 100 steps, one step each 25ms (color change interval is 5000 divided by total steps 200 )
    for (j = 0; j < 3; j++) { // compute changing RGB e.g. if i is near 100, color will be almost default
      color[j] = blueColor[j] - ((blueColor[j] - defaultColor[j]) / cSteps) * i;
    }
    setTimeout(drawBlock, cChangeInterval / cSteps / 2, ctx, blockX, blockY, color, blockSize);
  }
  rndPositonW = getRandomInt(0, canW); // find new random point for next block animation
  rndPositonH = getRandomInt(0, canH);
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function prepareBG(ctx) {
  var x = 0;
  var y = 0;
  var c = 0
  for (x = 0; x <= can.width; x += blockSize) {
    for (y = 0; y <= can.height; y += blockSize) {
      c = getRandomInt(50, 56);
      drawBlock(ctx, x, y, [c, c, c], blockSize);
    }
  }
  //CANVAS will be used as body's background:
  //document.body.style.background = 'url(' + can.toDataURL() + ')';
}

function drawBlock(ctx, x, y, c, blocksize) {
  ctx.fillStyle = 'rgb(' + c[0] + ', ' + c[1] + ', ' + c[2] + ')';
  ctx.fillRect(x, y, blockSize, blockSize);
}
<canvas id="cvsBg">

1 Ответ

0 голосов
/ 18 октября 2018

Отлично, спасибо, Кайидо!Это было мое неправильное понимание того, как работает setTimeout ... Я неправильно ожидал поведения, похожего на паузу, потому что это то, что я искал.

var blockSize = 20; // Size of one block
var canW = 500; // Size of canvas
var canH = 200;
var cvsName = 'cvsBg'; // Name of canvas
var color = [0,0,0]; // container for changing color
var defaultColor = [0,0,0] // container for block color given by prepareBG()
var blueColor = [0,204,255]; // color to which is default color changing
var animationSteps = 30; // total animation steps up & down
var animationPause = 1000; // pause between animations
var animationTime = 1000; // duration of one animation
var animationRunning = false;

var can = document.getElementById(cvsName); 
can.width = canW;
can.height = canH;
var ctx = can.getContext('2d');

prepareBG(ctx); //prepare bg with gray colored blocks

var count = 0;
function update(rndPositonW,rndPositonH) {
  if(!animationRunning) {
    var pixelData = ctx.getImageData(rndPositonW, rndPositonH, 1, 1).data; // get default color at randomly selected point
    defaultColor = [pixelData[0],pixelData[1],pixelData[2]];
    animationRunning = true;
  }
  var blockX = Math.floor(rndPositonW / blockSize) * blockSize; // get zero coordinated of block under randomly selected point 
  var blockY = Math.floor(rndPositonH / blockSize) * blockSize;
  var j;
  for(j=0; j<3; j++){ // compute changing RGB e.g. if i is near 100, color will be almost blue
    if(count < (animationSteps / 2)) color[j] = defaultColor[j] + ((blueColor[j] - defaultColor[j]) / (animationSteps / 2)) * count; //way up
    else color[j] = blueColor[j] - ((blueColor[j] - defaultColor[j]) / (animationSteps / 2)) * (count - (animationSteps / 2)); //way down
  }
  drawBlock(ctx, blockX, blockY, color, blockSize);
  
  if (++count <= animationSteps) {
    setTimeout(update, animationTime / animationSteps, rndPositonW, rndPositonH);
  } else {
    count = 0;
    animationRunning = false;
    setTimeout(update, animationPause, getRandomInt(0, canW), getRandomInt(0, canH));
  }       
}
update(getRandomInt(0, canW), getRandomInt(0, canH));

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
} 

function prepareBG(ctx){     
  var x = 0;
  var y = 0;
  var c = 0
  for (x = 0; x <= can.width; x+=blockSize) {
    for (y = 0; y <= can.height; y+=blockSize) {
      c = getRandomInt(50, 60);
      drawBlock(ctx, x, y, [c,c,c], blockSize);
    }
  }
  //CANVAS will be used as body's background:
  //document.body.style.background = 'url(' + can.toDataURL() + ')';
}

function drawBlock(ctx,x,y,c,blocksize){
  ctx.fillStyle = 'rgb(' + c[0] + ', ' + c[1] + ', ' + c[2] + ')';
  ctx.fillRect(x, y, blockSize, blockSize);
}
<canvas id="cvsBg">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...