Canvas JavaScript

Lines in Motion

This JavaScript program demonstrates how to draw lines in motion on a canvas element.

LinesInMotion.html

<!DOCTYPE html>
<html>
  <head>
    <title>XoaX.net's Javascript</title>
    <script type="text/javascript" src="LinesInMotion.js"></script>
  </head>
  <body onload="Initialize()">
    <canvas id="idCanvas" width="640" height ="480" style="background-color: #F0F0F0;"></canvas>
  </body>
</html>

LinesInMotion.js

var gqContext2D = null;
var gqMovingLines = null;

function AnimationLoop() {
	gqContext2D.clearRect(0, 0, 640, 480);
	gqMovingLines.mfnAdvance();
	gqMovingLines.mfnDrawLines(gqContext2D);
	setTimeout(AnimationLoop, 50);
}

function Initialize() {
	var qCanvas = document.getElementById("idCanvas");
	gqContext2D = qCanvas.getContext("2d");
	gqMovingLines = new CMovingLines();
	AnimationLoop();
}

function CreateRandowUnitVector() {
	return new CVector(Math.cos(Math.PI*2.0*Math.random()), Math.sin(Math.PI*2.0*Math.random()));
}

function CreateRandowPoint() {
	return new CPoint(639.0*Math.random(), 479.0*Math.random());
}

function CPoint(dX, dY) {
	this.mdX = dX;
	this.mdY = dY;
}

function CVector(dDx, dDy) {
	this.mdDx = dDx;
	this.mdDy = dDy;
}

function CParametricLinearMotion(qP, qV) {
	this.mqP = qP;
	this.mqV = qV;
	this.mdSpeed = 15.0; // This will be one, for now
	this.mfnAdvance = function() {
		// Find any intersections for both and x and y.
		// Determine which is first
		let dNextX = this.mqP.mdX + this.mdSpeed*this.mqV.mdDx;
		if (dNextX > 639.0) {// If x hits reverse it
			this.mqP.mdX = 639.0 + 639.0 - dNextX;
			this.mqV.mdDx = -this.mqV.mdDx;
		} else if (dNextX < 0.0) {
			this.mqP.mdX = -dNextX;
			this.mqV.mdDx = -this.mqV.mdDx;
		} else {
			this.mqP.mdX = dNextX;
		}
		let dNextY = this.mqP.mdY + this.mdSpeed*this.mqV.mdDy;
		if (dNextY > 479.0) {// If x hits reverse it
			this.mqP.mdY = 479.0 + 479.0 - dNextY;
			this.mqV.mdDy = -this.mqV.mdDy;
		} else if (dNextY < 0.0) {
			this.mqP.mdY = -dNextY;
			this.mqV.mdDy = -this.mqV.mdDy;
		} else {
			this.mqP.mdY = dNextY;
		}
	}
	this.mfnGetPosition = function() {
		return new CPoint(this.mqP.mdX, this.mqP.mdY);
	}
}

// A Line Segment Contructor
function CLineSegment(qP1, qP2) {
	this.mqP1 = qP1;
	this.mqP2 = qP2;
	this.mfnDrawLine = function(qContext2D) {
		// The line width and color will be set elsewhere
		qContext2D.beginPath();
		qContext2D.moveTo(this.mqP1.mdX, this.mqP1.mdY);
		qContext2D.lineTo(this.mqP2.mdX, this.mqP2.mdY);
		qContext2D.stroke();
	}
}

function CMovingLines() {
	// This will have two parametric lines of motion
	// Use the global alpha to draw the lines
	this.mqMotion1 = new CParametricLinearMotion(CreateRandowPoint(), CreateRandowUnitVector());
	this.mqMotion2 = new CParametricLinearMotion(CreateRandowPoint(), CreateRandowUnitVector());
	this.mqaLines = [];
	this.mfnAdvance = function() {
		this.mqMotion1.mfnAdvance();
		this.mqMotion2.mfnAdvance();
		// Add a new line at the first index
		this.mqaLines.unshift(new CLineSegment(this.mqMotion1.mfnGetPosition(), this.mqMotion2.mfnGetPosition()));
		if (this.mqaLines.length > 25) {
			this.mqaLines.pop();
		}
	}
	this.mfnDrawLines = function(qContext2D) {
		gqContext2D.globalAlpha = 1.0;
		gqContext2D.strokeStyle = "black";
		for(var i in this.mqaLines) {
			this.mqaLines[i].mfnDrawLine(gqContext2D);
			gqContext2D.globalAlpha *= 0.75;
		}
		gqContext2D.globalAlpha = 1.0;
	}
}
 

Output

 
 

© 2007–2025 XoaX.net LLC. All rights reserved.