Models 44

Claude Haiku 4.5

by AnthropicReasoningClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
25.9 s
Cost
$0.042
Output tokens
8,385
Spent thinking
5,204 tokens
Speed
333.7 tok/s
Console errors
0
First token after
730 ms
First visible text after
23.1 s
Prompt tokens
492
Code size
10.4 KB
Finish reason
stop
Served by
Amazon Bedrock
Model id
anthropic/claude-haiku-4.5
Reasoning sent
{"enabled":true}
Max output
64,000 tokens
Generated
Nov 10, 2026

What it was asked

The prompt
“a 3D aquarium with Three.js where the fish swim away when I move the mouse near them (Load Three.js only through this import map: <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>)”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 277 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Aquarium</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            width: 100%;
            height: 100vh;
            overflow: hidden;
            background: #000;
            font-family: Arial, sans-serif;
        }
        canvas {
            display: block;
            width: 100%;
            height: 100%;
        }
        #info {
            position: absolute;
            top: 20px;
            left: 20px;
            color: #87ceeb;
            font-size: 16px;
            background: rgba(0, 0, 0, 0.7);
            padding: 15px 20px;
            border-radius: 8px;
            border: 1px solid #87ceeb;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div id="info">🐠 Move your mouse to scare the fish!</div>
    <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>
    <script type="module">
        import * as THREE from 'three';

        // Scene setup
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x0a2a42);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFShadowShadowMap;
        document.body.appendChild(renderer.domElement);

        camera.position.z = 28;

        // Lighting
        const ambientLight = new THREE.AmbientLight(0x87ceeb, 0.4);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
        directionalLight.position.set(20, 15, 20);
        directionalLight.castShadow = true;
        directionalLight.shadow.camera.near = 0.5;
        directionalLight.shadow.camera.far = 100;
        directionalLight.shadow.camera.left = -50;
        directionalLight.shadow.camera.right = 50;
        directionalLight.shadow.camera.top = 50;
        directionalLight.shadow.camera.bottom = -50;
        scene.add(directionalLight);

        // Bubbles for atmosphere
        const bubbleGeometry = new THREE.BufferGeometry();
        const bubbleCount = 80;
        const bubblePositions = new Float32Array(bubbleCount * 3);
        const bubbleSizes = [];
        
        for (let i = 0; i < bubbleCount * 3; i += 3) {
            bubblePositions[i] = (Math.random() - 0.5) * 70;
            bubblePositions[i + 1] = (Math.random() - 0.5) * 50;
            bubblePositions[i + 2] = (Math.random() - 0.5) * 40;
            bubbleSizes.push(Math.random() * 0.15 + 0.05);
        }
        
        bubbleGeometry.setAttribute('position', new THREE.BufferAttribute(bubblePositions, 3));
        const bubbleMaterial = new THREE.PointsMaterial({ 
            color: 0x87ceeb, 
            size: 0.3, 
            transparent: true, 
            opacity: 0.2,
            sizeAttenuation: true
        });
        const bubbles = new THREE.Points(bubbleGeometry, bubbleMaterial);
        scene.add(bubbles);

        // Fish class
        class Fish {
            constructor(index) {
                this.velocity = new THREE.Vector3(
                    (Math.random() - 0.5) * 0.15,
                    (Math.random() - 0.5) * 0.08,
                    (Math.random() - 0.5) * 0.15
                );
                this.position = new THREE.Vector3(
                    (Math.random() - 0.5) * 50,
                    (Math.random() - 0.5) * 30,
                    (Math.random() - 0.5) * 25
                );
                this.targetAngle = 0;
                this.fleeDirection = new THREE.Vector3();
                this.isFleeing = false;
                this.fleeTimer = 0;
                this.wanderAngle = Math.random() * Math.PI * 2;

                // Create fish group
                this.group = new THREE.Group();

                // Color palette
                const colors = [0xff6b6b, 0xffd93d, 0x6bcf7f, 0x4ecdc4, 0xff8fb1, 0x95e1d3];
                const baseColor = colors[index % colors.length];

                // Fish body
                const bodyGeometry = new THREE.ConeGeometry(0.8, 2.8, 12);
                const bodyMaterial = new THREE.MeshPhongMaterial({
                    color: baseColor,
                    shininess: 120,
                    wireframe: false
                });
                const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
                body.castShadow = true;
                body.receiveShadow = true;
                this.group.add(body);

                // Fish fin (dorsal)
                const finGeometry = new THREE.ConeGeometry(0.3, 1.2, 8);
                const finMaterial = new THREE.MeshPhongMaterial({
                    color: new THREE.Color(baseColor).multiplyScalar(0.6),
                    shininess: 80
                });
                const fin = new THREE.Mesh(finGeometry, finMaterial);
                fin.position.set(0, 0.8, -0.3);
                fin.rotation.z = Math.PI / 4;
                fin.castShadow = true;
                this.group.add(fin);

                // Fish eye
                const eyeGeometry = new THREE.SphereGeometry(0.25, 16, 16);
                const eyeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
                const eye = new THREE.Mesh(eyeGeometry, eyeMaterial);
                eye.position.set(0, 0.15, 1.1);
                eye.castShadow = true;
                this.group.add(eye);

                // Pupil
                const pupilGeometry = new THREE.SphereGeometry(0.12, 8, 8);
                const pupilMaterial = new THREE.MeshPhongMaterial({ color: 0x000000 });
                const pupil = new THREE.Mesh(pupilGeometry, pupilMaterial);
                pupil.position.set(0, 0.15, 1.25);
                this.group.add(pupil);

                // Fish tail
                const tailGeometry = new THREE.ConeGeometry(0.5, 1.3, 16);
                const tailMaterial = new THREE.MeshPhongMaterial({
                    color: new THREE.Color(baseColor).multiplyScalar(0.8),
                    shininess: 100
                });
                const tail = new THREE.Mesh(tailGeometry, tailMaterial);
                tail.position.z = -1.8;
                tail.scale.set(1.8, 1.8, 1);
                tail.castShadow = true;
                this.group.add(tail);

                this.group.position.copy(this.position);
                scene.add(this.group);
            }

            update(mousePos) {
                // Distance to mouse
                const distToMouse = this.group.position.distanceTo(mousePos);
                
                if (distToMouse < 12) {
                    this.isFleeing = true;
                    this.fleeTimer = 100;
                    this.fleeDirection = new THREE.Vector3()
                        .subVectors(this.group.position, mousePos)
                        .normalize();
                } else if (this.fleeTimer > 0) {
                    this.fleeTimer--;
                } else {
                    this.isFleeing = false;
                }

                // Update velocity
                if (this.isFleeing) {
                    this.velocity.lerp(this.fleeDirection.clone().multiplyScalar(0.45), 0.15);
                } else {
                    // Wandering behavior
                    this.wanderAngle += (Math.random() - 0.5) * 0.3;
                    const wanderForce = new THREE.Vector3(
                        Math.cos(this.wanderAngle) * 0.05,
                        Math.sin(this.wanderAngle) * 0.03,
                        Math.cos(this.wanderAngle * 0.7) * 0.04
                    );
                    this.velocity.add(wanderForce);
                    this.velocity.multiplyScalar(0.96);
                }

                // Speed limit
                const maxSpeed = this.isFleeing ? 0.45 : 0.2;
                if (this.velocity.length() > maxSpeed) {
                    this.velocity.normalize().multiplyScalar(maxSpeed);
                }

                // Update position
                this.group.position.add(this.velocity);

                // Boundaries
                const bounds = 35;
                if (Math.abs(this.group.position.x) > bounds) {
                    this.velocity.x *= -1;
                    this.group.position.x = Math.sign(this.group.position.x) * bounds;
                }
                if (Math.abs(this.group.position.y) > bounds) {
                    this.velocity.y *= -1;
                    this.group.position.y = Math.sign(this.group.position.y) * bounds;
                }
                if (Math.abs(this.group.position.z) > bounds) {
                    this.velocity.z *= -1;
                    this.group.position.z = Math.sign(this.group.position.z) * bounds;
                }

                // Rotation to face velocity
                if (this.velocity.length() > 0.01) {
                    this.targetAngle = Math.atan2(this.velocity.x, this.velocity.z);
                }
                this.group.rotation.y += (this.targetAngle - this.group.rotation.y) * 0.12;
            }
        }

        // Create fish
        const fish = [];
        for (let i = 0; i < 8; i++) {
            fish.push(new Fish(i));
        }

        // Mouse tracking
        let mousePos = new THREE.Vector3(0, 0, 0);
        document.addEventListener('mousemove', (e) => {
            const rect = renderer.domElement.getBoundingClientRect();
            const x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
            const y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
            
            mousePos.x = x * 38;
            mousePos.y = y * 26;
            mousePos.z = 0;
        });

        // Animation loop
        function animate() {
            requestAnimationFrame(animate);

            fish.forEach(f => f.update(mousePos));

            renderer.render(scene, camera);
        }

        // Handle resize
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        animate();
    </script>
