<body ondragover="event.preventDefault()" ondrop="onDrop(event)">
        <babylon-viewer
            engine="WebGPU"
        environment="https://unpkg.com/@babylonjs/viewer@preview/assets/photoStudio.env"
                    source="https://raw.githubusercontent.com/BabylonJS/Assets/master/meshes/ufo.glb"

            animation-speed="1.5"
            hotspots="testHotSpot1 1 228 113 111 0.217 0.341 0.442"
        >
            <!-- <div slot="tool-bar" style="position: absolute; top: 12px; left: 12px; width: 100px; height: 36px">
                <button onclick="document.querySelector('babylon-viewer').toggleAnimation()">Toggle Animation</button>
            </div> -->
            <svg id="lines" style="position: absolute; width: 100%; height: 100%" xmlns="http://www.w3.org/2000/svg" class="lineContainer">
                <line class="line"></line>
            </svg>
        </babylon-viewer>
        <button class="toggle-dom-button" onclick="onToggleDOM()">Toggle DOM</button>
        <button class="toggle-engine-button" onclick="onToggleEngine()">Toggle Engine</button>

        <button id="anchor-button" class="toggle-hotspot-button" onclick="onToggleHotSpot()">Toggle Hot Spot</button>
              <button class="toggle-skybox-button" onclick="onToggleSkybox()">Toggle Skybox</button>
      
 <script type="module" src="https://unpkg.com/@babylonjs/viewer@preview/dist/babylon-viewer.esm.min.js"></script>
</script>
        <script>
            const viewerElement = document.querySelector("babylon-viewer");
            const lines = document.querySelectorAll("line");
            const hotspotResult = { screenPosition: [0, 0], worldPosition: [0, 0, 0] };

            let viewerDetails;
            viewerElement.addEventListener("viewerready", (event) => {
                viewerDetails = viewerElement.viewerDetails;

                console.log(`Viewer ready.`, viewerDetails);
            });
            viewerElement.addEventListener("modelchange", (event) => {
             console.log(`Model changed.`, viewerDetails);
             console.log(viewerElement)
               
            });
            let isViewerConnected = true;
            let hotspotVisible = false;
            let skyboxEnabled = false;

            (async () => {
                // The module referenced in the script tag above is loaded asynchronously, so we need to wait for it to load and for the custom element to be defined.
                // Alternatively, we could just await import("/packages/tools/viewer-alpha/src/index.ts") here instead.
                await customElements.whenDefined("babylon-viewer");
              
              //  await new Promise((resolve) => setTimeout(resolve, 2000));
                //viewerElement.source = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/main/2.0/BrainStem/glTF-Binary/BrainStem.glb";
                //viewerElement.environment = "";
                // error case
                //viewerElement.source = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/main/2.0/BrainStem/glTF-Binary/BrainStem2.glb";
              //  await new Promise((resolve) => setTimeout(resolve, 2000));
                //viewerElement.source = "https://playground.babylonjs.com/scenes/BoomBox.glb";
            })();

            async function onDrop(event) {
                const file = event.dataTransfer.files[0];
                if (file) {
                    event.preventDefault();
                    await customElements.whenDefined("babylon-viewer");
                    await viewerDetails.viewer.loadModel(file);
                }
            }

            // update hotspot svg
            function drawHotSpotLine(svgLine, name, rect) {
                if (viewerElement.queryHotSpot(name, hotspotResult) && rect) {
                    svgLine.setAttribute("x1", hotspotResult.screenPosition[0]);
                    svgLine.setAttribute("y1", hotspotResult.screenPosition[1]);
                    svgLine.setAttribute("x2", (rect.left + rect.right) / 2);
                    svgLine.setAttribute("y2", (rect.top + rect.bottom) / 2);
                }
            }

            // use requestAnimationFrame to update with renderer
            const startHotSpotLinesRenderLoop = () => {
                const hotspotBaseRect = document.querySelector("#anchor-button").getBoundingClientRect();
                drawHotSpotLine(lines[0], "testHotSpot1", hotspotBaseRect);
                if (hotspotVisible) {
                    requestAnimationFrame(startHotSpotLinesRenderLoop);
                }
            };

            function onToggleDOM() {
                isViewerConnected ? document.body.removeChild(viewerElement) : document.body.appendChild(viewerElement);
                isViewerConnected = !isViewerConnected;
            }

            function onToggleEngine() {
                viewerElement.engine = viewerElement.engine === "WebGL" ? "WebGPU" : "WebGL";
            }

            function onToggleHotSpot() {
                hotspotVisible = !hotspotVisible;
                lines[0].style.visibility = hotspotVisible ? "visible" : "hidden";
                startHotSpotLinesRenderLoop(); 
            }
          
          function onToggleSkybox(){
           
           if(skyboxEnabled){
 skyboxEnabled = !skyboxEnabled
             console.log(viewerDetails.viewer)
             console.log(viewerDetails.scene)
            viewerElement.environment ="https://unpkg.com/@babylonjs/viewer@preview/assets/photoStudio.env"

           } else{
              skyboxEnabled = !skyboxEnabled
             console.log("DISABLED")
      viewerElement.environment = null
           }
          }
        </script>

    </body>
  html,
            body {
                width: 100%;
                height: 100%;
                padding: 0;
                margin: 0;
                overflow: hidden;
            }

            .toggle-dom-button {
                position: absolute;
                top: 10px;
                right: 10px;
            }

            .toggle-engine-button {
                position: absolute;
                top: 40px;
                right: 10px;
            }

            .toggle-hotspot-button {
                position: absolute;
                top: 70px;
                right: 10px;
            }

            .toggle-skybox-button {
                position: absolute;
                top: 100px;
                right: 10px;
            }

            .lineContainer {
                pointer-events: none;
                display: block;
            }

            .line {
                stroke: #e6a516;
                stroke-width: 8;
                stroke-dasharray: 16;
            }

            babylon-viewer {
                /* --ui-foreground-color: red; */
                /* --ui-background-hue: 200;
                --ui-background-saturation: 70%; */
            }

            /* babylon-viewer::part(tool-bar) {
                border-radius: 0;
                left: 0;
                right: 0;
                bottom: unset;
                top: 0;
                width: unset;
                max-width: unset;
                transform: unset;
            } */
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.