/three.ez

Simplify three.js development, including events, drag & drop, binding, focus management, smart rendering, tweening and more.

Primary LanguageTypeScriptMIT LicenseMIT

three.ez

npm version Quality Gate Status DeepScan grade CodeFactor BundlePhobia

three.ez is a library designed to simplify the development of a three.js application, enabling the easy creation of reusable and maintainable components and providing a range of other functionalities. It offers high performance on desktops and mobile devices.

Features

Automatic Resize Handling

Automatically resizes Renderer, Camera, EffectComposer. Using rendererResize event is also possibile to set resolution for custom shaders.

Smart Rendering

Smart rendering allows a frame to render only when it is needed, which is particularly useful when using mostly static scenes, optimizing performance and reducing unnecessary computational overhead.
It is based on a Scene property called needsRender, which is changed automatically when there is a change in position, scale, rotation, visiblity, focus, removal or addition of Object3D. It is also possible to change it manually, in cases where changes are not automatically identified.

Simplified Rendering

The rendering of viewports is handled by the Main class, using the createView method, which returns an instance of RenderView.
By modifying the various properties of this instance, various parameters can be changed, including: the size, position, background, interaction state, and visibility. It is also possible to specify an EffectComposer for each RenderView to handle post-processing effects.

Object3D Property Binding

It is possible to bind to a property of an Object3D the result of a callback, using the bindProperty method.
The bindings are computed automatically during each animate cycle. To manually compute the various bindings using the setManualDetectionMode and detectChanges methods.

Event Programming

It facilitates interaction with Object3D by adding a series of programmable events.
Interaction events work similarly to DOM events, with the same propagation and methods such as preventDefault or stopPropagation.
Events list: InteractionEventsMiscEventsUpdateEvents

Focus and Blur

Implements focus handling and related events to handle certain interactions more easily.
By setting the value of the focusable property of an Object3D you can determine whether it can receive focus.

Drag and Drop

Implements drag and drop handling and related events by adding two properties to each Object3D:

  • draggable: makes an object draggable.
  • findDropTarget: determines whether intersections with drop targets will be checked during dragging.

The drag can be cancelled by pressing 'Esc'.

Hitbox Functionality

Hitboxes can be used to handle a different intersection area or to simplify intersection calculations.

Raycasting Options

It is possible to choose between continuous raycasting (every frame) or raycasting only during mouse movement, providing the flexibility to optimise raycasting operations according to application requirements.
In addition, it is possible to choose which objects can be intersected, setting interceptByRaycaster property.

Tweening

Implements smooth animations effortlessly with built-in tweening functionality. Vector3, Euler, Quaternion, Color are supported.

Simplified InstancedMesh

With the class InstancedMesh2 it is possible to handle each sub-entity of an InstancedMesh as if it were an Object3D. This makes development much simpler and more intuitive.

How It Works

The Main class handles rendering, resizing, events and all other functionality.
The Main class documentation is available here.
In addition, methods and properties have been added to the Object3D and Scene classes.
List of properties and methods added: Object3DScene

Installation

You can install three.ez via npm using the following command:

npm install @three.ez/main

Usage

Example of a simple animated and draggable box:

import { Scene as SceneBase, Mesh, BoxGeometry, MeshNormalMaterial } from 'three';
import { Main as MainBase, PerspectiveCameraAuto } from '@three.ez/main';

class DraggableBox extends Mesh {
  constructor() {
    super(new BoxGeometry(0.2, 0.2, 0.2), new MeshNormalMaterial());
    this.draggable = true;
    this.on('animate', (e) => this.rotateX(e.delta).rotateY(e.delta * 2));
  }
}

class Scene extends SceneBase {
  constructor() {
    super();
    this.add(new DraggableBox());
  }
}

class Main extends MainBase {
  constructor() {
    super();
    this.createView({ scene: new Scene(), camera: new PerspectiveCameraAuto(70).translateZ(1) });
  }
}

const main = new Main();
Show smaller version
import { Scene, Mesh, BoxGeometry, MeshNormalMaterial } from 'three';
import { Main, PerspectiveCameraAuto } from '@three.ez/main';

const box = new Mesh(new BoxGeometry(0.2, 0.2, 0.2), new MeshNormalMaterial());
box.draggable = true;
box.on('animate', (e) => box.rotateX(e.delta).rotateY(e.delta * 2));
const scene = new Scene().add(box);
const main = new Main();
main.createView({ scene, camera: new PerspectiveCameraAuto(70).translateZ(1) });

Override Typescript Type Definition

To extend the definitions of three, go into ts.config and add this path:

"compilerOptions": {
  "paths": {
    "three": ["./node_modules/@three.ez/main/types"]
  }
}

Live Examples

These examples use vite and some mobile devices may go out of memory. There is one example without vite.

Examples Collection

Documentation

The API documentation is available here.
If there is demand, comprehensive, guided tutorials will be written for each functionality.

Contributing

Any help is highly appreciated. If you would like to contribute to this package or report problems, feel free to open a bug or pull request.

Questions?

If you have questions or need assistance, you can create a discussion in the appropriate section.