Newer
Older
about-Leaflet / VirtualShop-new.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="WebGL-output"></div>
    <button id="play-animation">("Ü")</button>
    
    <script type="module">
    import * as THREE from "https://unpkg.com/three@0.126.1/build/three.module.js";
    import { PointerLockControls } from "https://unpkg.com/three@0.126.1/examples/jsm/controls/PointerLockControls.js";
    import { GLTFLoader } from "https://unpkg.com/three@0.126.1/examples/jsm/loaders/GLTFLoader.js";
 
    let camera;
    let scene;
    let renderer;
    let controls;
    let moveForward = false;
    let moveBackward = false;
    let moveLeft = false;
    let moveRight = false;
    let bChanLoaded = false;
    let classroomModel, blackboardModel, bchanModel;
    let mixer;
    let action;
    let clock;

    function init() {
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xffffff);
    
        camera = new THREE.PerspectiveCamera(
            45,
            window.innerWidth / window.innerHeight,
            0.1,
            1000
        );
        camera.position.set(1, 5, 5);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
         // rendererの初期化を先に行う
    renderer = new THREE.WebGLRenderer({
        alpha: true,
        antialias: true,
    });
    renderer.setSize(window.innerWidth * 0.8, window.innerHeight * 0.8);
    renderer.domElement.style.position = 'absolute';
    renderer.domElement.style.left = '10%';
    renderer.domElement.style.top = '10%';
    document.getElementById("WebGL-output").appendChild(renderer.domElement);

    // controlsの初期化
    controls = new PointerLockControls(camera, renderer.domElement);
    
    // イベントリスナーの追加
    renderer.domElement.addEventListener("click", function () {
        controls.lock();
    });
 
        const light = new THREE.SpotLight(0xffffff, 1.0);
        light.position.set(100, 500, 500);
        scene.add(light);
        light.castShadow = true;
 
        const loader = new GLTFLoader();
 
        loader.load(
            'https://www.yatex.org/gitbucket/j2311/about-Leaflet/raw/main/class_room_final.glb',
            function (gltf) {
                classroomModel = gltf.scene;
                scene.add(classroomModel);
            },
            function (xhr) {
                console.log((xhr.loaded / xhr.total * 100) + '% loaded');
            },
            function (error) {
                console.error('An error happened', error);
            }
        );
 
        loader.load(
            'https://www.yatex.org/gitbucket/j2311/about-Leaflet/raw/main/black_board.glb',
            function (gltf) {
                blackboardModel = gltf.scene;
                scene.add(blackboardModel);
            },
            function (xhr) {
                console.log((xhr.loaded / xhr.total * 100) + '% loaded');
            },
            function (error) {
                console.error('An error happened', error);
            }
        );
 
        loader.load(
            'https://www.yatex.org/gitbucket/j2311/about-Leaflet/raw/main/B-chan_plus_feel.gltf',
            function (gltf) {
                bchanModel = gltf.scene;
                scene.add(bchanModel);
                bChanLoaded = true;

                mixer = new THREE.AnimationMixer(bchanModel);

                if (gltf.animations.length > 0) {
                    action = mixer.clipAction(gltf.animations[0]);
                }
            },
            function (xhr) {
                console.log((xhr.loaded / xhr.total * 100) + '% loaded');
            },
            function (error) {
                console.error('An error happened', error);
            }
        );

        controls = new PointerLockControls(camera, renderer.domElement);
        
        renderer.domElement.addEventListener("click", function () {
            controls.lock();
        });
 
        document.addEventListener("keydown", handleKeyDown);
        document.addEventListener("keyup", handleKeyUp);
 
        renderer = new THREE.WebGLRenderer({
            alpha: true,
            antialias: true,
        });
        renderer.setSize(window.innerWidth * 0.8, window.innerHeight * 0.8);
        renderer.domElement.style.position = 'absolute';
        renderer.domElement.style.left = '10%';
        renderer.domElement.style.top = '10%';
        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        clock = new THREE.Clock();

        document.getElementById('play-animation').addEventListener('click', playAnimation);
    }

    function handleKeyDown(event) {
        switch (event.key) {
            case "w":
            case "ArrowUp":
                moveForward = true;
                break;
            case "s":
            case "ArrowDown":
                moveBackward = true;
                break;
            case "a":
            case "ArrowLeft":
                moveLeft = true;
                break;
            case "d":
            case "ArrowRight":
                moveRight = true;
                break;
            case "g":
                if (bChanLoaded) {
                    bchanModel.position.z -= 0.5;
                }
                break;
            case "b":
                if (bChanLoaded) {
                    bchanModel.position.z += 0.5;
                }
                break;
            case "f":
                if (bChanLoaded) {
                    bchanModel.position.x -= 0.5;
                }
                break;
            case "h":
                if (bChanLoaded) {
                    bchanModel.position.x += 0.5;
                }
                break;
        }
    }
 
    function handleKeyUp(event) {
        switch (event.key) {
            case "w":
            case "ArrowUp":
                moveForward = false;
                break;
            case "s":
            case "ArrowDown":
                moveBackward = false;
                break;
            case "a":
            case "ArrowLeft":
                moveLeft = false;
                break;
            case "d":
            case "ArrowRight":
                moveRight = false;
                break;
        }
    }
    
    function updateCameraPosition() {
        const speed = 5;
        const direction = new THREE.Vector3();
        const { x, y, z } = controls.getObject().position;
        direction.x = Number(moveRight) - Number(moveLeft);
        direction.z = Number(moveBackward) - Number(moveForward);
        direction.normalize();
        const delta = speed * 0.1;
        controls.getObject().translateX(direction.x * delta);
        controls.getObject().translateZ(direction.z * delta);
    }
 
    function animate() {
        requestAnimationFrame(animate);
        updateCameraPosition();

        if (mixer) {
            mixer.update(clock.getDelta());
        }

        renderer.render(scene, camera);
    }

    function playAnimation() {
        if (action) {
            action.reset();
            action.play();
        }
    }
 
    document.addEventListener("dblclick", function (event) {
        event.preventDefault();
        const raycaster = new THREE.Raycaster();
        const mouse = new THREE.Vector2();
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);
        const intersects = raycaster.intersectObjects(scene.children, true);
        if (intersects.length > 0) {
            if (intersects[0].object.name === "blackboard_main") {
                window.open("https://www.yatex.org/gitbucket/j2311/about-Leaflet/pages/HELPLIST-web.html");
            }
            console.log(intersects[0]);
        }
    });
 
    init();
    animate();
    </script>
</body>
</html>