Three.ez - library for events, drag & drop, binding, focus management, smart rendering, tweening and more

Hello everyone, I wrote this library and would like to share it with you :slight_smile:

three.ez

npm Quality Gate Status DeepScan grade

three.ez is a TypeScript library designed to streamline and enhance the development of three.js applications.
It provides a comprehensive suite of user-friendly tools and high-performance features, making it accessible even to beginners.
With three.ez, you’ll discover an efficient and robust toolkit for your 3D projects.

This library has only one dependency: three.js r151+.

Key Features

Feature Description
Automatic Resize Handling Automatically resizes the Renderer, Camera, and EffectComposer.
Using the rendererResize event, you can easily set the resolution for custom shaders.
Smart Rendering Optimize performance by rendering frames only when necessary, reducing computational overhead.
Simplified Multiple Rendering Effortlessly manage rendering for multiple scenes or viewports within a single canvas.
Object3D Property Binding Streamline the management of Object3D properties.
Event Programming Add interactions to Object3D through programmable events, similar to DOM events.
You can bind events for changes in position, scale, rotation, visibility, and enabled state.
Focus and Blur Enhance interactivity with focus and blur events.
Drag and Drop Seamlessly integrate drag-and-drop functionality.
Hitbox Functionality Leverage hitboxes for customized intersections or simplified calculations.
Raycasting Options Choose between continuous or mouse movement-based raycasting, optimizing intersection operations.
Tweening Create smooth animations effortlessly with built-in tweening.
Simplified InstancedMesh Manage InstancedMesh instances with the ease of working with Object3D, simplifying creation and manipulation.

Installation

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

npm install @three.ez/main

Usage

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

const box = new Mesh(new BoxGeometry(0.1, 0.1, 0.1), new MeshNormalMaterial());
box.draggable = true;
box.on('animate', (e) => box.rotateX(e.delta).rotateY(e.delta * 2));
box.on(['pointerover', 'pointerout'], function (e) {
    this.tween('id').to(500, { scale: e.type === 'pointerover' ? 1.5 : 1 }, { easing: 'easeOutElastic' }).start();
});

const scene = new Scene().add(box);

const main = new Main();
main.createView({ scene, camera: new PerspectiveCameraAuto(70).translateZ(1) });

Live Examples

These examples use vite, and some mobile devices may run out of memory. However, there is one example without it.

Examples Collection

Documentation

The tutorial is available here (work in progress).

The API documentation is available here.

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.

Example on CodePen (drag and tween)

3 Likes

Thanks for sharing your library. It looks like it has a lot of useful features.
I always admire when people share their work … especially when the API is well documented.

Smart rendering is good, I also have some form of it, for two end-user’s reasons:

  • less noise and heating when 3D is run on a laptop
  • more battery when 3D is run on a smartphone

Is this list (position, scale,…) the complete list? If it is, you should also monitor for changes in materials, changes in environment …

Also, when in VR mode, optimizing scene rendered could be tricky. I found this the hard way – I tried to restrict FPS by skipping some of the render requests – and the result was strong photoepilepsy inducing flickering.

2 Likes

Thank you very much for the feedback!

Currently only those changes are automatically detected and that is because the position, scale, rotation and visibility are overridden, so the cost is a single extra operation for changing the needsRender flag.

There is not, currently, an automatism that controls all object changes (materials, geometries, etc.) because it might slow down performance, so in case I do, it will probably be a separate package.

It is, however, possible to change the flag of needsRender manually by editing it on any Object3D that is added to a scene, as in this example:

const draggableBox = new Mesh(new BoxGeometry(0.2, 0.2, 0.2), new MeshLambertMaterial({ color: 'green' }));
draggableBox.draggable = true;
draggableBox.on(['pointerenter', 'pointerleave'], function(e) {
  this.material.color.set(e.type === 'pointerenter' ? 'yellow' : 'green');
  this.needsRender = true; // necessary because color change cannot be auto detected
});

const scene = new Scene();
scene.activeSmartRendering(); // auto detect drag moves in this case
scene.add(new AmbientLight(), new DirectionalLight().translateZ(1), draggableBox);

const main = new Main();
main.createView({ scene, camera: new PerspectiveCameraAuto(70).translateZ(1) });

I wrote this library to simplify writing examples or 3d viewers, although it can be used for something more complex, but I did not consider VR. I will definitely try it!

Soon I will add more features such as fps setting, continuous raycasting frequency, multidrag and multifocus.

1 Like

Cool library, i made a little experiment with it:

It’s very useful and easy to use, especially the instaced mesh implementation, however i’m waiting for the complete documentation.

1 Like