So I want to add 3d avataars in my streamlit project. But by three js it is possible. Is it possible to add 3js in my streamlit. If yes then any example code snippet.l to understand
Yes, you can do that by using a streamlit component
her is an exemple :
js_content = f'''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js GLTF Model</title>
<style>
body {{ margin: 0; }}
canvas {{ display: block; }}
#three-container {{ width: 100vw; height: 100vh; }}
</style>
<script type="importmap">
{{
"imports": {{
"three": "https://cdn.jsdelivr.net/npm/three@0.149.0/build/three.module.js",
"three/examples/jsm/": "https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/"
}}
}}
</script>
</head>
<body>
<div id="three-container"></div>
<script type="module">
import * as THREE from 'three';
import {{ OrbitControls }} from 'three/examples/jsm/controls/OrbitControls.js';
import {{ GLTFLoader }} from 'three/examples/jsm/loaders/GLTFLoader.js';
// and her u can write ur code
</script>
</body>
</html>
st.components.v1.html(js_content, height=1000, width=1000)
i used your code snippet but its just showing me black box.
the 3d model is not showing
i am a beginner in this kindly help me out
The code I shared with you does exactly what you need. You’ll need to add the behavior for your 3D object in the section where I left a comment. I’ll share an example of the behavior, including a section where you can insert your object—try modifying the path accordingly.
model_url = "http://localhost:8501/app/static/objet1/exemple.gltf" #make ur object path in this variable
html_content = f'''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js GLTF Model</title>
<style>
body {{ margin: 0; }}
canvas {{ display: block; }}
#three-container {{ width: 100vw; height: 100vh; }}
</style>
<script type="importmap">
{{
"imports": {{
"three": "https://cdn.jsdelivr.net/npm/three@0.149.0/build/three.module.js",
"three/examples/jsm/": "https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/"
}}
}}
</script>
</head>
<body>
<div id="three-container"></div>
<script type="module">
import * as THREE from 'three';
import {{ OrbitControls }} from 'three/examples/jsm/controls/OrbitControls.js';
import {{ GLTFLoader }} from 'three/examples/jsm/loaders/GLTFLoader.js';
let camera, scene, renderer;
function init() {{
const container = document.getElementById('three-container');
camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.25, 20);
camera.position.set(1, 0.9, 1);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({{ antialias: true }});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.maxDistance = 10;
controls.target.set(0, 0, -0.2);
controls.update();
const loader = new GLTFLoader();
loader.load('{model_url}', function (gltf) {{
const model = gltf.scene;
// here I'm applying a texture
model.traverse(function (child) {{
if (child.isMesh) {{
const textureLoader = new THREE.TextureLoader();
textureLoader.load('{image_url}', function (texture) {{
child.material.map = texture;
child.material.needsUpdate = true;
render();
}});
}}
}});
scene.add(model);
render();
}}, undefined, function (error) {{
console.error('An error happened:', error);
}});
window.addEventListener('resize', onWindowResize);
render();
}}
function onWindowResize() {{
const container = document.getElementById('three-container');
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
render();
}}
function render() {{
renderer.render(scene, camera);
}}
init();
</script>
</body>
</html>
'''
Hello thanks for the code snippet I tried it with my glb file but i still only get a black box, i don’t know what i’m doing wrong, it’s probbaly some settings cause the file can’t be found even if I used a file uploader… PLEASE save me on this project here is my code thanks a lot in advance to anyone who finds the solution (even gpt 4o did not find anything…)
import streamlit as st
from io import BytesIO
import os
def render_maquette():
# Upload the .glb file dynamically from the user
model_file = st.file_uploader(“Upload GLB model”, type=[“glb”, “gltf”])
if model_file is not None:
# Save the uploaded file to a temporary location
temp_path = "temp_model.glb"
with open(temp_path, "wb") as f:
f.write(model_file.getbuffer()) # Write the uploaded file to the disk
# Now, use the path to load the model in Three.js
model_url = temp_path # Path to the saved model file
# HTML and JavaScript code to render the model
html_content = f'''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js GLTF Model</title>
<style>
body {{ margin: 0; }}
canvas {{ display: block; }}
#three-container {{ width: 100vw; height: 100vh; }}
</style>
<script type="importmap">
{{
"imports": {{
"three": "https://cdn.jsdelivr.net/npm/three@0.149.0/build/three.module.js",
"three/examples/jsm/": "https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/"
}}
}}
</script>
</head>
<body>
<div id="three-container"></div>
<script type="module">
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.149.0/build/three.module.js';
import {{ OrbitControls }} from 'https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/controls/OrbitControls.js';
import {{ GLTFLoader }} from 'https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/loaders/GLTFLoader.js';
let camera, scene, renderer;
function init() {{
const container = document.getElementById('three-container');
camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.25, 20);
camera.position.set(1, 0.9, 1);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({{ antialias: true }});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.maxDistance = 10;
controls.target.set(0, 0, -0.2);
controls.update();
const loader = new GLTFLoader();
loader.load('{model_url}', function (gltf) {{
const model = gltf.scene;
scene.add(model);
render();
}}, undefined, function (error) {{
console.error('An error happened:', error);
}});
window.addEventListener('resize', onWindowResize);
render();
}}
function onWindowResize() {{
const container = document.getElementById('three-container');
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
render();
}}
function render() {{
renderer.render(scene, camera);
}}
init();
</script>
</body>
</html>
'''
# Display the HTML content in Streamlit
st.components.v1.html(html_content, height=800)