Custom Code Experiment •
Conformal Map 2
Source Code View HTML / CSS / JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Conformal Map 2</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
width: 100%; height: 100%;
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
canvas {
display: block;
max-width: 60vmin;
max-height: 60vmin;
width: 60vmin;
height: 60vmin;
}
</style>
</head>
<body>
<canvas id="c"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
(function () {
const canvas = document.getElementById('c');
function resize() {
const S = Math.round(Math.min(window.innerWidth, window.innerHeight) * 0.6);
canvas.width = S;
canvas.height = S;
canvas.style.width = S + 'px';
canvas.style.height = S + 'px';
if (renderer) {
renderer.setSize(S, S);
mat.uniforms.uRes.value.set(S, S);
}
}
const S0 = Math.round(Math.min(window.innerWidth, window.innerHeight) * 0.6);
canvas.width = S0;
canvas.height = S0;
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setSize(S0, S0);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);
camera.position.z = 1;
/* ─── Vertex shader ─── */
const vertShader = `
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy, 0.0, 1.0);
}`;
/* ─── Fragment shader ─── */
const fragShader = `
precision highp float;
varying vec2 vUv;
uniform float uTime;
uniform vec2 uRes;
#define PI 3.14159265358979
#define TAU 6.28318530717959
#define ITER 8
/* ── Complex arithmetic ── */
vec2 cmul(vec2 a, vec2 b){ return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x); }
vec2 cdiv(vec2 a, vec2 b){
float d = dot(b,b);
return vec2(dot(a,b), a.y*b.x - a.x*b.y)/d;
}
vec2 clog(vec2 z){ return vec2(log(length(z)), atan(z.y, z.x)); }
vec2 cexp(vec2 z){ return exp(z.x)*vec2(cos(z.y), sin(z.y)); }
/* ── Turtle SDF (signed-distance field) ── */
float sdTurtle(vec2 p){
p.y -= 0.08;
float body = length(p / vec2(0.38, 0.28)) - 1.0;
float neck = length((p - vec2(0.0, 0.27)) / vec2(0.11, 0.14)) - 1.0;
float head = length((p - vec2(0.0, 0.44)) / vec2(0.13, 0.12)) - 1.0;
float fl = length((p - vec2(-0.30, 0.18)) / vec2(0.16, 0.10)) - 1.0;
float fr = length((p - vec2( 0.30, 0.18)) / vec2(0.16, 0.10)) - 1.0;
float bl = length((p - vec2(-0.28,-0.20)) / vec2(0.14, 0.09)) - 1.0;
float br = length((p - vec2( 0.28,-0.20)) / vec2(0.14, 0.09)) - 1.0;
float tail = length((p - vec2(0.0, -0.34)) / vec2(0.07, 0.10)) - 1.0;
return min(body, min(neck, min(head, min(min(fl,fr), min(min(bl,br), tail)))));
}
/* ── Tile colour at a given UV ── */
vec3 eschTileColor(vec2 uv){
vec2 cell = fract(uv * 3.0 + vec2(0.5));
float turt = sdTurtle((cell - 0.5) * 0.7);
/* shell scute shading */
float scute = sin(uv.x * 28.0) * sin(uv.y * 28.0);
vec3 shellDark = vec3(0.12, 0.35, 0.14);
vec3 shellLight = vec3(0.28, 0.60, 0.26);
vec3 tileDark = vec3(0.07, 0.08, 0.09);
vec3 tileLight = vec3(0.84, 0.81, 0.74);
vec3 col;
if(turt < 0.0){
/* turtle body */
col = mix(shellDark, shellLight, smoothstep(-0.12, 0.12, scute));
/* eye */
float eye = length(cell - vec2(0.53, 0.81)) - 0.025;
if(eye < 0.0) col = vec3(0.04, 0.04, 0.05);
if(abs(eye) < 0.013) col = vec3(0.88, 0.82, 0.65);
} else {
/* background chequerboard-ish */
float stripe = sin(cell.x * 18.0 + cell.y * 12.0) * 0.5 + 0.5;
col = mix(tileDark, tileLight, step(0.5, stripe));
/* subtle grid lines */
float gx = abs(fract(uv.x * 3.0 + 0.5) - 0.5);
float gy = abs(fract(uv.y * 3.0 + 0.5) - 0.5);
col = mix(vec3(0.50, 0.46, 0.38), col, smoothstep(0.0, 0.04, min(gx, gy)));
}
/* outline rim */
col = mix(vec3(0.58, 0.52, 0.28), col, smoothstep(0.0, 0.022, abs(turt)));
return col;
}
/* ── Main ── */
void main(){
vec2 uv = vUv * 2.0 - 1.0;
uv.x *= uRes.x / uRes.y; /* square aspect */
float slowTime = uTime * 0.12;
float R = 0.82; /* outer ring radius */
float r = 0.18; /* inner ring radius */
float logR = log(R / r);
vec3 finalColor = vec3(0.0);
float totalWeight = 0.0;
float brightness = 1.0;
vec2 w = uv;
for(int i = 0; i < ITER; i++){
float wlen = length(w);
if(wlen < 0.001 || wlen > 3.0) break;
/* conformal logarithm → (angle, radius) coordinates */
vec2 logW = clog(w);
float angle = logW.y / TAU;
float radius = logW.x / logR;
/* animate by drifting angle */
vec2 tileUV = vec2(angle + slowTime * 0.5, radius);
vec3 tileCol = eschTileColor(tileUV * vec2(4.0, 2.0));
float weight = brightness
* smoothstep(3.0, 0.5, wlen)
* smoothstep(0.0, 0.15, wlen);
finalColor += tileCol * weight;
totalWeight += weight;
/* Droste step: multiply by e^logR to recurse inward */
w = w * exp(logR);
brightness *= 0.70;
if(length(w) < r * 0.5) break;
}
if(totalWeight > 0.001) finalColor /= totalWeight;
/* vignette */
finalColor *= smoothstep(1.4, 0.6, length(uv) / R);
/* golden border glow */
float borderGlow = smoothstep(0.025, 0.0, abs(length(uv) - R * 0.99));
finalColor += vec3(0.72, 0.62, 0.32) * borderGlow * 0.7;
/* subtle scanline texture */
finalColor += sin(vUv.y * uRes.y * 0.5) * 0.012;
/* gentle gamma */
finalColor = pow(clamp(finalColor, 0.0, 1.0), vec3(0.88));
gl_FragColor = vec4(finalColor, 1.0);
}`;
const geo = new THREE.PlaneGeometry(2, 2);
const mat = new THREE.ShaderMaterial({
vertexShader: vertShader,
fragmentShader: fragShader,
uniforms: {
uTime: { value: 0 },
uRes: { value: new THREE.Vector2(S0, S0) }
}
});
scene.add(new THREE.Mesh(geo, mat));
/* ── Animation loop ── */
let frame = 0;
let raf;
function animate() {
raf = requestAnimationFrame(animate);
mat.uniforms.uTime.value = (++frame) * 0.016;
renderer.render(scene, camera);
}
animate();
/* ── Pause when off-screen ── */
new IntersectionObserver(entries => {
if (!entries[0].isIntersecting) cancelAnimationFrame(raf);
else animate();
}, { threshold: 0 }).observe(canvas);
/* ── Responsive resize ── */
window.addEventListener('resize', resize);
})();
</script>
</body>
</html>