const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const width = 1000; const height = 1000; canvas.style.width = width + "px"; canvas.style.height = height + "px"; canvas.width = width; canvas.height = height; let minX = -2, minY = -2, maxX = 2, maxY = 2; let selection = null; let isMouseDown = false; let mouseStartPosition = null; let mandelbrot = ctx.createImageData(width, height); function calcRe(col) { return (col * (maxX - minX)) / width + minX; } function calcIm(row) { return (row * (maxY - minY)) / height + minY; } function drawMandelbrotSet() { ctx.putImageData(mandelbrot, 0, 0); } let needToDraw = false; function draw() { if (needToDraw) { ctx.clearRect(0, 0, width, height); drawMandelbrotSet(); } if (selection) { ctx.fillStyle = "rgba(0, 0, 255, 0.8)"; ctx.fillRect( selection.startX, selection.startY, selection.endX - selection.startX, selection.endY - selection.startY ); needToDraw = true; } setTimeout(draw, 1000 / 60); } canvas.addEventListener("mousedown", (event) => { isMouseDown = true; selection = { startX: event.clientX - event.target.offsetLeft, startY: event.clientY - event.target.offsetTop, endX: event.clientX - event.target.offsetLeft, endY: event.clientY - event.target.offsetTop, }; }); canvas.addEventListener("mousemove", (event) => { if (isMouseDown) { const posX = event.clientX - event.target.offsetLeft; const posY = event.clientY - event.target.offsetTop; const dx = posX - selection.startX; const dy = posY - selection.startY; if (Math.abs(dx) > Math.abs(dy)) { selection.endX = selection.startX + dx; selection.endY = selection.startY + dx; } else { selection.endX = selection.startX + dy; selection.endY = selection.startY + dy; } } }); canvas.addEventListener("mouseup", (event) => { isMouseDown = false; const newMinX = calcRe(selection.startX); const newMinY = calcIm(selection.startY); const newMaxX = calcRe(selection.endX); const newMaxY = calcIm(selection.endY); minX = newMinX; minY = newMinY; maxX = newMaxX; maxY = newMaxY; updateWorker(); selection = null; }); let worker; function updateWorker() { worker.postMessage([{ mandelbrot: mandelbrot, width, height, minX, maxX, minY, maxY, }]); } function initWorker() { worker = new Worker('worker.js'); updateWorker(); worker.onmessage = (e) => { mandelbrot = e.data[0]; needToDraw = true; }; } initWorker(); draw();