Models 44

Qwen3 Coder Next

by Qwenreasoning defaultClean
Open in new window

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

How it went

Total time
47.8 s
Cost
$0.0038
Output tokens
4,726
Spent thinking
0 tokens
Speed
99.7 tok/s
Console errors
0
First token after
431 ms
First visible text after
431 ms
Prompt tokens
433
Code size
19.6 KB
Finish reason
stop
Served by
Parasail
Model id
qwen/qwen3-coder-next
Reasoning sent
model default
Max output
235,929 tokens
Generated
Nov 13, 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 · 530 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive 3D Aquarium</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #001e2d;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            user-select: none;
        }

        #canvas-container {
            width: 100vw;
            height: 100vh;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
        }

        #ui-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 10;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            pointer-events: none; /* Let clicks pass through to canvas when hidden */
            transition: opacity 0.5s;
        }

        #start-message {
            background: rgba(0, 30, 45, 0.8);
            color: #fff;
            padding: 2rem;
            border-radius: 1rem;
            text-align: center;
            border: 2px solid #00a8cc;
            box-shadow: 0 0 20px rgba(0, 168, 204, 0.5);
            pointer-events: auto;
            transition: opacity 0.5s;
        }

        h1 {
            margin-top: 0;
            color: #00a8cc;
            text-transform: uppercase;
            letter-spacing: 3px;
            font-size: 2.5rem;
        }

        p {
            font-size: 1.2rem;
            line-height: 1.5;
        }

        .hidden {
            opacity: 0;
            pointer-events: none !important;
        }

        #stats {
            position: absolute;
            bottom: 20px;
            left: 20px;
            color: rgba(255, 255, 255, 0.6);
            font-size: 0.9rem;
            z-index: 20;
            pointer-events: none;
        }
    </style>
