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

three-sprites

v0.0.6

Published

A library for THREE.JS to render and animate spritesheet-based tilemaps and sprites.

Downloads

94

Readme

three-sprites

A library for THREE.js to render, animate and layer spritesheet/tileset-based tilemaps and sprites. The project provides tiling-based versions of most THREE.js materials but also allows you to extend custom materials.

  • Load spritesheets/tilesets
  • Render, animate and tile sprites
  • Render and layer tilemaps
  • No texture cloning

ko-fi

Demos

Demo

Installation

Dependencies

Has a peer dependency to THREE.js.

NPM

Install via:

npm install three three-sprites

Import in ESM projects:

import * as THREE from "three";
import { SpriteMeshBasicMaterial, TilemapMeshBasicMaterial } from "three-sprites";

Import in CJS projects:

const THREE = require("three");
const { SpriteMeshBasicMaterial, TilemapMeshBasicMaterial } = require("three-sprites");

Browser / CDN

Configure import map:

<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js",
      "three-sprites": "https://cdn.jsdelivr.net/npm/three-sprites@latest/dist/browser/three-sprites.min.js",
    }
  }
</script>

Import in your project:

import * as THREE from "three";
import { SpriteMeshBasicMaterial, TilemapMeshBasicMaterial } from "three-sprites";

Usage

For details see the documentation and the demo source code.

Materials

The library provides exports for almost all THREE.js materials.

For sprites:

import {
  SpriteMeshBasicMaterial,
  SpriteMeshLambertMaterial,
  SpriteMeshStandardMaterial,
  SpriteMeshPhysicalMaterial,
  SpriteMeshPhongMaterial,
  SpriteMeshToonMaterial
} from "three-sprites"

For tilemaps:

import {
  TilemapMeshBasicMaterial,
  TilemapMeshLambertMaterial,
  TilemapMeshStandardMaterial,
  TilemapMeshPhysicalMaterial,
  TilemapMeshPhongMaterial,
  TilemapMeshToonMaterial
} from "three-sprites"

Chose the ones which fit your needs. They all provide the same interface around sprites/tilemaps but also come with the corresponding material's set of features.

Sprites

Render a sprite based on a tileset index

Working with a tileset (all tiles have the same size), you can use tile indices to render and animate sprites. The following example loads a tileset and renders one tile as a sprite.

// Import THREE.js and a material from thee-sprites
import * as THREE from "three";
import { SpriteMeshBasicMaterial } from "three-sprites";

// Load spritesheet or tileset
const texture = new THREE.TextureLoader().load("spritesheet.png");

// Turn off mipmapping to minimize seams on mag/min filters
texture.magFilter = THREE.LinearFilter;
texture.minFilter = THREE.LinearFilter;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;

// Create a mesh with the new material
const sprite = new THREE.Mesh(
  new THREE.PlaneGeometry(1, 1),
  new SpriteMeshBasicMaterial({
    side: THREE.FrontSide,
    precision: "highp",
    map: texture,
  }),
);

// Configure the tiling
sprite.material.tile({
  // Define the size of the tileset in px
  tileSize: { x: 128, y: 128 },
  // Define the size of the tiles in the tileset in px
  tilesetSize: { x: 16, y: 16 },
  // Set the index of the tile in the tileset to render
  // In this case, we display the fourth tile in the tileset
  // On a tileset of w/h 128/128 with tiles of 16/16, that's the tile at x/y 48/0
  tile: 3,
});

// Position the mesh and add it to your scene...
myScene.add(sprite)

With the sprite in your scene, animate through tile 3-6 based on tile indices:

let tileIndex = 3;
let lastts = 0;
const tick = ts => {
  if (tileIndex > 6)
    tileIndex = 3;
  // Set the corresponding tile
  sprite.tile({ tile: tileIndex++ });
  requestAnimationFrame(tick);
};
tick();

Render a sprite based on spritesheet coordinates

Working with a spritesheet instead of a tileset, you can use coordinates to render the sprite:

// Imports and mesh setup identical to the previous full example...