</body>
</html>
Reasoning trace (5,204 tokens)
The user wants me to create a 3D aquarium with Three.js where fish swim away when the mouse moves near them. 

Key requirements:
1. Use Three.js with the specific import map provided
2. Create a 3D aquarium scene
3. Have fish that swim in the aquarium
4. Fish should swim away when the mouse moves near them
5. Must work in a 1280×800 viewport and scale down to 375px
6. Must look good on first paint without interaction
7. Should have mouse tracking for the "scare away" effect

Let me break down what I need:
1. Three.js scene with a camera and renderer
2. An aquarium container (maybe a transparent box or just the background)
3. Multiple fish that swim around
4. Mouse tracking to detect when mouse is near fish
5. Fish behavior to flee when mouse is nearby

I'll create:
- A simple aquarium scene with a blue gradient background/environment
- Multiple fish (can make them as simple shapes or use some geometry)
- A camera that shows the aquarium
- Mouse tracking to get the mouse position
- Fish AI that makes them swim around and flee from the mouse cursor

Let me structure the code:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Aquarium</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #000;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>
    <script type="module">
        import * as THREE from 'three';

        // Scene setup
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x1a4d6d);
        document.body.appendChild(renderer.domElement);

        camera.position.z = 20;

I'm setting up the basic scene, camera, and renderer with a blue-toned clear color for the underwater feel, positioning the camera back enough to view the full aquarium space.

