npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vctrl/hooks

v0.2.2

Published

vctrl/hooks is a React hooks package designed to simplify 3D model loading and management within React applications. It's part of the vectreal-core ecosystem and is primarily used in the vctrl/viewer React component and the official website application.

Downloads

412

Readme

vctrl/hooks

Version and release packages to NPM @vctrl/hooks | NPM Downloads

This library is still undergoing heavy development until the first major version is released. This may lead to breaking changes in upcoming updates.

Overview

vctrl/hooks is a React hooks package designed to simplify 3D model loading and management within React applications. It's part of the vectreal-core ecosystem and is primarily used in the vctrl/viewer React component and the official website application.

The package provides a powerful hook for loading various 3D model file formats, along with a React context for easy state management and an event system for handling different stages of the model loading process.

Table of contents

Features

  • Direct 3D model file loading (supports GLTF, GLB, and USDZ formats)
  • React context for state management (ModelContext)
  • Event system for handling loading progress and completion
  • Three.js integration
  • TypeScript support

Installation

To install the package, use npm or yarn:

npm install @vctrl/hooks
# or
yarn add @vctrl/hooks

Usage

The main hook exported by this package is useLoadModel. Here's a basic example of how to use it:

import React from 'react';
import { useLoadModel } from '@vctrl/hooks/use-load-model';

function ModelLoader() {
  const { load, file, progress, isLoading } = useLoadModel();

  const onFileChange = (event) => {
    const files = Array.from(event.target.files);
    load(files);
  };

  return (
    <div>
      <input type="file" onChange={onFileChange} />
      {isLoading && <p>Loading: {progress}%</p>}
      {file && <p>Model loaded: {file.name}</p>}
    </div>
  );
}

Multiple files can be handled, e.g. when uploading a .gltf model, its .bin file and the relavant image texture files as .jpeg/.png (Other texture file formats have not been tested).

The useLoadModel and useOptimizeModel hooks may be used together or standalone to optimize gltf based scenes.

  1. Either use the optimizer directly with the useLoadModel hook

    import React from 'react';
    import { useLoadModel } from '@vctrl/hooks/use-load-model';
    import { useOptimizeModel } from '@vctrl/hooks/use-optimize-model';
    
    function ModelLoader() {
      const optimizer = useOptimizeModel();
      const { load: loadFile, file, optimize } = useLoadModel(optimizer);
      const { load: loadModel, getModel, simplifyOptimization } = optimize;
    
      async function handleClick() {
        await simplifyOptimization();
      }
    }

Changes are applied to the file.model field from useLoadModel automatically when using optimizations

  1. Or use the optimizer together with the ModelProvider

    // App.tsx
    import { ModelProvider } from '@vctrl/hooks/use-load-model';
    import { useOptimizeModel } from '@vctrl/hooks/use-optimize-model';
    
    function App() {
       const optimizer = useOptimizeModel();
    
       return (
         <ModelProvider optimizer={optimizer}>
           <Scene>
         </ModelProvider>
       )
    }
    // Scene.tsx
    import { useModelContext } from '@vctrl/hooks/use-load-model';
    
    function Scene() {
      const { optimize } = useModelContext();
      const { load, getModel, simplifyOptimization } = optimize;
    
      //...
    }

API Reference

useLoadModel

The main hook for loading and managing 3D model files.

Returns

  • file: The loaded file object of type ModelFile | null.
  • isLoading: A boolean indicating whether a file is currently being loaded.
  • progress: A number between 0 and 100 representing the loading progress.
  • load: A function to handle file upload. It accepts an array of File objects or a mixed array of File objects and directory entries.
  • reset: A function to reset the internal state back to it's initial values.
  • on: A function to subscribe to events.
  • off: A function to unsubscribe from events.
  • optimize: An object optionally populated by the useOptimizeModel hook

useOptimizeModel

An addon that may be used in conjunction with the useLoadModel hook. It populates the optimize property returned by the useLoadModel and useModelContext hooks.

Returns

  • load: Loads a Three.js Object3D model into the optimizer.
  • getModel: Simplifies the current model document using the MeshoptSimplifier.
  • simplifyOptimization: Returns the current model document as a binary array buffer.

ModelContext

A React context that provides the state and functions from useLoadModel to child components. It's implemented in model-context.tsx.

import { ModelProvider, useModelContext } from '@vctrl/hooks/use-load-model';

function App() {
  return (
    <ModelProvider>
      <ModelConsumer />
    </ModelProvider>
  );
}

function ModelConsumer() {
  const { file, isLoading, progress, load } = useModelContext();
  // Use the context values
}

When using the React Context, only load models with the useModelContext hook.

Event System

The package includes a custom event system for handling various stages of the model loading process. The event system is implemented in event-system.ts and provides three main methods:

  • emit<T extends EventTypes>(event: T, data: EventData[T]): void
  • on<T extends EventTypes>(event: T, handler: EventHandler<T>): void
  • off<T extends EventTypes>(event: T, handler: EventHandler<T>): void

Events

You can subscribe to these events using the on method:

  • 'UPLOAD_PROGRESS': Emitted with the current progress (0-100) during file upload.
  • 'UPLOAD_COMPLETE': Emitted with the loaded file object when the upload is complete.
  • 'MULTIPLE_3D_MODELS': Emitted if multiple supported 3D model files are detected in the upload.
  • 'UNSUPPORTED_FILE_TYPE': Emitted if an unsupported file type is uploaded.

Example usage:

const { on, off } = useLoadModel();

useEffect(() => {
  const handleProgress = (progress) => {
    console.log(`Upload progress: ${progress}%`);
  };

  on('UPLOAD_PROGRESS', handleProgress);

  return () => off('UPLOAD_PROGRESS', handleProgress);
}, [on, off]);

Supported File Types

The package currently supports the following 3D model file formats:

  • GLTF (.gltf)
  • GLB (.glb)
  • USDZ (.usdz)

These are defined in the ModelFileTypes enum in types.ts.

File Loading Process

The file loading process, particularly for GLTF files, is handled by the useLoadGltf hook in use-load-gltf.ts. This hook performs the following steps:

  1. Parses the GLTF file content.
  2. Embeds external resources (buffers and images) into the GLTF content.
  3. Uses Three.js GLTFLoader to parse the modified GLTF content.
  4. Dispatches actions to update the state with the loaded model.

The loading process includes progress updates, which are communicated through the event system.

State Management

The package uses a reducer pattern for state management, implemented in state.ts. The state includes:

  • file: The currently loaded model file.
  • isFileLoading: A boolean indicating if a file is being loaded.
  • progress: The current loading progress.
  • supportedFileTypes: An array of supported file types.

Actions for updating the state are defined in the Action type in types.ts.

Integration with Three.js

The package integrates with Three.js for handling 3D model rendering. The loaded models are compatible with Three.js scene rendering, with the model stored as a Three.js Object3D in the ModelFile interface.

Development

This package is part of a monorepo workspace managed with Nx. To contribute or modify the package:

  1. Clone the monorepo
  2. Install dependencies: npm install or yarn install
  3. Make your changes
  4. Build the package: nx build vctrl/hooks
  5. Test your changes: nx test vctrl/hooks

License

Please refer to the LICENSE file in the package root for licensing information.

Contributing

Contributions are welcome! Please read the contributing guidelines in the vectreal-core monorepo before submitting pull requests.

Support

For issues, feature requests, or questions, please file an issue in the GitHub repository.