const WIDTH = 800; const HEIGHT = 600; const ASPECT_RATIO = WIDTH / HEIGHT; const ZOOM_SPEED = 1; let zoom = 0.5; let zoom_dB = -3; let posX = -0.75; let posY = 0; console.clear(); let canvas = createCanvas(WIDTH, HEIGHT); canvas.style.border = "2px solid red"; let hueSlider = createLabeledSlider("Barvy", 0, 255, 1, 0); hueSlider.onInput(redraw); hueSlider.position(820, 10); let inputX = createLabeledInputField("X", "number", posX, { step: 0.001 }); inputX.position(820, 100); inputX.onChange(function() { posX = inputX.value(); redraw(); }); let inputY = createLabeledInputField("Y", "number", posY, { step: 0.001 }); inputY.position(820, 140); inputY.onChange(function() { posY = inputY.value(); redraw(); }); let inputZoom = createLabeledInputField("Zoom", "number", zoom, { step: 0.5, min: 0.1 }); inputZoom.position(820, 200); inputZoom.onChange(function() { zoom = inputZoom.value(); zoom_dB = 10/ZOOM_SPEED*loga(10, zoom); redraw(); }); let txtX = createParagraph("X: ??"); // txtX.position(820, 100); let txtY = createParagraph("Y: ??"); // txtY.position(820, 130); let txtZoom = createParagraph("Zoom: 1:??"); // txtZoom.position(820, 160); function mandelX(x) { return map(x, 0, WIDTH, -1, 1)/zoom; } function mandelY(y) { return map(y, 0, HEIGHT, -1, 1)/(ASPECT_RATIO*zoom); } (function() { let x0, y0; let posX0, posY0; let active = false; canvas.addEventListener("wheel", e => { e.preventDefault(); if(sign(e.deltaY) == 1 && zoom <= 0.1) return; zoom_dB -= sign(e.deltaY); zoom = pow(10, zoom_dB*ZOOM_SPEED/10); inputZoom.value(zoom); redraw(); }); canvas.addEventListener("mousedown", e => { x0 = Mouse.canvas.x; y0 = Mouse.canvas.y; posX0 = posX; posY0 = posY; active = true; }); canvas.addEventListener("mousemove", e => { if(!active) return; posX = posX0 - (mandelX(Mouse.canvas.x) - mandelX(x0)); posY = posY0 - (mandelY(Mouse.canvas.y) - mandelY(y0)); inputX.value(posX); inputY.value(posY); redraw(); }); canvas.addEventListener("mouseup", e => { posX = posX0 - (mandelX(Mouse.canvas.x) - mandelX(x0)); posY = posY0 - (mandelY(Mouse.canvas.y) - mandelY(y0)); inputX.value(posX); inputY.value(posY); redraw(); active = false; }); })(); function writePixel(img, x, y, r, g, b, a) { let data = img.data; let pos = 4*(x + img.width*y); data[pos] = r; data[pos+1] = g; data[pos+2] = b; data[pos+3] = a; } function wrap(x, min, max) { while(x > max) x -= max; while(x < min) x += min; return x; } function mandelbrot(img, xx_ofs, yy_ofs, zoom, MAX_ITERATIONS) { // const MAX_ITERATIONS = 100; const HUE_SPAN = 200+hueSlider.value(); for(let y = 0; y < HEIGHT; ++y) { const y0 = yy_ofs + mandelY(y); for(let x = 0; x < WIDTH; ++x) { const x0 = xx_ofs + mandelX(x); let re = 0; let im = 0; let iteration = 0; while(re*re + im*im <= 4 && iteration < MAX_ITERATIONS) { let reTemp = re*re - im*im + x0; im = 2*re*im + y0; re = reTemp; ++iteration; } if(iteration < MAX_ITERATIONS) { let it = wrap(iteration+200, 1, MAX_ITERATIONS); let hue = map(log(it), 0, log(MAX_ITERATIONS), 0, 255); hue = wrap(hue*10 + HUE_SPAN, 0, 255); // console.log(hue); let col = hsvToRgb(hue, 150, 255); // writePixel(img, x, y, 0, 200, 180, 255); writePixel(img, x, y, 0, col.r, col.g, 255); } else { writePixel(img, x, y, 0, 0, 0, 255); } } } } function cross(img, x0, y0, len, r, g, b, a) { for(let y = y0-len; y <= y0+len; ++y) writePixel(img, x0, y, r, g, b, a); for(let x = x0-len; x <= x0+len; ++x) writePixel(img, x, y0, r, g, b, a); } let img = createImageData(WIDTH, HEIGHT); let changed = false; let changeTime = 0; function redraw() { txtX.text("X: " + floor(posX*1000000)/1000000); txtY.text("Y: " + floor(posY*1000000)/1000000); txtZoom.text("Zoom: " + floor(zoom*100)/100); mandelbrot(img, posX, posY, zoom, 400); cross(img, WIDTH/2, HEIGHT/2, 10, 255, 0, 0, 255); putImageData(img, 0, 0); changed = true; changeTime = Date.now(); } redraw();
Editor je nyní spuštěn v režimu pouze pro čtení. Scripty můžete s příslušným oprávněním vytvářet a editovat z  uživatelské sekce.