Giter Club home page Giter Club logo

three.ez's Introduction

Three.ez

Simplify your three.js application development with three.ez!

three.ez on npm Quality Gate Status DeepScan grade GitHub Repo stars BundlePhobia Discord conversation

With three.ez, turn complexity into creativity. This lightweight yet powerful library allows you to make the most of Three.js with a reduced learning curve, making the creation of interactive 3D scenes a breeze. Perfect for developers of all levels.

Extend the functionalities of Object3D and Scene classes, making their usage more straightforward, and introduce utility classes.

The only one dependency is three.js r151+.

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

const box = new Mesh(new BoxGeometry(), new MeshNormalMaterial());
box.draggable = true; // make it draggable
box.on('animate', (e) => box.rotateX(e.delta).rotateY(e.delta * 2)); // animate it every frame
box.on(['pointerover', 'pointerout'], (e) => box.scale.setScalar(e.type === 'pointerover' ? 1.5 : 1));

const scene = new Scene().add(box);
const main = new Main(); // init inside the renderer, and handle events, resize, etc
main.createView({ scene, camera: new PerspectiveCameraAuto(70).translateZ(1) }); // create the view to be rendered

βœ… Why three.ez?

  • Program the logic of your Object3D more quickly and intuitively
  • Less code and cleaner
  • Streamlined rendering
  • Declarative and imperative programming
  • Compatible with your three.js code and external libraries
  • Easy to learn
  • High performance

πŸ”‘ Key Features

Add interactions to Object3D through programmable events, similar to DOM events, including a propagation system.
See events list here: Interaction, Miscellaneous, Update.

const box = new Mesh(geometry, material);
box.on('click', (e) => e.stopPropagation());
box.on('animate', (e) => console.log('animate'));
box.on('positionchange', () => console.log('position changed'));

πŸ”₯ Drag and Drop

Integrate drag and drop functionality. The drag is cancelled by pressing ESC.

const box = new Mesh(geometry, material);
box.draggable = true;
box.findDropTarget = true;
box.on('drag', (e) => console.log(`new position: ${e.position}`));

const plane = new Mesh(geometry, material);
plane.on('drop', (e) => console.log(`obj dropped on this: ${e.relatedTarget}`));

πŸš€ Focus and Blur

Enhance interactivity with focus and blur events.

const box = new Mesh(geometry, material);
box.focusable = true; // default is true
box.on('focus', (e) => console.log('focused'));
box.on('blur', (e) => console.log('focus lost'));

Streamline the management of Object3D properties.

const box = new Mesh(geometry, material);
box.bindProperty('visible', () => box.parent?.enabled); 

βœ‚οΈ Automatic Resize Handling

Automatically resizes the Renderer, Camera, and EffectComposer.
Utilize the viewportResize event to easily set the resolution for custom shaders.

const line = new Line2(geometry, material);
line.on('viewportresize', (e) => material.resolution.set(e.width, e.height));

πŸ’‘ Smart Rendering

Optimize performance by rendering frames only when necessary, reducing computational overhead.
Automatically identifies changes in position, scale, rotation, visibility, focus, blurring and addition or removal of objects.

const scene = new Scene();
scene.activeSmartRendering();

const box = new Mesh(new BoxGeometry(), new MeshLambertMaterial({ color: 'green' }));
box.draggable = true; // if you drag the frame, it automatically detects changes and renders the frame

box.material.color.set('yellow');
box.needsRender = true; // necessary because color change cannot be automatically detected

Effortlessly manage rendering for multiple scenes or viewports within a single canvas.

const main = new Main(); 
main.createView({ scene, camera, viewport: { left: 0, bottom: 0, width: 0.5, height: 1 } });
main.createView({ scene, camera, viewport: { left: 0.5, bottom: 0, width: 0.5, height: 1 } });

πŸ› οΈ Asset Management

Efficiently load and preload the assets for your 3D projects.

load:

const audioBuffer = await Asset.load(AudioLoader, 'audio.mp3', onProgressCallback, onErrorCallback);

preload:

// soldier.js
Asset.preload(GLTFLoader, 'https://threejs.org/examples/models/gltf/Soldier.glb');

export class Soldier extends Group {
  constructor() {
    super();
    const gltf = Asset.get('https://threejs.org/examples/models/gltf/Soldier.glb');
    this.add(...gltf.scene.children);
  }
}

// main.js
await Asset.preloadAllPending({ onProgress: (e) => console.log(e * 100 + '%'), onError: (e) => console.error(e) });
const main = new Main();
const soldier = new Soldier();

πŸŽ₯ Tweening

Create smooth animations effortlessly with built-in tweening.

