How to deal with flickering?

Ignore my drivel. I think I misinterpreted motion blur as flickering. If I do the same in pure JavaScript, I get the same visual effects. Snap works fine.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bounce</title>
    <style>
      body { background: silver; }
      canvas { background: white; }
      span.sign { display: inline-block; white-space: pre; width: 1ch; text-align: center; }
      span.number { display: inline-block; white-space: pre; }
      label { margin-right: 1ex; }
      label:not(:nth-of-type(1)) { margin-left: 3em; }
    </style>
  </head>
  <body>
    <canvas width="1200" height="900"></canvas>
    <div>
      <label>Frame duration:</label><span id="duration"></span> ms
      <label>Time used:</label><span id="timeused"></span>
      <label>Acceleration:</label><span id="acceleration"></span>
      <label>Step δx:</label><span id="stepx"></span>
      <label>Step δy:</label><span id="stepy"></span>
    </div>
  </body>
  <script>
    class DocFloat {
      #value;
      constructor (parent, value, digits) {
	this.sign = document.createElement('span');
	this.sign.setAttribute('class', 'sign');
	this.number = document.createElement('span');
	this.number.setAttribute('class', 'number');
	this.digits = Number(digits);
	this.value = Number(value);
	parent.appendChild(this.sign);
	parent.appendChild(this.number);
      }
      get value() { return this.#value; }
      set value(v) {
	this.#value = v;
	this.sign.innerHTML = v < 0 ? '-' : ' ';
	this.number.innerHTML = Math.abs(v).toFixed(this.digits);
      }
    }
    class Bounce {
      constructor() {
	this.acceleration = new DocFloat(document.getElementById('acceleration'), 20, 2);
	this.duration = new DocFloat(document.getElementById('duration'), 0, 1);
	this.timeused = new DocFloat(document.getElementById('timeused'), 0, 1);
	this.view_canvas = document.querySelector("canvas");
	this.view_context = this.view_canvas.getContext("2d");
	this.draw_canvas = document.createElement('canvas');
	this.draw_canvas.width = this.view_canvas.width;
	this.draw_canvas.height = this.view_canvas.height;
	this.draw_context = this.draw_canvas.getContext("2d");
	this.items = [];
	this.arid = null;
	let last_time = 0;
	this.animation = () => {
	  const frame_time = performance.now();
	  this.duration.value = frame_time - last_time;
	  last_time = frame_time;
	  this.animate();
	  this.draw_context.fillStyle = "rgb(255, 255, 255)";
	  this.draw_context.fillRect(
	    0, 0, this.draw_canvas.width, this.draw_canvas.height);
	  for (const item of this.items) {
	    item.move(this.draw_canvas)
	    item.draw(this.draw_context);
	  }
	  this.view_context.drawImage(this.draw_canvas, 0, 0);
	  this.timeused.value = performance.now() - frame_time;
	};
	this.view_canvas.addEventListener('click', ev => {
	  if (this.arid)
	    this.stop();
	  else
	    this.animate();
	});
	this.view_canvas.addEventListener('wheel', ev => {
	  ev.preventDefault();
	  switch (true) {
	  case ev.deltaY < 0:
	    this.acceleration.value = this.acceleration.value * Math.SQRT2;
	    break;
	  case ev.deltaY > 0:
	    this.acceleration.value = this.acceleration.value / Math.SQRT2;
	    break;
	  }
	});
      }
      animate() {
	this.arid = requestAnimationFrame(this.animation);
      }
      stop() {
	cancelAnimationFrame(this.arid);
	this.arid = null;
      }
    }
    class Ball {
      constructor(game) {
	this.game = game;
	this.x = 100;
	this.y = 100;
	this.r = 20;
	this.twopi = 2 * Math.PI;
	this.dx = Math.SQRT1_2;
	this.dy = Math.SQRT1_2;
	this.stepx = new DocFloat(document.getElementById('stepx'), 0, 1);
	this.stepy = new DocFloat(document.getElementById('stepy'), 0, 1);
	game.items.push(this);
      }
      draw(context) {
	context.beginPath();
	context.fillStyle = "rgb(255 0 0)";
	context.arc(this.x, this.y, this.r, 0, this.twopi);
	context.fill();
      }
      move(canvas) {
	this.stepx.value = this.dx * this.game.acceleration.value;
	this.x += this.stepx.value;
	if (this.x > canvas.width) {
	  this.x = canvas.width - (this.x - canvas.width);
	  this.dx = - this.dx;
	  this.stepx.value = - this.stepx.value;
	}
	if (this.x < 0) {
	  this.x = - this.x
	  this.dx = - this.dx;
	  this.stepx.value = - this.stepx.value;
	}
	this.stepy.value = this.dy * this.game.acceleration.value;
	this.y += this.stepy.value;
	if (this.y > canvas.height) {
	  this.y = canvas.height - (this.y - canvas.height);
	  this.dy = - this.dy;
	  this.stepy.value = - this.stepy.value;
	}
	if (this.y < 0) {
	  this.y = - this.y
	  this.dy = - this.dy;
	  this.stepy.value = - this.stepy.value;
	}
      }
    }
    window.game = new Bounce;
    window.ball = new Ball(window.game);
    window.game.animate();
  </script>
</html>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.