Is there a way to draw "stripe" ("digital phosphor" effect) on HTML5 canvas?

I want to draw a moving point on HTML5 canvas that follows a complex path. This I know how to do it; see, for example, the Lorentz attractor as implemented below. But with small dots, it's hard to follow. Is there a way to add a blurry trail behind the point? I can keep the past history of the dots drawn, I just don't know how to make them disappear.

In technical terms, I am assuming it will be a polyline / curve, where the opacity / width / color changes smoothly along the curve. I know how to draw polylines (and can compute Bezier curves if need be), but I don't know how to apply a smooth gradient along a path.

(Digital oscilloscopes solved this "problem" with the Digital Phosphor Oscilloscope effect, where the region emulated the old analog "phosphor" effect: regions caught in the "beam" would take a while to disappear.)

<!DOCTYPE html>
<html>
<head><script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
	var x = 1, y = 0, z = 0, t=0;
	function onTick(timestamp)
	{
		var ctx = document.getElementById('canvas').getContext('2d');
		ctx.clearRect(0, 0, 300, 300);
		ctx.fillStyle = 'black';
		var cx = 150;
		var cy = 150;
		var r = 5;
		var now = timestamp * 0.001;
		var dt = now - t;
		t = now;
		if (dt > 0.1)
			dt = 0.1;
		// Lorenz attractor
		var sigma = 10, rho=28, beta=8/3;
		var dxdt = sigma*(y-x);
		var dydt = x*(rho-z)-y;
		var dzdt = x*y-beta*z;
		x += dt*dxdt;
		y += dt*dydt;
		z += dt*dzdt;
		
		var drawx = cx + r*x;
		var drawy = cy + r*y;
		var rdot = 2;
		ctx.beginPath();
		ctx.arc(drawx, drawy, rdot, 0, 2 * Math.PI, true);
		ctx.fill();
		requestAnimationFrame(onTick);		
	}
	requestAnimationFrame(onTick);
  });
</script></head>
<body>
  <canvas id="canvas" width="300" height="300"/>
  </body>
</html>
      

Run codeHide result


+3


source to share


2 answers


Instead of clearing a rectangle from every frame, just draw it in the alpha channel to keep those previous points for a moment. I replaced your clearRect

on fillRect

fillStyle

to white.

Hold in min, you can adjust the alpha channel, this will make the dot stay longer / shorter. In my code, this is 0.04

in ctx.fillStyle = "rgba(255, 255, 255, 0.04)";

. I just adjusted it lower so that these tracks stay for a long time.



document.addEventListener("DOMContentLoaded", function(event) {
	var x = 1, y = 0, z = 0, t=0;
	function onTick(timestamp)
	{
		var ctx = document.getElementById('canvas').getContext('2d');
		//ctx.clearRect(0, 0, 300, 300);
        ctx.fillStyle = "rgba(255, 255, 255, 0.04)";
        ctx.fillRect(0, 0, 300, 300);
		ctx.fillStyle = 'black';
		var cx = 150;
		var cy = 150;
		var r = 5;
		var now = timestamp * 0.001;
		var dt = now - t;
		t = now;
		if (dt > 0.1)
			dt = 0.1;
		// Lorenz attractor
		var sigma = 10, rho=28, beta=8/3;
		var dxdt = sigma*(y-x);
		var dydt = x*(rho-z)-y;
		var dzdt = x*y-beta*z;
		x += dt*dxdt;
		y += dt*dydt;
		z += dt*dzdt;
		
		var drawx = cx + r*x;
		var drawy = cy + r*y;
		var rdot = 2;
		ctx.beginPath();
		ctx.arc(drawx, drawy, rdot, 0, 2 * Math.PI, true);
		ctx.fill();
		requestAnimationFrame(onTick);		
	}
	requestAnimationFrame(onTick);
  });
      

canvas {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: -1;
}
      

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

Run codeHide result


+3


source


The classic trick was to draw a polyline instead of a single point, changing the color and / or opacity on each vertex of the polyline, the brightest would be the farthest along the path



0


source







All Articles