Music Forem

Bad Builders
Bad Builders

Posted on

baloon dog

`<!DOCTYPE html>



Three.js Balloon Dog
<br> body { margin: 0; overflow: hidden; background-color: #111827; }<br> canvas { display: block; width: 100vw; height: 100vh; }<br>


<!-- Three.js Library -->

<!-- OrbitControls -->
<script>
    // Main initialization function
    function init() {
        // 1. Scene Setup
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x111827);
        scene.fog = new THREE.Fog(0x111827, 20, 100);

        // 2. Camera Setup
        const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(15, 12, 15);

        // 3. Renderer Setup
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        document.body.appendChild(renderer.domElement);

        // 4. Orbit Controls
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.autoRotate = true;
        controls.autoRotateSpeed = 0.5;

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

        const dirLight = new THREE.DirectionalLight(0xffffff, 1);
        dirLight.position.set(10, 20, 10);
        dirLight.castShadow = true;
        dirLight.shadow.mapSize.width = 2048;
        dirLight.shadow.mapSize.height = 2048;
        scene.add(dirLight);

        // Add some point lights to enhance the metallic reflection
        const pointLight1 = new THREE.PointLight(0xffffff, 0.5);
        pointLight1.position.set(-10, 10, -10);
        scene.add(pointLight1);

        const pointLight2 = new THREE.PointLight(0xffffff, 0.5);
        pointLight2.position.set(10, 5, -10);
        scene.add(pointLight2);

        // 6. Grid Helper
        const gridHelper = new THREE.GridHelper(50, 50, 0x444444, 0x222222);
        scene.add(gridHelper);

        // 7. Balloon Dog Construction

        // Material - Metallic Magenta/Pink style
        const balloonMaterial = new THREE.MeshPhysicalMaterial({
            color: 0xE0249B,      // Magenta
            metalness: 0.7,
            roughness: 0.15,
            clearcoat: 1.0,
            clearcoatRoughness: 0.1,
            reflectivity: 1.0
        });

        // Helper to create a balloon segment (Capsule approximation for r128)
        function createBalloonSegment(length, radius) {
            const group = new THREE.Group();

            // Cylinder
            const cylinderGeo = new THREE.CylinderGeometry(radius, radius, length, 32);
            const cylinder = new THREE.Mesh(cylinderGeo, balloonMaterial);
            cylinder.castShadow = true;
            cylinder.receiveShadow = true;
            group.add(cylinder);

            // Top Cap
            const sphereGeo = new THREE.SphereGeometry(radius, 32, 16);
            const topCap = new THREE.Mesh(sphereGeo, balloonMaterial);
            topCap.position.y = length / 2;
            topCap.castShadow = true;
            topCap.receiveShadow = true;
            group.add(topCap);

            // Bottom Cap
            const bottomCap = new THREE.Mesh(sphereGeo, balloonMaterial);
            bottomCap.position.y = -length / 2;
            bottomCap.castShadow = true;
            bottomCap.receiveShadow = true;
            group.add(bottomCap);

            return group;
        }

        // Group to hold the whole dog
        const dogGroup = new THREE.Group();

        const radius = 0.8;

        // --- Body ---
        const torsoLength = 4;
        const torso = createBalloonSegment(torsoLength, radius);
        torso.rotation.z = Math.PI / 2;
        torso.position.y = 3.5;
        dogGroup.add(torso);

        // --- Legs (Back) ---
        const legLength = 3.5;
        const backLegLeft = createBalloonSegment(legLength, radius);
        backLegLeft.position.set(-2, 1.75, 0.6); // Offset X (back), Y (height/2), Z (width)
        dogGroup.add(backLegLeft);

        const backLegRight = createBalloonSegment(legLength, radius);
        backLegRight.position.set(-2, 1.75, -0.6);
        dogGroup.add(backLegRight);

        // --- Legs (Front) ---
        const frontLegLeft = createBalloonSegment(legLength, radius);
        frontLegLeft.position.set(2, 1.75, 0.6);
        dogGroup.add(frontLegLeft);

        const frontLegRight = createBalloonSegment(legLength, radius);
        frontLegRight.position.set(2, 1.75, -0.6);
        dogGroup.add(frontLegRight);

        // --- Neck ---
        const neckLength = 2.5;
        const neck = createBalloonSegment(neckLength, radius);
        neck.position.set(2.2, 5, 0); 
        neck.rotation.z = -Math.PI / 8; // Slight tilt back
        dogGroup.add(neck);

        // --- Head ---
        // Head is roughly a horizontal segment or a sphere. 
        // In balloon dogs, the head is a segment with a snout segment attached.
        const headLength = 2.0;
        const head = createBalloonSegment(headLength, radius);
        head.position.set(2.2, 6.8, 0);
        head.rotation.x = Math.PI / 2; // Make horizontal relative to camera view? No, rotation logic tricky.
        // Let's just place a sphere knot for the main head joint
        const headJoint = new THREE.Mesh(new THREE.SphereGeometry(radius * 1.1, 32, 32), balloonMaterial);
        headJoint.position.set(2.3, 6.5, 0);
        headJoint.castShadow = true;
        dogGroup.add(headJoint);

        // Snout
        const snoutLength = 1.5;
        const snout = createBalloonSegment(snoutLength, radius);
        snout.rotation.z = Math.PI / 2;
        snout.position.set(3.5, 6.5, 0); // Forward from head joint
        dogGroup.add(snout);

        // Nose tip (small black sphere)
        const noseGeo = new THREE.SphereGeometry(0.3, 16, 16);
        const noseMat = new THREE.MeshStandardMaterial({ color: 0x000000, roughness: 0.4 });
        const nose = new THREE.Mesh(noseGeo, noseMat);
        nose.position.set(4.4, 6.5, 0);
        dogGroup.add(nose);

        // --- Ears ---
        const earLength = 3.5;
        const earLeft = createBalloonSegment(earLength, radius);
        earLeft.position.set(2.3, 8.5, 0.5);
        dogGroup.add(earLeft);

        const earRight = createBalloonSegment(earLength, radius);
        earRight.position.set(2.3, 8.5, -0.5);
        dogGroup.add(earRight);

        // --- Tail ---
        const tailLength = 1.5;
        const tail = createBalloonSegment(tailLength, radius * 0.8);
        tail.position.set(-2.2, 4.5, 0);
        tail.rotation.z = Math.PI / 4;
        dogGroup.add(tail);

        // Add dog to scene
        scene.add(dogGroup);

        // 8. Animation Loop
        function animate() {
            requestAnimationFrame(animate);
            controls.update(); // Required for autoRotate and damping
            renderer.render(scene, camera);
        }
        animate();

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

        // 10. Parent Interactivity Functions
        // Defined inside init() to access closure variables (controls, gridHelper)

        window.resetCamera = function() {
            controls.reset();
            // If reset() stops autoRotate in some versions, ensure it's re-enabled
            controls.autoRotate = true;
            camera.position.set(15, 12, 15);
            camera.lookAt(0, 0, 0);
        };

        window.toggleGrid = function() {
            gridHelper.visible = !gridHelper.visible;
        };
    }

    // Start everything
    init();

</script>



 `

Top comments (0)