이 글은 Gradio HTML Javascript 렌더링 방법을 간략히 정리한다. 가끔, HTML, javascript(자바스크립트)를 Gradio 페이지에 표시하고 싶을 때가 있다. 예를 들어, Gradio 기존 컴포넌트에서 지원되지 않는 3D 그래픽을 렌더링해야 할 때가 있다.
하지만, Gradio는 HTML만 지원하고, javascript는 다양한 이유로 사용자가 직접 Gradio에서 실행하는 것을 허용하지 않는다. 이 경우, iframe 을 사용한다.
다음은 Gradio에서 3D graphic 렌더링을 위해 three.js를 사용하는 예를 보여준다.
import os, json, requests, gradio as gr
from gradio import Interface, File, Files, Button, Label, Markdown
class 3D_viewer_component:
def __init__(self, gr):
self.html_code = """
<iframe srcdoc="
<!DOCTYPE html>
<html>
<head>
<style>
body, html { margin: 0; overflow: hidden; height: 100%; }
canvas { display: block; }
</style>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js'></script>
</head>
<body>
<script>
const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0x111111, 1);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 0.1, 10000);
camera.position.z = 30;
camera.position.y = 10;
scene.add(camera);
const boxGeometry = new THREE.BoxGeometry(10, 10, 10);
const basicMaterial = new THREE.MeshBasicMaterial({ color: 0x0095dd });
const cube = new THREE.Mesh(boxGeometry, basicMaterial);
cube.position.x = -25;
cube.rotation.set(0.4, 0.2, 0);
scene.add(cube);
const torusGeometry = new THREE.TorusGeometry(7, 1, 16, 32);
const phongMaterial = new THREE.MeshPhongMaterial({ color: 0xff9500 });
const torus = new THREE.Mesh(torusGeometry, phongMaterial);
torus.rotation.set(0.5, 0.5, 0);
scene.add(torus);
const light = new THREE.PointLight(0xffffff);
light.position.set(-10, 15, 50);
scene.add(light);
let t = 0;
function render() {
t += 0.01;
requestAnimationFrame(render);
cube.rotation.y += 0.01;
torus.scale.y = Math.abs(Math.sin(t));
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
" width="100%" height="100%" style="border:none;"></iframe>
"""
self.component = gr.HTML(self.html_code)
with gr.Blocks(title='3D viewer') as interface:
gr.Markdown("# 3D viewer")
with gr.Row(equal_height=True):
3D_viewer_component(gr)
3D_viewer_component(gr)
interface.launch(share=True)
참고로, Gradio에서 공식적으로 추천하는 방법은 다음과 같이 커스텀 컴포넌트를 개발한 것이다.
- backend/ <- The python code for your custom component- frontend/ <- The javascript code for your custom component- demo/ <- A sample app using your component. Modify this!- pyproject.toml <- Used to build the package and specify package metadata.
Gradio 커스텀 컴포넌트 예시(Gradio Custom Components Gallery)
이외 3차원 모델 파일 뷰어는 Model3D 컴포넌트를 사용할 수도 있다.
레퍼런스