├── fractals.html
├── LICENSE
├── README.md
└── js
└── fractals.js
/fractals.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Fractals
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Initial image of a Mandelbrot set
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2013 Dmitry Alimov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | fractals-js
2 | ===========
3 | [](https://github.com/delimitry/ascii_canvas/blob/master/LICENSE)
4 |
5 | Fractals in JavaScript using HTML5 Canvas
6 |
7 | ### Fractals Visualizations
8 |
9 | 1) Visualization of the Mandelbrot Set
10 |
11 | 
12 |
13 | 2) Visualization of the Julia Set
14 |
15 | 
16 | 
17 |
18 | 3) Visualization of the Burning Ship fractal
19 |
20 | 
21 |
22 | 4) Visualization of the Sierpinski carpet fractal
23 |
24 | 
25 |
26 | License:
27 | --------
28 | Released under [The MIT License](https://github.com/delimitry/fractals-js/blob/master/LICENSE).
29 |
--------------------------------------------------------------------------------
/js/fractals.js:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------
2 | // Fractals
3 | //
4 | // Author: delimitry
5 | //-----------------------------------------------------------------------
6 |
7 | function checkCanvasIsSupported() {
8 | canvas = document.getElementById("canvas");
9 | canvas.width = 480;
10 | canvas.height = 320;
11 | if (canvas.getContext) {
12 | context = canvas.getContext('2d');
13 | render();
14 | //setInterval(render, 100);
15 | } else {
16 | alert("Sorry, but your browser doesn't support a canvas.");
17 | }
18 | }
19 |
20 | function render() {
21 | context.clearRect(0, 0, canvas.width , canvas.height);
22 | // visualize the Mandelbrot set
23 | drawMandelbrot();
24 | // visualize the Julia set
25 | //drawJulia();
26 | // visualize Burning Ship fractal
27 | //drawBurningShipFractal();
28 | // draw Sierpinski carpet
29 | //drawSierpinskiCarpet();
30 | }
31 |
32 | function drawMandelbrot() {
33 | // prepare image and pixels
34 | var image_data = context.createImageData(canvas.width, canvas.height);
35 | var d = image_data.data;
36 |
37 | max_iterations = 100;
38 | for (var i = 0; i < canvas.height; i++) {
39 | for (var j = 0; j < canvas.width; j++) {
40 |
41 | // limit the axis
42 | x0 = -2.0 + j * 3.0 / canvas.width; // (-2, 1)
43 | y0 = -1.0 + i * 2.0 / canvas.height; // (-1, 1)
44 |
45 | x = 0;
46 | y = 0;
47 | iteration = 0;
48 |
49 | while ((x * x + y * y < 4) && (iteration < max_iterations)) {
50 | x_n = x * x - y * y + x0;
51 | y_n = 2 * x * y + y0;
52 | x = x_n;
53 | y = y_n;
54 | iteration++;
55 | }
56 |
57 | // set pixel color [r,g,b,a]
58 | d[i * canvas.width * 4 + j * 4 + 0] = iteration*15;
59 | d[i * canvas.width * 4 + j * 4 + 1] = iteration*3;
60 | d[i * canvas.width * 4 + j * 4 + 2] = iteration*5;
61 | d[i * canvas.width * 4 + j * 4 + 3] = 255;
62 | }
63 | }
64 |
65 | // draw image
66 | context.putImageData(image_data, 0, 0);
67 | }
68 |
69 |
70 | function drawJulia() {
71 | // prepare image and pixels
72 | var image_data = context.createImageData(canvas.width, canvas.height);
73 | var d = image_data.data;
74 |
75 | x0 = -0.4;
76 | y0 = -0.6;
77 | max_iterations = 100;
78 | for (var i = 0; i < canvas.height; i++) {
79 | for (var j = 0; j < canvas.width; j++) {
80 |
81 | // limit the axis
82 | x = -1.5 + j * 3.0 / canvas.width;
83 | y = -1.0 + i * 2.0 / canvas.height;
84 |
85 | iteration = 0;
86 |
87 | while ((x * x + y * y < 4) && (iteration < max_iterations)) {
88 | x_n = x * x - y * y + x0;
89 | y_n = 2 * x * y + y0;
90 | x = x_n;
91 | y = y_n;
92 | iteration++;
93 | }
94 |
95 | // set pixel color [r,g,b,a]
96 | d[i * canvas.width * 4 + j * 4 + 0] = iteration*25;
97 | d[i * canvas.width * 4 + j * 4 + 1] = iteration*5;
98 | d[i * canvas.width * 4 + j * 4 + 2] = iteration*8;
99 | d[i * canvas.width * 4 + j * 4 + 3] = 255;
100 | }
101 | }
102 |
103 | // draw image
104 | context.putImageData(image_data, 0, 0);
105 | }
106 |
107 | function drawBurningShipFractal() {
108 | // prepare image and pixels
109 | var image_data = context.createImageData(canvas.width, canvas.height);
110 | var d = image_data.data;
111 |
112 | max_iterations = 100;
113 | for (var i = 0; i < canvas.height; i++) {
114 | for (var j = 0; j < canvas.width; j++) {
115 |
116 | x0 = -1.80 + j * (-1.7+1.80) / canvas.width;
117 | y0 = -0.08 + i * (0.01+0.08) / canvas.height;
118 | x = 0;
119 | y = 0;
120 | iteration = 0;
121 |
122 | while ((x * x + y * y < 4) && (iteration < max_iterations)) {
123 | x_n = x * x - y * y + x0;
124 | y_n = 2 * Math.abs(x * y) + y0;
125 | x = x_n;
126 | y = y_n;
127 | iteration++;
128 | }
129 |
130 | // set pixel color [r,g,b,a]
131 | d[i * canvas.width * 4 + j * 4 + 0] = 25+iteration*30;
132 | d[i * canvas.width * 4 + j * 4 + 1] = 25+iteration*10;
133 | d[i * canvas.width * 4 + j * 4 + 2] = 85-iteration*5;
134 | d[i * canvas.width * 4 + j * 4 + 3] = 255;
135 | }
136 | }
137 |
138 | // draw image
139 | context.putImageData(image_data, 0, 0);
140 | }
141 |
142 | function drawSierpinskiCarpet() {
143 | // draw carpet
144 | var draw_carpet = function (x, y, width, height, iteration) {
145 | if (iteration == 0) return;
146 | var w = width / 3;
147 | var h = height / 3;
148 |
149 | // draw subsquare
150 | context.fillStyle = 'rgb(255,255,255)';
151 | context.fillRect(x + w, y + h, w, h);
152 |
153 | // draw subcarpets
154 | for (var i = 0; i < 3; i++) {
155 | for (var j = 0; j < 3; j++) {
156 | // remove central subsquare
157 | if (j == 1 && i == 1) continue;
158 | draw_carpet(x + j * w, y + i * h, w, h, iteration - 1);
159 | }
160 | }
161 | }
162 |
163 | // init carpet size
164 | var carpet_width = canvas.height;
165 | var carpet_height = canvas.height;
166 | // align to the center
167 | var carpet_left = (canvas.width - carpet_width) / 2;
168 | // limit the depth of recursion
169 | var max_iterations = 4;
170 |
171 | // draw Sierpinski carpet
172 | draw_carpet(carpet_left, 0, carpet_width, carpet_height, max_iterations);
173 | }
174 |
--------------------------------------------------------------------------------