Created
May 29, 2024 09:53
-
-
Save kujirahand/fc69de9771874ce123bc8e34e61e3155 to your computer and use it in GitHub Desktop.
マンデルブロ集合の図形(マウスイベント+カラー変更)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html><head><meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>マンデルブロ集合</title> | |
</head> | |
<body> | |
<canvas id="cnavas" width="800" height="800"></canvas> | |
</body> | |
<script> | |
// キャンバスと描画用のコンテキストを取得 | |
const canvas = document.getElementById('cnavas'); | |
const ctx = canvas.getContext('2d'); | |
const width = canvas.width; | |
const height = canvas.height; | |
// 描画の為のパラメータを指定 | |
const maxIter = 500; // 最大繰返し回数 | |
let xMin = -2.0; | |
let xMax = 2.0; | |
let yMin = -2.0; | |
let yMax = 2.0; | |
// マンデルブロの計算 | |
function mandelbrot(c) { | |
let z = { x: 0, y: 0 }; | |
let n = 0; | |
while (n < maxIter && (z.x * z.x + z.y * z.y) <= 4) { | |
const xTemp = z.x * z.x - z.y * z.y + c.x; | |
z.y = 2 * z.x * z.y + c.y; | |
z.x = xTemp; | |
n++; | |
} | |
return n; | |
} | |
// 実際にキャンバスに描画を行う関数 | |
function draw() { | |
for (let px = 0; px < width; px++) { | |
for (let py = 0; py < height; py++) { | |
const x0 = xMin + (xMax - xMin) * px / width; | |
const y0 = yMin + (yMax - yMin) * py / height; | |
const c = { x: x0, y: y0 }; | |
const m = mandelbrot(c); | |
let color; | |
if (m === maxIter) { | |
color = 'white' | |
} else { | |
const hue = Math.floor(m / maxIter * 360); | |
color = `hsl(${hue}, 100%, 50%)` | |
} | |
ctx.fillStyle = color; | |
ctx.fillRect(px, py, 1, 1); | |
} | |
} | |
} | |
draw(); | |
// マウスイベントで拡大率を指定する | |
canvas.addEventListener('mousedown', function (event) { | |
// Canvas上のクリックした位置を計算 | |
const rect = canvas.getBoundingClientRect(); | |
const mouseX = event.clientX - rect.left; | |
const mouseY = event.clientY - rect.top; | |
// クリックした位置を中心に拡大 | |
const x0 = xMin + (xMax - xMin) * mouseX / width; | |
const y0 = yMin + (yMax - yMin) * mouseY / height; | |
const zoomFactor = 0.5; | |
const newWidth = (xMax - xMin) * zoomFactor; | |
const newHeight = (yMax - yMin) * zoomFactor; | |
xMin = x0 - newWidth / 2; | |
xMax = x0 + newWidth / 2; | |
yMin = y0 - newHeight / 2; | |
yMax = y0 + newHeight / 2; | |
draw(); | |
}); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment