--- /dev/null
+var gColorPalette = getColorPalette('kairo');
+
+function drawImage() {
+ var canvas = document.getElementById("mbrotImage");
+ if (canvas.getContext) {
+ var context = canvas.getContext("2d");
+
+ // example:
+ // context.fillStyle = "rgb(200,0,0)";
+ // context.fillRect (10, 10, 55, 50); // x, y, width, height
+ //
+ // context.fillStyle = "rgba(0, 0, 200, 0.5)";
+ // context.fillRect (30, 30, 55, 50);
+
+ var Cr_min = -2.0;
+ var Cr_max = 1.0;
+ var Cr_scale = Cr_max - Cr_min;
+
+ var Ci_min = -1.5;
+ var Ci_max = 1.5;
+ var Ci_scale = Ci_max - Ci_min;
+
+ var iterMax = 500;
+
+ for (var img_x = 0; img_x < canvas.width; img_x++) {
+ for (var img_y = 0; img_y < canvas.height; img_y++) {
+ var C = new complex(Cr_min + (img_x / canvas.width) * Cr_scale,
+ Ci_min + (img_y / canvas.height) * Ci_scale);
+ window.setTimeout(drawPoint, 0, context, img_x, img_y, C, iterMax);
+ }
+ }
+ }
+}
+
+function complex(aReal, aImag) {
+ this.r = aReal;
+ this.i = aImag;
+ this.square = function() {
+ return new complex(this.r * this.r - this.i * this.i,
+ 2 * this.r * this.i);
+ }
+ this.dist = function() {
+ return Math.sqrt(this.r * this.r + this.i * this.i);
+ }
+ this.add = function(aComplex) {
+ return new complex(this.r + aComplex.r, this.i + aComplex.i);
+ }
+}
+
+function mandelbrotValue (aC, aIterMax) {
+ var Z = new complex(0.0, 0.0);
+ for (var iter = 0; iter < aIterMax; iter++) {
+ Z = Z.square().add(aC);
+ if (Z.r * Z.r + Z.i * Z.i > 256) { break; }
+ }
+ return iter;
+}
+
+function getColor(aIterValue, aIterMax) {
+ var standardizedValue = Math.round(aIterValue * 1024 / aIterMax);
+ return gColorPalette[standardizedValue];
+ if (aIterValue == aIterMax) {
+ return "rgb(0,0,0)";
+ }
+ else {
+ //return "rgb(" + img_x + "," + img_y + ",0)";
+ return "rgb(255,255,255)";
+ }
+}
+
+function getColorPalette(palName) {
+ var palette = [];
+ switch (palName) {
+ case 'bw':
+ for (var i = 0; i < 1024; i++) {
+ palette[i] = 'rgb(255,255,255)';
+ }
+ palette[1024] = 'rgb(0,0,0)';
+ break;
+ case 'kairo':
+ // outer areas
+ for (var i = 0; i < 32; i++) {
+ var cc1 = Math.floor(i * 127 / 31);
+ var cc2 = 170 - Math.floor(i * 43 / 31);
+ palette[i] = 'rgb(' + cc1 + ',' + cc2 + ',' + cc1 + ')';
+ }
+ // inner areas
+ for (var i = 0; i < 51; i++) {
+ var cc = Math.floor(i * 170 / 50);
+ palette[32 + i] = 'rgb(' + cc + ',0,' + (170 + cc) + ')';
+ }
+ // corona
+ for (var i = 0; i < 101; i++) {
+ var cc = Math.floor(i * 200 / 100);
+ palette[83 + i] = 'rgb(255,' + cc + ',0)';
+ }
+ // inner corona
+ for (var i = 0; i < 201; i++) {
+ var cc1 = 255 - Math.floor(i * 85 / 200);
+ var cc2 = 200 - Math.floor(i * 30 / 200);
+ var cc3 = Math.floor(i * 170 / 200);
+ palette[184 + i] = 'rgb(' + cc1 + ',' + cc2 + ',' + cc3 + ')';
+ }
+ for (var i = 0; i < 301; i++) {
+ var cc1 = 170 - Math.floor(i * 43 / 300);
+ var cc2 = 170 + Math.floor(i * 85 / 300);
+ palette[385 + i] = 'rgb(' + cc1 + ',' + cc1 + ',' + cc2 + ')';
+ }
+ for (var i = 0; i < 338; i++) {
+ var cc = 127 + Math.floor(i * 128 / 337);
+ palette[686 + i] = 'rgb(' + cc + ',' + cc + ',255)';
+ }
+ palette[1024] = 'rgb(0,0,0)';
+ break;
+ case 'rainbow-linear1':
+ for (var i = 0; i < 256; i++) {
+ palette[i] = 'rgb(' + i + ',0,0)';
+ palette[256 + i] = 'rgb(255,' + i + ',0)';
+ palette[512 + i] = 'rgb(' + (255 - i) + ',255,' + i + ')';
+ palette[768 + i] = 'rgb(' + i + ',' + (255 - i) + ',255)';
+ }
+ palette[1024] = 'rgb(0,0,0)';
+ break;
+ }
+/*
+Select Case palnr
+Case 1 'Standard-Palette (QB-Colors)
+ For i = 0 To 1024
+ xx = CInt(i * 500 / 1024 + 2)
+ If xx <= 15 Then clr = xx
+ If xx > 15 Then clr = CInt(Sqr((xx - 15 + 1) * 15 ^ 2 / 485))
+ If xx >= 500 Then clr = 0
+ palette(i) = QBColor(clr)
+ Next
+Case 3 'Regenbogen-Palette 1 (qu.)
+ For i = 0 To 33
+ clr = CInt(i * 255 / 33)
+ palette(i) = RGB(clr, 0, 0)
+ Next
+ For i = 0 To 136
+ clr = CInt(i * 255 / 136)
+ palette(34 + i) = RGB(255, clr, 0)
+ Next
+ For i = 0 To 306
+ clr = CInt(i * 255 / 306)
+ palette(171 + i) = RGB(255 - clr, 255, clr)
+ Next
+ For i = 0 To 545
+ clr = CInt(i * 255 / 545)
+ palette(478 + i) = RGB(clr, 255 - clr, 255)
+ Next
+Case 4 'Regenbogen-Palette 2 (linear)
+ For i = 0 To 204
+ clr = CInt(i * 255 / 204)
+ palette(i) = RGB(255, clr, 0)
+ palette(204 + i) = RGB(255 - clr, 255, 0)
+ palette(409 + i) = RGB(0, 255, clr)
+ palette(614 + i) = RGB(0, 255 - clr, 255)
+ palette(819 + i) = RGB(clr, 0, 255)
+ Next
+Case 5 'Regenbogen-Palette 2 (qu.)
+ For i = 0 To 18
+ clr = CInt(i * 255 / 18)
+ palette(i) = RGB(255, clr, 0)
+ Next
+ For i = 0 To 73
+ clr = CInt(i * 255 / 73)
+ palette(20 + i) = RGB(255 - clr, 255, 0)
+ Next
+ For i = 0 To 167
+ clr = CInt(i * 255 / 167)
+ palette(93 + i) = RGB(0, 255, clr)
+ Next
+ For i = 0 To 297
+ clr = CInt(i * 255 / 297)
+ palette(261 + i) = RGB(0, 255 - clr, 255)
+ Next
+ For i = 0 To 464
+ clr = CInt(i * 255 / 464)
+ palette(559 + i) = RGB(clr, 0, 255)
+ Next
+*/
+ return palette;
+}
+
+function drawPoint(context, img_x, img_y, C, iterMax) {
+ var itVal = mandelbrotValue(C, iterMax);
+ context.fillStyle = getColor(itVal, iterMax);
+ context.fillRect (img_x, img_y, 1, 1); // x, y, width, height
+}
+
+function saveImage() {
+ // should call filepicker!
+ saveCanvas(document.getElementById("mbrotImage"), "/home/robert/temp/canvas-save.png")
+}
+
+// function below is from from http://developer.mozilla.org/en/docs/Code_snippets:Canvas
+function saveCanvas(canvas, destFile) {
+ // convert string filepath to an nsIFile
+ var file = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ file.initWithPath(destFile);
+
+ // create a data url from the canvas and then create URIs of the source and targets
+ var io = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
+ var target = io.newFileURI(file);
+
+ // prepare to save the canvas data
+ var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+ .createInstance(Components.interfaces.nsIWebBrowserPersist);
+
+ persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+
+ // displays a download dialog (remove these 3 lines for silent download)
+ var xfer = Components.classes["@mozilla.org/transfer;1"]
+ .createInstance(Components.interfaces.nsITransfer);
+ xfer.init(source, target, "", null, null, null, persist);
+ persist.progressListener = xfer;
+
+ // save the canvas data to the file
+ persist.saveURI(source, null, null, null, null, file);
+}
+
+// function below is from http://developer.mozilla.org/en/docs/How_to_Quit_a_XUL_Application
+function quitApp(aForceQuit) {
+ var appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1']
+ .getService(Components.interfaces.nsIAppStartup);
+
+ // eAttemptQuit will try to close each XUL window, but the XUL window can cancel the quit
+ // process if there is unsaved data. eForceQuit will quit no matter what.
+ var quitSeverity = aForceQuit ? Components.interfaces.nsIAppStartup.eForceQuit :
+ Components.interfaces.nsIAppStartup.eAttemptQuit;
+ appStartup.quit(quitSeverity);
+}