init the git repo with an intial working state of the KaiRo-Mandelbrot 4pre application
[mandelbrot.git] / xulapp / chrome / mandelbrot / content / mandelbrot.js
CommitLineData
37b05b56
RK
1var gColorPalette = getColorPalette('kairo');
2
3function drawImage() {
4 var canvas = document.getElementById("mbrotImage");
5 if (canvas.getContext) {
6 var context = canvas.getContext("2d");
7
8 // example:
9 // context.fillStyle = "rgb(200,0,0)";
10 // context.fillRect (10, 10, 55, 50); // x, y, width, height
11 //
12 // context.fillStyle = "rgba(0, 0, 200, 0.5)";
13 // context.fillRect (30, 30, 55, 50);
14
15 var Cr_min = -2.0;
16 var Cr_max = 1.0;
17 var Cr_scale = Cr_max - Cr_min;
18
19 var Ci_min = -1.5;
20 var Ci_max = 1.5;
21 var Ci_scale = Ci_max - Ci_min;
22
23 var iterMax = 500;
24
25 for (var img_x = 0; img_x < canvas.width; img_x++) {
26 for (var img_y = 0; img_y < canvas.height; img_y++) {
27 var C = new complex(Cr_min + (img_x / canvas.width) * Cr_scale,
28 Ci_min + (img_y / canvas.height) * Ci_scale);
29 window.setTimeout(drawPoint, 0, context, img_x, img_y, C, iterMax);
30 }
31 }
32 }
33}
34
35function complex(aReal, aImag) {
36 this.r = aReal;
37 this.i = aImag;
38 this.square = function() {
39 return new complex(this.r * this.r - this.i * this.i,
40 2 * this.r * this.i);
41 }
42 this.dist = function() {
43 return Math.sqrt(this.r * this.r + this.i * this.i);
44 }
45 this.add = function(aComplex) {
46 return new complex(this.r + aComplex.r, this.i + aComplex.i);
47 }
48}
49
50function mandelbrotValue (aC, aIterMax) {
51 var Z = new complex(0.0, 0.0);
52 for (var iter = 0; iter < aIterMax; iter++) {
53 Z = Z.square().add(aC);
54 if (Z.r * Z.r + Z.i * Z.i > 256) { break; }
55 }
56 return iter;
57}
58
59function getColor(aIterValue, aIterMax) {
60 var standardizedValue = Math.round(aIterValue * 1024 / aIterMax);
61 return gColorPalette[standardizedValue];
62 if (aIterValue == aIterMax) {
63 return "rgb(0,0,0)";
64 }
65 else {
66 //return "rgb(" + img_x + "," + img_y + ",0)";
67 return "rgb(255,255,255)";
68 }
69}
70
71function getColorPalette(palName) {
72 var palette = [];
73 switch (palName) {
74 case 'bw':
75 for (var i = 0; i < 1024; i++) {
76 palette[i] = 'rgb(255,255,255)';
77 }
78 palette[1024] = 'rgb(0,0,0)';
79 break;
80 case 'kairo':
81 // outer areas
82 for (var i = 0; i < 32; i++) {
83 var cc1 = Math.floor(i * 127 / 31);
84 var cc2 = 170 - Math.floor(i * 43 / 31);
85 palette[i] = 'rgb(' + cc1 + ',' + cc2 + ',' + cc1 + ')';
86 }
87 // inner areas
88 for (var i = 0; i < 51; i++) {
89 var cc = Math.floor(i * 170 / 50);
90 palette[32 + i] = 'rgb(' + cc + ',0,' + (170 + cc) + ')';
91 }
92 // corona
93 for (var i = 0; i < 101; i++) {
94 var cc = Math.floor(i * 200 / 100);
95 palette[83 + i] = 'rgb(255,' + cc + ',0)';
96 }
97 // inner corona
98 for (var i = 0; i < 201; i++) {
99 var cc1 = 255 - Math.floor(i * 85 / 200);
100 var cc2 = 200 - Math.floor(i * 30 / 200);
101 var cc3 = Math.floor(i * 170 / 200);
102 palette[184 + i] = 'rgb(' + cc1 + ',' + cc2 + ',' + cc3 + ')';
103 }
104 for (var i = 0; i < 301; i++) {
105 var cc1 = 170 - Math.floor(i * 43 / 300);
106 var cc2 = 170 + Math.floor(i * 85 / 300);
107 palette[385 + i] = 'rgb(' + cc1 + ',' + cc1 + ',' + cc2 + ')';
108 }
109 for (var i = 0; i < 338; i++) {
110 var cc = 127 + Math.floor(i * 128 / 337);
111 palette[686 + i] = 'rgb(' + cc + ',' + cc + ',255)';
112 }
113 palette[1024] = 'rgb(0,0,0)';
114 break;
115 case 'rainbow-linear1':
116 for (var i = 0; i < 256; i++) {
117 palette[i] = 'rgb(' + i + ',0,0)';
118 palette[256 + i] = 'rgb(255,' + i + ',0)';
119 palette[512 + i] = 'rgb(' + (255 - i) + ',255,' + i + ')';
120 palette[768 + i] = 'rgb(' + i + ',' + (255 - i) + ',255)';
121 }
122 palette[1024] = 'rgb(0,0,0)';
123 break;
124 }
125/*
126Select Case palnr
127Case 1 'Standard-Palette (QB-Colors)
128 For i = 0 To 1024
129 xx = CInt(i * 500 / 1024 + 2)
130 If xx <= 15 Then clr = xx
131 If xx > 15 Then clr = CInt(Sqr((xx - 15 + 1) * 15 ^ 2 / 485))
132 If xx >= 500 Then clr = 0
133 palette(i) = QBColor(clr)
134 Next
135Case 3 'Regenbogen-Palette 1 (qu.)
136 For i = 0 To 33
137 clr = CInt(i * 255 / 33)
138 palette(i) = RGB(clr, 0, 0)
139 Next
140 For i = 0 To 136
141 clr = CInt(i * 255 / 136)
142 palette(34 + i) = RGB(255, clr, 0)
143 Next
144 For i = 0 To 306
145 clr = CInt(i * 255 / 306)
146 palette(171 + i) = RGB(255 - clr, 255, clr)
147 Next
148 For i = 0 To 545
149 clr = CInt(i * 255 / 545)
150 palette(478 + i) = RGB(clr, 255 - clr, 255)
151 Next
152Case 4 'Regenbogen-Palette 2 (linear)
153 For i = 0 To 204
154 clr = CInt(i * 255 / 204)
155 palette(i) = RGB(255, clr, 0)
156 palette(204 + i) = RGB(255 - clr, 255, 0)
157 palette(409 + i) = RGB(0, 255, clr)
158 palette(614 + i) = RGB(0, 255 - clr, 255)
159 palette(819 + i) = RGB(clr, 0, 255)
160 Next
161Case 5 'Regenbogen-Palette 2 (qu.)
162 For i = 0 To 18
163 clr = CInt(i * 255 / 18)
164 palette(i) = RGB(255, clr, 0)
165 Next
166 For i = 0 To 73
167 clr = CInt(i * 255 / 73)
168 palette(20 + i) = RGB(255 - clr, 255, 0)
169 Next
170 For i = 0 To 167
171 clr = CInt(i * 255 / 167)
172 palette(93 + i) = RGB(0, 255, clr)
173 Next
174 For i = 0 To 297
175 clr = CInt(i * 255 / 297)
176 palette(261 + i) = RGB(0, 255 - clr, 255)
177 Next
178 For i = 0 To 464
179 clr = CInt(i * 255 / 464)
180 palette(559 + i) = RGB(clr, 0, 255)
181 Next
182*/
183 return palette;
184}
185
186function drawPoint(context, img_x, img_y, C, iterMax) {
187 var itVal = mandelbrotValue(C, iterMax);
188 context.fillStyle = getColor(itVal, iterMax);
189 context.fillRect (img_x, img_y, 1, 1); // x, y, width, height
190}
191
192function saveImage() {
193 // should call filepicker!
194 saveCanvas(document.getElementById("mbrotImage"), "/home/robert/temp/canvas-save.png")
195}
196
197// function below is from from http://developer.mozilla.org/en/docs/Code_snippets:Canvas
198function saveCanvas(canvas, destFile) {
199 // convert string filepath to an nsIFile
200 var file = Components.classes["@mozilla.org/file/local;1"]
201 .createInstance(Components.interfaces.nsILocalFile);
202 file.initWithPath(destFile);
203
204 // create a data url from the canvas and then create URIs of the source and targets
205 var io = Components.classes["@mozilla.org/network/io-service;1"]
206 .getService(Components.interfaces.nsIIOService);
207 var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
208 var target = io.newFileURI(file);
209
210 // prepare to save the canvas data
211 var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
212 .createInstance(Components.interfaces.nsIWebBrowserPersist);
213
214 persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
215 persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
216
217 // displays a download dialog (remove these 3 lines for silent download)
218 var xfer = Components.classes["@mozilla.org/transfer;1"]
219 .createInstance(Components.interfaces.nsITransfer);
220 xfer.init(source, target, "", null, null, null, persist);
221 persist.progressListener = xfer;
222
223 // save the canvas data to the file
224 persist.saveURI(source, null, null, null, null, file);
225}
226
227// function below is from http://developer.mozilla.org/en/docs/How_to_Quit_a_XUL_Application
228function quitApp(aForceQuit) {
229 var appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1']
230 .getService(Components.interfaces.nsIAppStartup);
231
232 // eAttemptQuit will try to close each XUL window, but the XUL window can cancel the quit
233 // process if there is unsaved data. eForceQuit will quit no matter what.
234 var quitSeverity = aForceQuit ? Components.interfaces.nsIAppStartup.eForceQuit :
235 Components.interfaces.nsIAppStartup.eAttemptQuit;
236 appStartup.quit(quitSeverity);
237}