import panel as pn
from panel.custom import JSComponent
import param
import requests
pn.extension(template="fast")
class ThreeGLTFPlot(JSComponent):
width = param.Integer(default=800)
height = param.Integer(default=600)
gltf_data = param.Bytes(default=None, doc="The data stored in the GLTF file")
binary = param.Boolean(default=False)
def __init__(self, file_path: str):
super().__init__()
if file_path:
if file_path.startswith("http"):
response = requests.get(file_path)
response.raise_for_status() # Check for request errors
self.gltf_data = response.content
else:
with open(file_path, 'rb') as file:
self.gltf_data = file.read()
_esm = """
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
export function render({model, el }) {
// Create a scene
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
renderer.setSize(model.width, model.height);
el.appendChild(renderer.domElement);
// Create a camera
const camera = new THREE.PerspectiveCamera(75, el.clientWidth / el.clientHeight, 0.1, 1000);
camera.position.set(0, 1, 3);
load_gltf(model, scene)
// Add lighting
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(2, 2, 2);
scene.add(light);
// Add OrbitControls for radial control
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // Enable damping for smoother controls
controls.dampingFactor = 0.05;
// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update(); // Update controls for smooth camera movements
renderer.render(scene, camera); // Render the scene
}
animate();
}
function load_gltf(model, scene){
const loader = new GLTFLoader();
loader.parse(model.gltf_data, "", (gltf) => {
gltf.scene.children.map((object) => scene.add(object))
});
}
"""
_importmap = {
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.169/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
}
}
three_gltf = ThreeGLTFPlot("https://github.com/KhronosGroup/glTF-Sample-Models/raw/refs/heads/main/2.0/Duck/glTF-Binary/Duck.glb")
pn.Column(three_gltf).servable()