// Display a 16x32 sprite from a spritesheet
sprite.material.tile({
  // Define the size of the spritesheet in px
  tileSize: { x: 128, y: 128 },
  // Define the (top/left corner) coordinates of the tile in the spritesheet
  tile: { x: 32 , y: 16}
  // Define the size of tile
  tilesetSize: { x: 16, y: 32 },
});

Animate via coordinates:

const tick = ts => {
  // ...
  sprite.tile({ tile: { x: 32 + n, 16 + m } });
  // ...
};

Repeat a sprite on the mesh

Instead of fitting one tile on a mesh, you can repeat the same tile horizontally/vertically:

// Imports and mesh setup identical to the previous full example...

// Create a 10x2 mesh
const sprite = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 2),
  new SpriteMeshBasicMaterial({
    side: THREE.FrontSide,
    precision: "highp",
    map: texture,
  }),
);

// Display a 16x16 sprite and repeat it 9 times horizontally
// and 1 time vertically
sprite.material.tile({
  // Define the size of the spritesheet in px
  tileSize: { x: 128, y: 128 },
  // Define the (top/left corner) coordinates of the tile in the spritesheet
  tile: { x: 32 , y: 16}
  // Define the size of tile in the spritesheet
  tilesetSize: { x: 16, y: 16 },
  // Repeat the tile vertically/horizontally:
  repeat: { x: 10, y: 2 }
});

Use a tileset with spacing

When working with a tileset with spacing between tiles, you can crop them:

// Imports and mesh setup identical to the previous full example...

sprite.material.tile({
  tileSize: { x: 128, y: 128 },
  tilesetSize: { x: 16, y: 16 },
  tile: 4,
  repeat: { x: 10, y: 2 },
  // Define the space between tiles in px
  spacing: 2
});

Tilemaps

Render a tilemap from a tileset

Instead of rendering individual sprites, you can render multiple different tiles on one mesh.

// Import THREE.js and a material from thee-sprites
// Note that Tilemaps use a different base material as they run on
// different shaders compared to sprites
import * as THREE from "three";
import { TilemapMeshBasicMaterial } from "three-sprites";

// Load tileset
const texture = new THREE.TextureLoader().load("tileset.png");

// Turn off mipmapping to minimize seams on mag/min filters
texture.magFilter = THREE.LinearFilter;
texture.minFilter = THREE.LinearFilter;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;

// Create a mesh with the new material
const sprite = new THREE.Mesh(
  new THREE.PlaneGeometry(20, 10),
  new TilemapMeshBasicMaterial({
    side: THREE.FrontSide,
    precision: "highp",
    map: texture,
  }),
);

// Configure the tiling
sprite.material.tile({
  // Define the size of the tileset in px
  tileSize: { x: 128, y: 128 },
  // Define the size of tiles in the tileset
  tilesetSize: { x: 16, y: 16 },
  // Define the space between tiles in the tileset
  spacing: 0,
  // Define how many tiles to display in each direction
  repeat: { x: 10, y: 5 }
  // Define which tiles to render
  tiles: [
    0, 0, 1, 5, 3, 9, 2, 5, 0, 0,
    0, 4, 4, 2, 2, 2, 1, 9, 0, 0,
    0, 1, 1, 5, 0, 9, 4, 3, 4, 0,
    0, 1, 0, 5, 3, 9, 2, 5, 0, 3,
    0, 7, 8, 4, 3, 2, 1, 9, 8, 7,
  ],
});

// Position the mesh and add it to your scene...
myScene.add(sprite)

Layer tilemaps

Blend multiple tilemap layers on one mesh. Supports transparency.

// Imports and mesh setup identical to the previous full example...

// Configure the tiling
sprite.material.tile({
  // Define the size of the tileset in px
  tileSize: { x: 128, y: 128 },
  // Define the size of tiles in the tileset
  tilesetSize: { x: 16, y: 16 },
  // Define the space between tiles in the tileset
  spacing: 0,
  // Define how many tiles to display in each direction
  repeat: { x: 10, y: 5 }
  // Define which tiles to render
  tiles: [
    // Layer one
    0, 0, 1, 5, 3, 9, 2, 5, 0, 0,
    0, 4, 4, 2, 2, 2, 1, 9, 0, 0,
    0, 1, 1, 5, 0, 9, 4, 3, 4, 0,
    0, 1, 0, 5, 3, 9, 2, 5, 0, 3,
    0, 7, 8, 4, 3, 2, 1, 9, 8, 7,
    // Layer two, will wrap around and start at the first tile again
    3, 7, 3, 0, 4, 7, 2, 7, 4, 6,
    3, 2, 3, 0, 1, 2, 2, 9, 6, 1,
    3, 7, 3, 2, 1, 7, 7, 1, 4, 6,
    2, 1, 2, 0, 4, 7, 2, 7, 2, 7,
    3, 7, 1, 3, 4, 7, 6, 6, 4, 9,
    // More layers
    // ...
  ],
});

