-
Notifications
You must be signed in to change notification settings - Fork 6
/
Mojulo.js
108 lines (93 loc) · 3.03 KB
/
Mojulo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
Mojulo = (function() {
// Constant properties for all mojulo displays
// Possibly should be passable as a options hash, but instead making file-global
var width = 100;
var height = 100;
var interval = 1000 / (10 /* fps */);
// Pad out a string, adding padding to the front until it is the width width
function pad(str, width, padding) {
return Array(width - str.length).join(padding) + str;
}
function Mojulo(equation, canvas) {
this.equation = mathparser.parse(equation); // Generate the equation
this.canvas = canvas;
this.scale = canvas.getAttribute('width') / width;
this.context = canvas.getContext('2d');
this.imageData = this.context.createImageData(width * this.scale, height * this.scale);
this.then = +Date.now();
this.frame = 1;
this.paused = true;
}
Mojulo.prototype = {
play: function() {
this.paused = false;
this.step();
},
pause: function() {
this.paused = true;
},
step: function() {
// Rerun the step() function every animation frame
if (this.paused) return;
requestAnimFrame(this.step.bind(this));
var now = +Date.now();
var delta = now - this.then;
if (delta > interval) {
this.then = now;
this.drawFrame();
this.frame++;
}
},
drawFrame: function() {
var equationContext = {
fns: {
sin: Math.sin,
cos: Math.cos,
tan: Math.tan,
rand: Math.random,
sqrt: Math.sqrt,
abs: Math.abs
},
vars: {
PI: Math.PI,
time: this.frame
}
};
var data = this.imageData.data;
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
// Set the x, y, r and A variables
equationContext.vars.x = x;
equationContext.vars.y = y;
equationContext.vars.r = Math.sqrt(x * x + y * y);
equationContext.vars.A = Math.atan(y / x);
// Get the color
var color = this.equation(equationContext.fns, equationContext.vars);
var R = (color & 0xff0000) >>> 16;
var G = (color & 0x00ff00) >>> 8;
var B = (color & 0x0000ff) >>> 0;
for (var sx = 0; sx < this.scale; sx++) {
for (var sy = 0; sy < this.scale; sy++) {
var i = (((y * this.scale + sy) * width * this.scale) + (x * this.scale + sx)) * 4;
this.imageData.data[i] = R;
this.imageData.data[i+1] = G;
this.imageData.data[i+2] = B;
this.imageData.data[i+3] = 255;
}
}
}
}
this.context.putImageData(this.imageData, 0, 0);
}
};
var requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 2000);
};
return Mojulo;
})();