126 lines
2.5 KiB
JavaScript
126 lines
2.5 KiB
JavaScript
|
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();
|