= 0;

Each fish gets a cone-shaped mesh with a random hue and a little eye sphere stuck to the front. The update method starts by checking the distance between the fish and the mouse position, triggering flee behavior when it gets within 8 units.

It sets a flee direction away from the mouse and a 60-frame timer, counting down otherwise and resetting the flag once it hits zero. Velocity gets set directly from the flee direction when fleeing, or drifts with small random nudges when wandering, damped by a 0.98 multiplier each frame.

Now I need to clamp speed to a max of 0.3 while fleeing or 0.15 otherwise, then apply velocity to position. Walls at a boundary of 25 units reflect velocity on whichever axis is exceeded, clamping position back to the boundary edge.

Rotation should ease toward the direction of travel using atan2 on x/z velocity, smoothly interpolating current rotation by 10% each frame.

I'll instantiate the fish array by looping fishCount times, then set up mouse tracking that maps clientX/Y into normalized scene coordinates for mousePos, used elsewhere for interaction. Finally, I start the animation loop with requestAnimationFrame.

Now let me double-check requirements: the import map needs to be included properly, fish should flee from cursor proximity, visuals must render well on first paint, and layout needs to adapt down to 375px wide. I'll make sure the import map is embedded correctly in the HTML and verify responsiveness and aesthetics across viewport sizes.

I want the aquarium to feel like an actual tank—visible boundaries, clearly visible fish, responsive mouse interaction, and reasonable mobile behavior even though mouse is the primary input. Revising the code: dark background with a blue aquarium tint, ambient and directional lighting with shadows, a sprinkling of bubble particles, and a Fish class using cone-shaped bodies with eyes and tails colored via HSL. Each fish wanders randomly but switches to a flee behavior—computing a direction away from the mouse and boosting speed—when the cursor comes within range, reverting after a timer expires. Fish bounce off tank boundaries and rotate smoothly toward their velocity direction. Mouse position gets mapped into 3D space on mousemove, and the animate loop updates each fish and renders the scene, with resize handling for responsiveness.

Checking off the requirements: Three.js via import map, 3D aquarium with fleeing fish, works at 1280×800 and scales to 375px, decent first-paint appearance—looks solid overall.