patternjavascriptMinor
Class(es) for animating objects on a canvas
Viewed 0 times
objectsanimatingforclasscanvas
Problem
I'm building a simple canvas animation engine as an exercise in learning ES6. Coming from C++ and Java, I miss static properties, but I've read that "Prototypes having data properties is generally considered an anti-pattern".
The animation engine simulates \$n\$ river waves (simple lines), flowing from right to left in an HTML5 canvas, using
Here's the first stab at this in ES6:
The animation engine simulates \$n\$ river waves (simple lines), flowing from right to left in an HTML5 canvas, using
requestAnimationFrame. Waves come in three lengths, based on a baseLength that should be configurable and have a default: 1x, 5x, and 7x. When creating a new wave, I'm picking one of the lengths at random. All waves have a constant flowing velocity on the x axis. You can see this in motion on CodePen (ES5 approach; ignore the boats).- How should this simple universe be organized into classes? One "
Wave" class with a constructor anddrawmethod, and another "Waves" class with ananimatemethod?
- Should the velocity (same for all waves) be stored at the
Wave, orWaveslevel?
- Is the
static config()method a good idea, or should each property be separate? Let's assume for simplicity we won't build an interface to modify these properties at runtime, but they are to be grouped at the top of the class for easy editing in the code.
- Is it better to use just one class,
Waves, and have acreateWavemethod which the constructor will call \$n\$ times to create all waves? I don't imagine ever needing to create aWavein isolation from its river /Waves.
Here's the first stab at this in ES6:
'use strict';
class Wave {
static config() {
const waveBaseLength = 5;
return {
color: '#4F5E5B',
waveLengths: [waveBaseLength, waveBaseLength 7, waveBaseLength 15],
velocity: 5
}
}
constructor(x, y, velocity) {
this.x = x;
this.y = y;
let waveLengths = Wave.config().waveLengths;
this.l = waveLengths[Math.floor(Math.random() * waveLengths.length)];
this.velocity = velocity || 0.5; // Chrome currently fails at velocity=0.5` in the constructor declaSolution
This is really cool! I do have a few small tips though.
First off, rather than creating an entire function, in this case,
Using this, you can do stuff like
Finally, you have a few, not so great variable names. A few include
First off, rather than creating an entire function, in this case,
config, that returns configuration data, I'd store it as a public getter, like this:class Wave {
static get CONFIG() {
const waveBaseLength = 5;
return {
color: '#4F5E5B',
waveLengths: [waveBaseLength, waveBaseLength * 7, waveBaseLength * 15],
velocity: 5
}
}
}Using this, you can do stuff like
Wave.CONFIG.color, and drop the un-needed parentheses.Finally, you have a few, not so great variable names. A few include
l and n. Names like these should be expanded for clarity and readability.Code Snippets
class Wave {
static get CONFIG() {
const waveBaseLength = 5;
return {
color: '#4F5E5B',
waveLengths: [waveBaseLength, waveBaseLength * 7, waveBaseLength * 15],
velocity: 5
}
}
}Context
StackExchange Code Review Q#96424, answer score: 2
Revisions (0)
No revisions yet.