3d-scene-creator
v0.1.0
Published
A simple utility to create and manage 3D scenes
Maintainers
Readme
Features
- 🎬 The SceneCreator class wraps Three.js and GSAP to provide a simple API to load models, animate objects, and setup 3D scenes
- ⚡ Optimized render function: only renders when something is moving
- 🎯 Type-safe API: Full TypeScript support with JSDoc documentation
- 🔧 Method chaining: All methods return
thisfor fluent API - 🎨 Easy animations: Color, opacity, position, and camera animations
- 🎮 Camera controls: Built-in OrbitControls with customizable settings
- 🌅 360° Skybox support: Load panoramic images as backgrounds
- 💾 Resource cleanup: Automatic memory management with
dispose()method - 🎯 Interactive mesh picking: Click, hover, and right-click detection on 3D objects with custom callbacks
Usage
Install
npm install 3d-scene-creatorQuick Start
import { SceneCreator } from "3d-scene-creator";
import * as THREE from "three";
// Create a container
const container = document.createElement('div');
container.style.height = '100vh';
container.style.width = '100%';
document.body.appendChild(container);
// Create scene
const scene = new SceneCreator(container);
// Setup scene with lighting and controls
scene.addLighting().addControls().addSkybox();
console.log("Scene ready!");Complete Example with Model Loading
import { SceneCreator } from "3d-scene-creator";
import * as THREE from "three";
const container = document.getElementById('canvas-container');
const scene = new SceneCreator(container, 1, new THREE.Vector3(15, 15, 15));
// Setup scene
scene
.addLighting()
.addControls()
.addSkybox("https://example.com/360-image.jpg");
// Load and animate a model
try {
const model = await scene.loadModel("/models/my-model.json");
model.name = "MyObject";
// Chain animations
scene
.animateModelColor("MyObject", "#ff0000", 2)
.animateModelPosition("MyObject", new THREE.Vector3(5, 0, 0), 3)
.animateModelOpacity("MyObject", 0.7, 2);
} catch (error) {
console.error("Failed to load model:", error);
}
// Move camera with callback
scene.moveCamera(
new THREE.Vector3(20, 20, 20),
new THREE.Vector3(0, 0, 0),
() => console.log("Camera animation complete!")
);
// Cleanup when done
window.addEventListener('beforeunload', () => {
scene.dispose();
});Loading 3D Models
// Load with default ObjectLoader
await scene.loadModel("/path/to/model.json");
// Load with custom loader
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
const gltfLoader = new GLTFLoader();
await scene.loadModel("/path/to/model.glb", gltfLoader);Camera Controls
// Add orbit controls with default settings
scene.addControls();
// Add with custom configuration
scene.addControls({
enableDamping: true,
dampingFactor: 0.05,
maxDistance: 100,
minDistance: 5
});
// Animate camera
scene.moveCamera(
new THREE.Vector3(10, 20, 20),
new THREE.Vector3(0, 5, 0)
);
// Reset to initial position
scene.resetCameraPosition();Lighting
// Add default lighting setup (recommended)
scene.addLighting();Skybox / Background
// Add skybox from 360° image
scene.addSkybox("https://example.com/panorama.jpg");
// Add colored skybox
scene.addSkybox(undefined, "#87CEEB"); // Sky blue
// Custom named skybox
scene.addSkybox("image.jpg", "#000000", "my-skybox");Animate Objects
const obj = await scene.loadModel("/model.json");
obj.name = "Character";
// Animate color
scene.animateModelColor("Character", "red", 2);
// Animate position
scene.animateModelPosition(
"Character",
new THREE.Vector3(-5, 2, 10),
3
);
// Animate opacity
scene.animateModelOpacity("Character", 0.5, 2);Interactive Object Picking
Enable interactive object selection with mouse click and hover events:
import { SceneCreator } from "3d-scene-creator";
import * as THREE from "three";
const scene = new SceneCreator(container);
scene.addLighting().addControls();
// Create some 3D objects...
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0xff6b6b });
const cube = new THREE.Mesh(geometry, material);
cube.name = "MyBox";
scene.scene.add(cube);
// Enable picking with callbacks
scene.enablePicking(
// Click callback
(object: THREE.Object3D) => {
console.log("Clicked:", object.name);
// Change color on click
if (object instanceof THREE.Mesh) {
object.material.color.set(Math.random() * 0xffffff);
}
},
// Hover callback
(object: THREE.Object3D | null) => {
if (object) {
console.log("Hovering over:", object.name);
// Highlight on hover
if (object instanceof THREE.Mesh) {
object.material.emissive.setHex(0xffffff);
}
} else {
console.log("Left object");
}
}
);
// Get the currently selected object
const selected = scene.getSelectedObject();
// Programmatic picking at specific mouse coordinates
const result = scene.pickAt(-0.5, 0.2); // Normalized coordinates (-1 to 1)
if (result) {
console.log("Picked object:", result.object.name);
console.log("Distance:", result.distance);
console.log("Hit point:", result.point);
}Resource Cleanup
Always call dispose() when done to prevent memory leaks:
scene.dispose(); // Stops rendering, clears scene, disposes rendererAPI Reference
SceneCreator Class
Constructor
constructor(
container?: HTMLElement,
scale?: number,
camPos?: THREE.Vector3,
targetPos?: THREE.Vector3
)Methods
Core Methods
attachRenderer(container: HTMLElement): this- Attach renderer to DOMloadModel(url: string, loader?: THREE.Loader): Promise<Object3D>- Load 3D modeldispose(): void- Clean up resources
Lighting & Scene Setup
addLighting(): this- Add default lightingaddSkybox(url?: string, color?: ColorRepresentation, name?: string): this- Add skyboxaddControls(overrides?: object): this- Add orbit controls
Camera
moveCamera(position: Vector3, target?: Vector3, callback?: Function): this- Animate cameraresetCameraPosition(): this- Reset to initial position
Animations
animateModelColor(name: string, color: string|number, duration?: number): thisanimateModelPosition(name: string, position: Vector3, duration?: number): thisanimateModelOpacity(name: string, value: number, duration?: number): this
Interactive Picking
enablePicking(onClickCallback?: (obj: Object3D) => void, onHoverCallback?: (obj: Object3D | null) => void): this- Enable object picking with click/hover eventsdisablePicking(): this- Disable pickinggetSelectedObject(): Object3D | null- Get currently selected/hovered objectpickAt(mouseX: number, mouseY: number): PickingResult | null- Pick object at normalized mouse coordinates
Rendering
startRenderLoop(): this- Start renderingstopRenderLoop(): this- Stop renderingsetAdditionalRenderFn(fn: () => void): this- Add custom render callback
