Thanks for sharing, didn't know this! Of course I had to do the classic 😃
https://play.ertdfgcvb.xyz/#/1768593702613
/**
@author kon
@title mandelbrot
@desc with zoom LMB/RMB
*/
export const settings = {
fps: 10,
backgroundColor: '#000',
color: '#fff'
}
const density = ' @#¢*+:=~ .'
let cx = -0.743643887037151
, cy = 0.13182590420533
, scale = 1.65
, prevPressed = false
, lastButton = 0
, lastButtons = 0
, lastShift = false
globalThis.onpointerdown = globalThis.onmousedown = (e) => {
lastButton = e.button | 0
lastButtons = e.buttons | 0
lastShift = !!e.shiftKey
}
globalThis.oncontextmenu = (e) => e.preventDefault()
const zoomIn = 0.75
, zoomOut = 1 / zoomIn
, aspectY = (metrics) => 0.6 / (metrics?.aspect || 0.5)
export function pre(context, cursor) {
const pressed = !!cursor?.pressed
, justPressed = pressed && !prevPressed
prevPressed = pressed
if (!justPressed) return
const aY = aspectY(context.metrics)
, nx = (cursor.x / context.cols - 0.5) * 2
, ny = (cursor.y / context.rows - 0.5) * 2 * aY
, tx = cx + nx * scale
, ty = cy + ny * scale
, zoomOutClick = lastShift || lastButton === 2 || (lastButtons & 2)
, z = zoomOutClick ? zoomOut : zoomIn
, newScale = scale * z
cx = tx - nx * newScale
cy = ty - ny * newScale
scale = newScale
}
export function main(coord, context) {
const aY = aspectY(context.metrics)
, nx = (coord.x / context.cols - 0.5) * 2
, ny = (coord.y / context.rows - 0.5) * 2 * aY
, x0 = cx + nx * scale
, y0 = cy + ny * scale
let x = 0, y = 0, i = 0
while (i++ < 128 && x * x + y * y < 4) {
const xx = x * x - y * y + x0
y = 2 * x * y + y0
x = xx
}
return density[(i / 10) | 0]
}