General

Re-using textures

Instead of defining texture wrapping per texture, this library allows you to re-use textures across sprites and tilemaps.

const texture = new THREE.TextureLoader().load("tileset.png");
const geo = new THREE.PlaneGeometry(1, 1);
const materialOptions = {
    side: THREE.FrontSide,
    precision: "highp",
    map: texture
};
const tilingOptions = {
  tileSize: { x: 16, y: 16 },
  tilesetSize: { x: 128, y: 128 }
}

// Sprite 1
const sprite1 = new THREE.Mesh(geo, new SpriteMeshBasicMaterial(materialOptions));
sprite1.tile({ ...tilingOptions, tile: 1 });
myScene.add(sprite1);

// Sprite 2
const sprite2 = new THREE.Mesh(geo, new SpriteMeshBasicMaterial(materialOptions));
sprite2.tile({ ...tilingOptions, tile: 5 });
myScene.add(sprite2);

// Sprite 3
const sprite3 = new THREE.Mesh(geo, new SpriteMeshBasicMaterial(materialOptions));
sprite3.tile({ ...tilingOptions, tile: 12 });
myScene.add(sprite3);

// Tlemap
const tilemap = new THREE.Mesh(geo, new TilemapMeshBasicMaterial(materialOptions));
tilemap.material.tile({
  ...tileOptions,
  repeat: { x: 10, y: 5 },
  tiles: [
    0, 0, 1, 5, 3, 9, 2, 5, 0, 0,
    0, 4, 4, 2, 2, 2, 1, 9, 0, 0,
    0, 1, 1, 5, 0, 9, 4, 3, 4, 0,
    0, 1, 0, 5, 3, 9, 2, 5, 0, 3,
    0, 7, 8, 4, 3, 2, 1, 9, 8, 7,
  ],
});
myScene.add(tilemap);

Documentation

Classes

| Class | Description | | ------ | ------ | | SpriteMaterial | Base material to render sprites: | | SpriteMeshBasicMaterial | THREE.MeshBasicMaterial extending SpriteMaterial. | | SpriteMeshLambertMaterial | THREE.MeshLambertMaterial extending SpriteMaterial. | | SpriteMeshPhongMaterial | THREE.MeshPhongMaterial extending SpriteMaterial. | | SpriteMeshPhysicalMaterial | THREE.MeshPhysicalMaterial extending SpriteMaterial. | | SpriteMeshStandardMaterial | THREE.MeshStandardMaterial extending SpriteMaterial. | | SpriteMeshToonMaterial | THREE.MeshToonMaterial extending SpriteMaterial. | | TilemapMaterial | Base material to render sprites: | | TilemapMeshBasicMaterial | THREE.MeshBasicMaterial extending TilemapMaterial. | | TilemapMeshLambertMaterial | THREE.MeshLambertMaterial extending TilemapMaterial. | | TilemapMeshPhongMaterial | THREE.MeshPhongMaterial extending TilemapMaterial. | | TilemapMeshPhysicalMaterial | THREE.MeshPhysicalMaterial extending TilemapMaterial. | | TilemapMeshStandardMaterial | THREE.MeshStandardMaterial extending TilemapMaterial. | | TilemapMeshToonMaterial | THREE.MeshToonMaterial extending TilemapMaterial. |

Interfaces

| Interface | Description | | ------ | ------ | | ISpriteTilingOptions | Options for SpriteMaterial.tile() | | ISpriteUniforms | Uniforms for SpriteMaterial | | ITilemapTilingOptions | Options for TilemapMaterial.tile() | | ITilemapUniforms | Uniforms for TilemapMaterial |