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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rbxts/viewportmodel

v1.0.2

Published

Type script version of the EgoMoose module "ViewportModel.lua". It's a module calculating the camera position to fit a model in the viewport frame.

Readme

ViewportModel.ts

ViewportModel.ts is a TypeScript version of the EgoMoose module ViewportModel.lua. It calculates the camera position to fit a model in the viewport frame.

The original Lua module can be found here: Github: EgoMoose/ViewportModel.lua

You can also find the Roblox Devforum post here: Devforum: ViewportFrame Model Fitter

Quick Start

Install

To install the module, you can use npm:

npm i @rbxts/viewportmodel

Usage

// Setup viewport frame and camera
const viewportFrame = PATH_TO_VIEWPORT_FRAME;
const camera = new Instance("Camera");
viewportFrame.CurrentCamera = camera;

const inst = MODEL_TEMPLATE:Clone();
inst.Parent = viewportFrame;

// Setup the ViewportModel
const viewportModel = new ViewportModel(viewportFrame, camera);
viewportModel.setModel(inst);


// Make the camera fit the model with the desired orientation
const angle = CFrame.fromEulerAnglesYXZ(-math.pi * 0.05, -math.pi * 0.2, 0);
const cf = viewportModel.getMinimumFitCFrame(angle);

camera.CFrame = cf;

Documentation

Constructor

Create a new ViewportModel instance using the constructor:

new (vpf: ViewportFrame, camera: Camera): ViewportModel;

Parameters:

  • vpf: The ViewportFrame to use for rendering the model.
  • camera: The Camera to use for rendering the model. This camera should be set to the ViewportFrame CurrentCamera property.

Methods

setModel

Used to set the model that is being focused on. Should be used for new models and/or a change in the current model.

e.g. parts added/removed from the model or the model cframe changed

setModel(model: Model): void;

Parameters:

  • model: The Model to set. This should be the model that you want to fit in the viewport frame.

calibrate

Should be called when something about the viewport frame / camera changes

e.g. the frame size or the camera field of view

calibrate(): void;

getFitDistance

Returns a fixed distance that is guaranteed to encapsulate the full model This is useful for when you want to rotate freely around an object w/o expensive calculations Focus position can be used to set the origin of where the camera's looking Otherwise the model's center is assumed

getFitDistance(focusPosition?: Vector3): number;

Parameters:

  • focusPosition: Optional. The position to focus on. If not provided, the model's center will be used.

getMinimumFitCFrame

Returns the optimal camera cframe that would be needed to best fit the model in the viewport frame at the given orientation. Keep in mind this functions best when the model's point-cloud is correct as such models that rely heavily on meshes, csg, etc will only return an accurate result as their point cloud

getMinimumFitCFrame(orientation: CFrame): CFrame;

Parameters:

  • orientation: The orientation to use for the camera. This should be a CFrame representing the desired orientation of the camera.

Examples

Fixed Minimum Distance with rotating camera

The first example is to calculate a fixed minimum distance that’s guaranteed to contain the model regardless of the camera orientation or viewport size.

// Setup viewport frame and camera
const viewportFrame = PATH_TO_VIEWPORT_FRAME;
const camera = new Instance("Camera");
viewportFrame.CurrentCamera = camera;

const inst = MODEL_TEMPLATE:Clone();
inst.Parent = viewportFrame;

// Setup the ViewportModel
const viewportModel = new ViewportModel(viewportFrame, camera);
viewportModel.setModel(inst);



// Make the camera rotating while fitting the model
const distance = viewportModel.getFitDistance();

RunService.RenderStepped:Connect(() => {
    // Update the camera CFrame
    camera.CFrame = cf.mul(CFrame.fromEulerAnglesYXZ(math.rad(-20), math.rad(tick() * 20) % (math.pi * 2), 0).mul(CFrame.new(0, 0, distance)));
});

Minimum Fit in every Orientation while camera is rotating

The second example is to calculate a camera cframe that best fits the model given an orientation. This will mean that the model will always be touching at least one edge of the viewport frame.

However, it’s important to note that this calculation is based off of the model’s point cloud meaning meshes, csg, and/or any other base part that makes it difficult to get a proper point cloud may cause this calculation to seem inaccurate.

// Setup viewport frame and camera
const viewportFrame = PATH_TO_VIEWPORT_FRAME;
const camera = new Instance("Camera");
viewportFrame.CurrentCamera = camera;

const inst = MODEL_TEMPLATE:Clone();
inst.Parent = viewportFrame;

// Setup the ViewportModel
const viewportModel = new ViewportModel(viewportFrame, camera);
viewportModel.setModel(inst);



// Make the camera rotating while fitting the model
RunService.RenderStepped:Connect(() => {
    const orientation = CFrame.fromEulerAnglesYXZ(math.rad(-20), math.rad(tick() * 20) % (math.pi * 2), 0);
    const cf = viewportModel.getMinimumFitCFrame(orientation);
    camera.CFrame = cf
});