Changed around line 1
+ function createChessboard() {
+ const container = document.getElementById('chessboard');
+ const center = [3, 3];
+
+ for(let i = 0; i < 8; i++) {
+ for(let j = 0; j < 8; j++) {
+ const cell = document.createElement('div');
+ cell.className = 'cell';
+ cell.dataset.x = i;
+ cell.dataset.y = j;
+
+ cell.addEventListener('click', () => {
+ const dx = Math.abs(i - center[0]);
+ const dy = Math.abs(j - center[1]);
+ const distance = Math.max(dx, dy);
+
+ cell.style.background = `hsl(${distance * 40}, 70%, 30%)`;
+ cell.textContent = distance;
+ });
+
+ container.appendChild(cell);
+ }
+ }
+ }
+
+ function createTaxicab() {
+ const container = document.getElementById('taxicab');
+ const svgNS = 'http://www.w3.org/2000/svg';
+ const svg = document.createElementNS(svgNS, 'svg');
+ svg.setAttribute('viewBox', '0 0 100 100');
+ svg.style.width = '100%';
+ svg.style.height = '100%';
+
+ const p1 = createDraggablePoint(30, 30);
+ const p2 = createDraggablePoint(70, 70);
+ const path = document.createElementNS(svgNS, 'path');
+ path.className.baseVal = 'taxicab-path';
+
+ function updatePath() {
+ const x1 = parseFloat(p1.style.left);
+ const y1 = parseFloat(p1.style.top);
+ const x2 = parseFloat(p2.style.left);
+ const y2 = parseFloat(p2.style.top);
+
+ const dx = Math.abs(x2 - x1);
+ const dy = Math.abs(y2 - y1);
+ const distance = dx + dy;
+
+ path.setAttribute('d',
+ `M ${x1}% ${y1}% L ${x2}% ${y1}% L ${x2}% ${y2}%`
+ );
+
+ distanceLabel.textContent = `L1 = ${distance.toFixed(1)}`;
+ distanceLabel.style.left = `${(x1 + x2)/2}%`;
+ distanceLabel.style.top = `${(y1 + y2)/2}%`;
+ }
+
+ const distanceLabel = document.createElement('div');
+ distanceLabel.className = 'distance-label';
+ container.append(svg, p1, p2, distanceLabel);
+ updatePath();
+
+ function createDraggablePoint(x, y) {
+ const point = document.createElement('div');
+ point.className = 'metric-point';
+ point.style.left = `${x}%`;
+ point.style.top = `${y}%`;
+
+ let isDragging = false;
+
+ point.addEventListener('mousedown', () => {
+ isDragging = true;
+ document.addEventListener('mousemove', onMove);
+ document.addEventListener('mouseup', () => {
+ isDragging = false;
+ document.removeEventListener('mousemove', onMove);
+ });
+ });
+
+ function onMove(e) {
+ if (!isDragging) return;
+ const rect = container.getBoundingClientRect();
+ const x = (e.clientX - rect.left) / rect.width * 100;
+ const y = (e.clientY - rect.top) / rect.height * 100;
+ point.style.left = `${Math.min(95, Math.max(5, x))}%`;
+ point.style.top = `${Math.min(95, Math.max(5, y))}%`;
+ updatePath();
+ }
+
+ return point;
+ }
+ }
+
+ function createEuclidean() {
+ const container = document.getElementById('euclidean');
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ let width, height;
+
+ function resize() {
+ width = canvas.width = container.clientWidth;
+ height = canvas.height = container.clientHeight;
+ }
+ resize();
+ window.addEventListener('resize', resize);
+
+ container.appendChild(canvas);
+
+ container.addEventListener('click', (e) => {
+ const rect = container.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+ drawCircle(x, y);
+ });
+
+ function drawCircle(x, y) {
+ ctx.clearRect(0, 0, width, height);
+
+ // Draw circle
+ ctx.beginPath();
+ ctx.arc(width/2, height/2, Math.hypot(x - width/2, y - height/2), 0, Math.PI*2);
+ ctx.strokeStyle = '#e53170';
+ ctx.lineWidth = 2;
+ ctx.stroke();
+
+ // Draw line
+ ctx.beginPath();
+ ctx.moveTo(width/2, height/2);
+ ctx.lineTo(x, y);
+ ctx.strokeStyle = '#7f5af0';
+ ctx.stroke();
+
+ // Show distance
+ const distance = Math.hypot(x - width/2, y - height/2).toFixed(1);
+ ctx.fillStyle = '#fffffe';
+ ctx.font = '18px monospace';
+ ctx.fillText(`L2 = ${distance}px`, x + 10, y - 10);
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ createChessboard();
+ createTaxicab();
+ createEuclidean();
+ });