</head>
<body>

    <div id="canvas-container"></div>
    
    <div id="ui-layer">
        <div id="start-message">
            <h1>Interactive Aquarium</h1>
            <p>Welcome to the deep blue!</p>
            <p>Move your mouse near the fish to scare them away.</p>
            <p style="margin-top: 20px; color: #00a8cc; font-weight: bold;">
                Click or Press any key to Start
            </p>
        </div>
    </div>

    <div id="stats">Fish Count: <span id="fish-count">0</span></div>

    <!-- 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>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

        // --- Configuration ---
        const FISH_COUNT = 30;
        const BUBBLE_COUNT = 100;
        const SCARE_RADIUS = 15;
        const SCARE_FORCE = 1.5;
        const RETURN_FORCE = 0.02;
        const MOUSE_INFLUENCE_RADIUS = 10;
        
        // --- Scene Setup ---
        const container = document.getElementById('canvas-container');
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x001e2d);
        scene.fog = new THREE.FogExp2(0x001e2d, 0.015);

        const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 10, 30);

        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.shadowMap.enabled = true;
        container.appendChild(renderer.domElement);

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

        const dirLight = new THREE.DirectionalLight(0xffffff, 2);
        dirLight.position.set(10, 20, 10);
        dirLight.castShadow = true;
        scene.add(dirLight);

        const backLight = new THREE.PointLight(0x00a8cc, 1, 50);
        backLight.position.set(-10, 10, -10);
        scene.add(backLight);

        // Environment
        function createAquariumEnvironment() {
            // Water Volume (Visual only)
            const geometry = new THREE.BoxGeometry(40, 20, 40);
            const material = new THREE.MeshPhysicalMaterial({
                color: 0x00a8cc,
                transparent: true,
                opacity: 0.15,
                roughness: 0.1,
                metalness: 0.1,
                side: THREE.BackSide,
                transmission: 0.8
            });
            const tank = new THREE.Mesh(geometry, material);
            tank.position.y = 0;
            scene.add(tank);

            // Sand Base
            const sandGeo = new THREE.PlaneGeometry(40, 40);
            const sandMat = new THREE.MeshStandardMaterial({ 
                color: 0xd2b48c, 
                roughness: 1,
                side: THREE.DoubleSide
            });
            const sand = new THREE.Mesh(sandGeo, sandMat);
            sand.rotation.x = -Math.PI / 2;
            sand.position.y = -10;
            sand.receiveShadow = true;
            scene.add(sand);

            // Decor: Rocks and Coral
            function createRock(x, z) {
                const geo = new THREE.DodecahedronGeometry(Math.random() * 2 + 1, 0);
                const mat = new THREE.MeshStandardMaterial({ color: 0x808080, roughness: 0.9 });
                const rock = new THREE.Mesh(geo, mat);
                rock.position.set(x, -9 + Math.random(), z);
                rock.rotation.set(Math.random(), Math.random(), Math.random());
                rock.scale.set(1, Math.random() * 0.5 + 0.5, 1);
                scene.add(rock);
            }

            for (let i = 0; i < 15; i++) {
                const angle = Math.random() * Math.PI * 2;
                const radius = 15 + Math.random() * 10;
                createRock(Math.cos(angle) * radius, Math.sin(angle) * radius);
            }

            // Plants
            function createPlant(x, z) {
                const group = new THREE.Group();
                const stemMat = new THREE.MeshStandardMaterial({ color: 0x2e8b57 });
                
                const stemGeo = new THREE.CylinderGeometry(0.1, 0.2, 8, 5);
                const stem = new THREE.Mesh(stemGeo, stemMat);
                stem.position.y = 4;
                stem.castShadow = true;
                group.add(stem);

                // Leaves
                const leafGeo = new THREE.ConeGeometry(0.5, 2, 4);
                for(let i=0; i<5; i++){
                    const leaf = new THREE.Mesh(leafGeo, stemMat);
                    leaf.position.y = 6 - (i * 1.2);
                    leaf.rotation.z = Math.random();
                    leaf.rotation.x = Math.random();
                    leaf.position.x = (Math.random() - 0.5) * 1.5;
                    group.add(leaf);
                }

                group.position.set(x, -9, z);
                scene.add(group);
            }

            for (let i = 0; i < 20; i++) {
                const angle = Math.random() * Math.PI * 2;
                const radius = 18 + Math.random() * 8;
                createPlant(Math.cos(angle) * radius, Math.sin(angle) * radius);
            }
        }

        createAquariumEnvironment();

        // --- Fish Class ---
        class Fish {
            constructor() {
                this.group = new THREE.Group();
                
                // Body
                const bodyGeo = new THREE.ConeGeometry(0.8, 3, 8);
                bodyGeo.rotateX(Math.PI / 2);
                const color = new THREE.Color().setHSL(Math.random() * 0.1 + 0.0, 0.8, 0.5); // Orange, Yellow, Red hues
                const bodyMat = new THREE.MeshStandardMaterial({ color: color, roughness: 0.3, metalness: 0.1 });
                this.body = new THREE.Mesh(bodyGeo, bodyMat);
                this.group.add(this.body);

                // Tail
                const tailGeo = new THREE.ConeGeometry(0.5, 2, 4);
                tailGeo.rotateX(Math.PI / 2);
                this.tail = new THREE.Mesh(tailGeo, bodyMat);
                this.tail.position.z = 1.5;
                this.group.add(this.tail);

                // Eye
                const eyeGeo = new THREE.SphereGeometry(0.15, 8, 8);
                const eyeMat = new THREE.MeshBasicMaterial({ color: 0x000000 });
                this.leftEye = new THREE.Mesh(eyeGeo, eyeMat);
                this.leftEye.position.set(1.2, 0.3, 0.4);
                this.group.add(this.leftEye);

                this.rightEye = new THREE.Mesh(eyeGeo, eyeMat);
                this.rightEye.position.set(1.2, -0.3, 0.4);
                this.group.add(this.rightEye);

                // Fins
                const finGeo = new THREE.BufferGeometry();
                const finVertices = new Float32Array([
                    0, 0, -0.5,   1, 0, 0,   0, 0, 0.5,
                    0, 0, -0.5,   0, 0.5, 0,  0, 0, 0.5
                ]);
                finGeo.setAttribute('position', new THREE.BufferAttribute(finVertices, 3));
                const finMat = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide });
                this.fin = new THREE.Mesh(finGeo, finMat);
                this.fin.position.set(0, 0.5, 0);
                this.group.add(this.fin);

                // Random Initial Properties
                this.position = new THREE.Vector3(
                    (Math.random() - 0.5) * 30,
                    (Math.random() - 0.5) * 15 + 5, // Keep mostly in middle area
                    (Math.random() - 0.5) * 30
                );
                
                this.velocity = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize().multiplyScalar(0.3);
                this.targetVelocity = this.velocity.clone();
                this.speed = 0.3 + Math.random() * 0.2;
                this.wiggleSpeed = 0.1 + Math.random() * 0.2;
                this.wiggleOffset = Math.random() * 100;

                scene.add(this.group);
            }

            update(mousePos, time) {
                // 1. Calculate Scare Force
                const distToMouse = this.position.distanceTo(mousePos);
                const scareForce = new THREE.Vector3();

                if (distToMouse < MOUSE_INFLUENCE_RADIUS) {
                    // Vector from mouse to fish
                    const pushDirection = new THREE.Vector3().subVectors(this.position, mousePos).normalize();
                    const scareIntensity = (MOUSE_INFLUENCE_RADIUS - distToMouse) / MOUSE_INFLUENCE_RADIUS;
                    
                    scareForce.copy(pushDirection).multiplyScalar(scareIntensity * SCARE_FORCE);
                    
                    // Fish panics: increases speed
                    this.currentSpeed = this.speed * 2.5;
                } else {
                    // Return to normal speed and natural movement
                    this.currentSpeed = this.speed;
                    
                    // Natural wandering
                    const wanderForce = new THREE.Vector3(
                        Math.sin(time * 0.002 + this.wiggleOffset) * 0.05,
                        Math.cos(time * 0.003 + this.wiggleOffset) * 0.05,
                        Math.sin(time * 0.001 + this.wiggleOffset) * 0.05
                    );
                    this.targetVelocity.add(wanderForce).normalize();
                }

                // 2. Apply Physics
                // Interpolate velocity towards (target + scare)
                if (distToMouse >= MOUSE_INFLUENCE_RADIUS) {
                    this.velocity.lerp(this.targetVelocity, RETURN_FORCE);
                } else {
                    this.velocity.lerp(scareForce, 0.1);
                }

                // Update Position
                this.position.add(this.velocity.clone().multiplyScalar(this.currentSpeed));

                // 3. Boundary Constraints (Soft Walls)
                const bounds = { x: 18, y: 8, z: 18 };
                const margin = 2;

                if (this.position.x > bounds.x - margin) this.velocity.x -= 0.1;
                if (this.position.x < -bounds.x + margin) this.velocity.x += 0.1;
                if (this.position.y > bounds.y - margin) this.velocity.y -= 0.1;
                if (this.position.y < -bounds.y + margin) this.velocity.y += 0.1;
                if (this.position.z > bounds.z - margin) this.velocity.z -= 0.1;
                if (this.position.z < -bounds.z + margin) this.velocity.z += 0.1;

                // Keep velocity normalized to current speed
                this.velocity.normalize().multiplyScalar(this.currentSpeed);

                // 4. Update Mesh
                this.group.position.copy(this.position);

                // Rotate to face direction
                const lookTarget = this.position.clone().add(this.velocity);
                this.group.lookAt(lookTarget);

                // Tail Wiggle Animation
                const wiggle = Math.sin(time * 0.02 + this.wiggleOffset) * 0.5;
                if (distToMouse < MOUSE_INFLUENCE_RADIUS) {
                    // Fast tail wiggle when scared
                    this.tail.rotation.y = Math.sin(time * 0.05) * 0.8;
                } else {
                    this.tail.rotation.y = wiggle;
                }
            }
        }

        // --- Bubble Class ---
        class Bubble {
            constructor() {
                const geo = new THREE.SphereGeometry(Math.random() * 0.5 + 0.1, 8, 8);
                const mat = new THREE.MeshPhysicalMaterial({
                    color: 0xffffff,
                    transparent: true,
                    opacity: 0.4,
                    transmission: 0.8,
                    roughness: 0
                });
                this.mesh = new THREE.Mesh(geo, mat);
                this.reset();
                scene.add(this.mesh);
            }

            reset() {
                this.mesh.position.set(
                    (Math.random() - 0.5) * 35,
                    -10 + Math.random() * 20,
                    (Math.random() - 0.5) * 35
                );
                this.speed = 0.05 + Math.random() * 0.1;
                this.size = this.mesh.scale.x;
            }

            update() {
                this.mesh.position.y += this.speed;
                // Gentle wave motion
                this.mesh.position.x += Math.sin(this.mesh.position.y * 0.2 + Date.now() * 0.001) * 0.02;
                
                if (this.mesh.position.y > 10) {
                    this.reset();
                }
            }
        }

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

        const bubbles = [];
        for (let i = 0; i < BUBBLE_COUNT; i++) {
            bubbles.push(new Bubble());
        }

        // Mouse Tracking
        const mouse = new THREE.Vector3(1000, 1000, 1000); // Start off screen
        const raycaster = new THREE.Raycaster();
        const mousePlane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0); // Plane at z=0 for simplicity
        
        // Handle Mouse Move
        document.addEventListener('mousemove', (event) => {
            // Convert screen coordinates to normalized device coordinates
            const mouseX = (event.clientX / window.innerWidth) * 2 - 1;
            const mouseY = -(event.clientY / window.innerHeight) * 2 + 1;

            // Raycast to find intersection with a virtual plane in the aquarium
            raycaster.setFromCamera({ x: mouseX, y: mouseY }, camera);
            
            // Create a plane that faces the camera roughly at the center of the tank
            const targetPlane = new THREE.Plane();
            targetPlane.setFromNormalAndCoplanarPoint(
                camera.getWorldDirection(new THREE.Vector3()),
                new THREE.Vector3(0, 0, 0)
            );

            const intersectionPoint = new THREE.Vector3();
            raycaster.ray.intersectPlane(targetPlane, intersectionPoint);

            if (intersectionPoint) {
                // Clamp the mouse interaction area to the tank
                mouse.x = THREE.MathUtils.clamp(intersectionPoint.x, -20, 20);
                mouse.y = THREE.MathUtils.clamp(intersectionPoint.y, -10, 10);
                mouse.z = THREE.MathUtils.clamp(intersectionPoint.z, -20, 20);
            }
        });

        // --- Animation & Logic ---
        let isRunning = false;
        let startTime = 0;

        const startMessage = document.getElementById('start-message');
        const uiLayer = document.getElementById('ui-layer');

        function startDemo() {
            if (isRunning) return;
            isRunning = true;
            startTime = performance.now();
            
            // Hide UI
            startMessage.classList.add('hidden');
            setTimeout(() => {
                uiLayer.classList.add('hidden');
            }, 500);
        }

        // Start triggers
        document.addEventListener('click', startDemo);
        document.addEventListener('keydown', startDemo);

        // Initial Demo Mode (Auto Swim)
        let demoTime = 0;

        function animate() {
            requestAnimationFrame(animate);

            const time = performance.now();
            
            if (isRunning) {
                // Update Fish
                fish.forEach(f => f.update(mouse, time));
                
                // Update Bubbles
                bubbles.forEach(b => b.update());

                // Slowly move camera for better view if not controlled
                if (controls && !controls.enableDamping) {
                     camera.position.x = Math.sin(time * 0.0001) * 35;
                     camera.position.z = Math.cos(time * 0.0001) * 35;
                     camera.lookAt(0, 0, 0);
                }
            } else {
                // Demo Mode Animation
                demoTime += 0.01;
                // Move fish in wide circles
                fish.forEach((f, i) => {
                    const angle = (time * 0.0005) + (i * (Math.PI * 2 / FISH_COUNT));
                    const radius = 15 + (i % 3) * 2;
                    f.position.x = Math.cos(angle) * radius;
                    f.position.z = Math.sin(angle) * radius;
                    f.position.y = Math.sin(angle * 0.5) * 5;
                    
                    f.group.position.copy(f.position);
                    f.group.lookAt(0, 0, 0); // Look at center
                    
                    // Tail wiggle
                    f.tail.rotation.y = Math.sin(time * 0.01 + i) * 0.5;
                });
            }

            renderer.render(scene, camera);
        }

        // Controls
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.minDistance = 15;
        controls.maxDistance = 60;
        controls.target.set(0, 0, 0);

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

        // Start Loop
        animate();

        // Update Stats
        document.getElementById('fish-count').innerText = FISH_COUNT;

    </script>
</body>
</html>