Skip to content

Three.js orbit controls

Read as Markdown

Drag a cube using OrbitControls connected to Pibbl-routed input.

Plain source. Run as a browser module after the document body exists. TSX uses jsx: "react-jsx" and jsxImportSource: "@pibbl/core".

import { pibbl } from "@pibbl/core";
import { defineThreeLayer, type PibblThreeInputBridge } from "@pibbl/three";
import {
BoxGeometry,
Mesh,
MeshNormalMaterial,
PerspectiveCamera,
Scene,
} from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 220;
const status = document.createElement("p");
status.textContent = "Drag the cube to orbit the camera.";
document.body.append(canvas, status);
const OrbitLayer = defineThreeLayer<
{},
{
scene: Scene;
camera: PerspectiveCamera;
mesh: Mesh<BoxGeometry, MeshNormalMaterial>;
controls: OrbitControls;
}
>({
create(context) {
const scene = new Scene();
const camera = new PerspectiveCamera(60, 320 / 220, 0.1, 100);
camera.position.set(2.5, 1.8, 4);
camera.lookAt(0, 0, 0);
const mesh = new Mesh(
new BoxGeometry(1.7, 1.7, 1.7),
new MeshNormalMaterial(),
);
scene.add(mesh);
const input: PibblThreeInputBridge = context.input;
const controls = input.connect(
(element) => new OrbitControls(camera, element),
);
controls.addEventListener("change", () => {
status.textContent = `Camera azimuth: ${controls.getAzimuthalAngle().toFixed(2)} radians`;
context.invalidate();
});
return { scene, camera, mesh, controls };
},
resize(resources, size) {
resources.camera.aspect = size.width / size.height;
resources.camera.updateProjectionMatrix();
},
targets(resources) {
return [{ object: resources.mesh, cursor: "grab" }];
},
dispose(resources) {
resources.controls.dispose();
resources.mesh.geometry.dispose();
resources.mesh.material.dispose();
},
});
const controller = pibbl(
canvas,
<OrbitLayer style={{ width: 320, height: 220 }} />,
);
window.addEventListener("pagehide", () => controller.dispose(), { once: true });
  • This controls example demonstrates drag input. The separate cube example demonstrates Pibbl target clicks; connected controls and target clicks currently do not coexist reliably in Chromium.
  • Requires the three peer dependency, WebGL, and browser OffscreenCanvas support.

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.