Creating A Time Reversal Effect Using JavaScript
Have you ever wished you could rewind time like a VHS tape? In this fun and visual tutorial, we will show you how to simulate time reversal effect using a dynamic particle system in JavaScript. The simulation will be made of bubbles floating and moving in random in direction with some collision physics.
Whether you are a beginner looking to get hands-on with JavaScript and HTML5 canvas, or you are just here to look at something cool, this tutorial will be good for you. Let get started!
Prerequisites
Before we get started, make sure you have a basic understanding of HTML, CSS, and JavaScript.
- Basic Understanding of HTML, CSS, and JavaScript: Familiarity with the fundamental concepts of HTML for structuring web pages, CSS for styling, and JavaScript for adding interactivity is essential. This tutorial assumes a basic knowledge of these languages.
- Web Browser: Use a modern web browser like Google Chrome, Mozilla Firefox, or Microsoft Edge.
For the purpose of this tutorial, you can download the source files for the demo to help you follow along:
Note: As you test the source files, ensure that you load them within a suitable environment such that all the files are loaded. For offline use, we recommend that you use Live Server and vscode to load the files. Simply open the files in Vscode and run “index.html” using Live Server.
Demo
Here is what we are going to create. If you press down the rewind button, the motion of the bubbles will reverse creating a time reversal effect.
Understanding the Basics
In simple terms, here is what we are going to learn:
- How to use JavaScript classes to create reusable objects (like vectors and bubbles).
- How to draw and animate with HTML5 Canvas.
- How to simulate Brownian motion (random movement).
- How to record and reverse motion data (time sampling).
- Add a "rewind" feature with visual effects like scanlines and jitter to mimic analog media.
Lets Get Started!
Let's start by setting up the basic HTML structure for our project as usual. Create an HTML called "index.html", with a basic HTML web format, and add a canvas element.
Creating the Canvas Element
We start with a simple structure as shown below. The canvas is where will draw our simulation. The button triggers the rewind mode. The style tag handles the CSS for centering, button styles, and background color.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Random Motion VHS</title>
<style>
/* Center the content vertically and horizontally */
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: black;
margin: 0;
}
/* Canvas border for visibility */
canvas {
border: 1px solid white;
}
/* Container to stack canvas and button vertically */
div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* Style for the rewind button */
button {
position: relative;
padding: 10px 20px;
background-color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 10px;
}
/* Button hover effect */
button:hover {
background-color: #bed9f1;
border: 1px solid #bed9f1;
}
/* Button click effect */
button:active {
background-color: #00a1fe;
border: 1px solid #f64e00;
}
</style>
</head>
<body>
<div>
<!-- Drawing area for animation -->
<canvas id="canvas" width="500" height="500" style="background: black"></canvas>
<!-- Button to activate rewind -->
<button id="rewind">Rewind</button>
</div>
</body>
</html>
Lets also add script tag just below the <canvas> section as shown below. Inside this tag, we shall add our JavaScript code.
<script type=text/javascript>
</script>Lets Dive Into the Code
In our JavaScript code, we create classes for the vectors and bubbles to helps simulate the physics of the bubbles. We also create a number of helper functions that will help us carryout different actions such as clearing the screen, and adding special effects.
1.Setting Up the Canvas
This part sets up the canvas environment and essential global variables. These include the canvas itself, its drawing context (ctx), dimensions, and parameters for bubble behavior.
// Get canvas and setup context
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const width = canvas.width;
const height = canvas.height;
const button = document.getElementById("rewind");
// Initialize parameters
const bubbles = [];
const bubble_count = 20;
const sampling_count = 200;
const sample_step = 1.5;
const speed = 1;canvas,ctx: references to the HTML canvas and its 2D context.width,height: dimensions of the canvas.button: the rewind button.bubbles: the array storing all bubble instances.bubble_count: total number of bubbles to create.sampling_count: how many motion history frames are saved for rewind.sample_step: frequency of motion sampling.speed: general velocity multiplier for bubble movement.
2. Vector Class
This utility class represents a 2D vector and includes standard math operations like addition, subtraction, normalization, and scaling. It's used for calculating positions and velocities in a clean, object-oriented way.
// 2D vector utility class for math operations
class vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
add(v) {
return new vector(this.x + v.x, this.y + v.y);
}
sub(v) {
return new vector(this.x - v.x, this.y - v.y);
}
copy() {
return new vector(this.x, this.y);
}
mult(scalar) {
return new vector(this.x * scalar, this.y * scalar);
}
div(scalar) {
return new vector(this.x / scalar, this.y / scalar);
}
normalize() {
const len = Math.sqrt(this.x * this.x + this.y * this.y);
return new vector(this.x / len, this.