box.tween().by(1000, { position: new Vector3(0, 0.5, 0) }, { easing: 'easeInOutBack' }).yoyoForever().start();

new Tween(box)
  .by(2000, { scale: 1, rotation: new Euler(Math.PI * 2, Math.PI, 0) }, { easing: 'easeOutElastic' })
  .delay(200)
  .to(1000, { scale: 1 }, { easing: 'easeOutBounce' })
  .start();

βš™οΈ Raycasting Customisable

Choose between continuous or mouse movement-based raycasting, optimizing intersection operations.
Set which objects to intersect from the main raycasting.

const scene = new Scene();
scene.continuousRaycasting = true; // default is false

const box = new Mesh(geometry, material);
box.interceptByRaycaster = false; // default is true

🎯 Hitbox Functionality

Leverage hitboxes for customized intersections or simplified calculations.

const ring = new Mesh(new RingGeometry(1, 1.5), new MeshBasicMaterial());
ring.hitboxes = [new Hitbox(new CircleGeometry(1.5))]; // intercept also inside the ring

πŸ’― Simplified InstancedMesh

Manage InstancedMesh instances with the ease of working with Object3D, simplifying creation and manipulation, including frustum culling.

const myInstancedMesh = new InstancedMesh2(geometry, material, count, (obj, index) => {
  obj.position.x += index;
  obj.scale.setScalar(2);
  obj.quaternion.random();
  obj.forceUpdateMatrix();
});

// How to handle instances
myInstancedMesh.instances[0].visible = false;
myInstancedMesh.instances[1].draggable = true;
myInstancedMesh.instances[2].rotateOnWorldAxis(xAxis, Math.PI);
myInstancedMesh.instances[2].updateMatrix();

πŸ” Query

Find and select Object3D using powerful query selectors.

scene.querySelectorAll('Mesh'); // Selects all the meshes in the scene.
scene.querySelectorAll('[name=box]'); // Selects all Object3D that have 'box' as their name.
scene.querySelectorAll('[name*=box]'); // Selects all Object3D that have 'box' anywhere in their name.
scene.querySelectorAll('Mesh.even'); // Selects meshes with both 'Mesh' type and 'even' tag.
scene.querySelectorAll('Group .even'); // Selects all Object3D with 'even' tag that are children of a 'Group'.
scene.querySelectorAll('Group > .even'); // Selects all direct children with 'even' tag under a 'Group'.
scene.querySelectorAll('Mesh, SkinnedMesh'); // Selects all meshes and skinned meshes in the scene.

⬇️ Installation

You can install it via npm using the following command:

npm install @three.ez/main

Or can import it from CDN:

<script type="importmap">
{
  "imports": {
    "three": "https://unpkg.com/[email protected]/build/three.module.js",
    "three/examples/jsm": "https://unpkg.com/[email protected]/examples/jsm/",
    "@three.ez/main": "https://unpkg.com/@three.ez/[email protected]/bundle.js"
  }
}
</script>

πŸ§‘β€πŸ’» 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.

❔ Questions?

If you have questions or need assistance, you can ask on our discord server.

⭐ Like it?

If you find this project helpful, I would greatly appreciate it if you could leave a star on this repository!
This helps me know that you appreciate my work and encourages me to continue improving it.
Thank you so much for your support! 🌟

three.ez's People

Contributors

agargaro avatar augusttty avatar gabrielecoco28 avatar luigidenora avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

three.ez's Issues

Drag & Drop Functionality Issue: Drag Operation Continues After Exiting Canvas

Description:

I've encountered a bug related to the drag & drop functionality on the canvas. Specifically, when I start dragging an object and then move the cursor outside the canvas while still holding the mouse button down, the drag operation does not terminate as expected.

Steps to reproduce:

  1. Start a drag on the canvas.
  2. Continue dragging the object outside of the canvas.
  3. Release the mouse button while the cursor is still outside the canvas.
  4. Move the cursor back inside the canvas.

Expected behavior:

When the mouse button is released outside the canvas, the drag operation should terminate. When the cursor re-enters the canvas, it should not be in a dragging state.

Actual behavior:

After performing the steps above, when the cursor re-enters the canvas, it is still in a dragging state as if the mouse button was never released.

Environment:

  • Browser: Chrome Version 119.0.6045.124

Resize on mobile

I think the scene viewport resize not work on mobile browser.

  • portrait mode: it have small gap above the scene
  • when switch to landscape : it not resize

I’m trying to fix it…

IMG_2743
IMG_2742

Specifying container for webgl canvas

Hello,

this is an awesome project that's adding a lot of the missing things in three.js!

Is there a way to create the canvas inside another html element (I did not find one).

And if not, is this planned sometime or is there a good workaround?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.