skin3d
Version:
A fast, customizable Minecraft skin viewer powered by Three.js. Easily render and preview Minecraft skins in 3D for your projects.
361 lines (360 loc) • 12.9 kB
TypeScript
import { type ModelType, type RemoteImage, type TextureSource } from "skinview-utils";
import { Color, type ColorRepresentation, PointLight, Group, PerspectiveCamera, Scene, Texture, WebGLRenderer, AmbientLight, type Mapping } from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js";
import { PlayerAnimation } from "./animation.js";
import { type BackEquipment, PlayerObject } from "./model.js";
import { NameTagObject } from "./nametag.js";
export interface LoadOptions {
/**
* Whether to make the object visible after the texture is loaded.
*
* @defaultValue `true`
*/
makeVisible?: boolean;
}
export interface SkinLoadOptions extends LoadOptions {
/**
* The model of the player (`"default"` for normal arms, and `"slim"` for slim arms).
*
* When set to `"auto-detect"`, the model will be inferred from the skin texture.
*
* @defaultValue `"auto-detect"`
*/
model?: ModelType | "auto-detect";
/**
* Whether to display the ears drawn on the skin texture.
*
* - `true` - Display the ears drawn on the skin texture.
* - `"load-only"` - Loads the ear texture, but do not make them visible.
* You can make them visible later by setting `PlayerObject.ears.visible` to `true`.
* - `false` - Do not load or show the ears.
*
* @defaultValue `false`
*/
ears?: boolean | "load-only";
}
export interface CapeLoadOptions extends LoadOptions {
/**
* The equipment (`"cape"` or `"elytra"`) to show when the cape texture is loaded.
*
* If `makeVisible` is set to false, this option will have no effect.
*
* @defaultValue `"cape"`
*/
backEquipment?: BackEquipment;
}
export interface EarsLoadOptions extends LoadOptions {
/**
* The type of the provided ear texture.
*
* - `"standalone"` means the provided texture is a 14x7 image that only contains the ears.
* - `"skin"` means the provided texture is a skin texture with ears, and we will use its ear part.
*
* @defaultValue `"standalone"`
*/
textureType?: "standalone" | "skin";
}
export interface ViewOptions {
/**
* The canvas where the renderer draws its output.
*
* @defaultValue If unspecified, a new canvas element will be created.
*/
canvas?: HTMLCanvasElement;
/**
* The CSS width of the canvas.
*/
width?: number;
/**
* The CSS height of the canvas.
*/
height?: number;
/**
* The pixel ratio of the canvas.
*
* When set to `"match-device"`, the current device pixel ratio will be used,
* and it will be automatically updated when the device pixel ratio changes.
*
* @defaultValue `"match-device"`
*/
pixelRatio?: number | "match-device";
/**
* The skin texture of the player.
*
* @defaultValue If unspecified, the skin will be invisible.
*/
skin?: RemoteImage | TextureSource;
/**
* The model of the player (`"default"` for normal arms, and `"slim"` for slim arms).
*
* When set to `"auto-detect"`, the model will be inferred from the skin texture.
*
* If the `skin` option is not specified, this option will have no effect.
*
* @defaultValue `"auto-detect"`
*/
model?: ModelType | "auto-detect";
/**
* The cape texture of the player.
*
* @defaultValue If unspecified, the cape will be invisible.
*/
cape?: RemoteImage | TextureSource;
/**
* The ear texture of the player.
*
* When set to `"current-skin"`, the ears drawn on the current skin texture (as is specified in the `skin` option) will be shown.
*
* To use an individual ear texture, you have to specify the `textureType` and the `source` option.
* `source` is the texture to use, and `textureType` can be either `"standalone"` or `"skin"`:
* - `"standalone"` means the provided texture is a 14x7 image that only contains the ears.
* - `"skin"` means the provided texture is a skin texture with ears, and we will show its ear part.
*
* @defaultValue If unspecified, the ears will be invisible.
*/
ears?: "current-skin" | {
textureType: "standalone" | "skin";
source: RemoteImage | TextureSource;
};
/**
* Whether to preserve the buffers until manually cleared or overwritten.
*
* @defaultValue `false`
*/
preserveDrawingBuffer?: boolean;
/**
* Whether to pause the rendering and animation loop.
*
* @defaultValue `false`
*/
renderPaused?: boolean;
/**
* The background of the scene.
*
* @defaultValue transparent
*/
background?: ColorRepresentation | Texture;
/**
* The panorama background to use.
*
* This option overrides the `background` option.
*/
panorama?: RemoteImage | TextureSource;
/**
* Camera vertical field of view, in degrees.
*
* The distance between the player and the camera will be automatically computed from `fov` and `zoom`.
*
* @defaultValue `50`
*
* @see {@link View.adjustCameraDistance}
*/
fov?: number;
/**
* Zoom ratio of the player.
*
* This value affects the distance between the object and the camera.
* When set to `1.0`, the top edge of the player's head coincides with the edge of the canvas.
*
* The distance between the player and the camera will be automatically computed from `fov` and `zoom`.
*
* @defaultValue `0.9`
*
* @see {@link View.adjustCameraDistance}
*/
zoom?: number;
/**
* Whether to enable mouse control function.
*
* This function is implemented using {@link OrbitControls}.
* By default, zooming and rotating are enabled, and panning is disabled.
*
* @defaultValue `true`
*/
enableControls?: boolean;
/**
* The animation to play on the player.
*
* @defaultValue If unspecified, no animation will be played.
*/
animation?: PlayerAnimation;
/**
* The name tag to display above the player.
*
* @defaultValue If unspecified, no name tag will be displayed.
* @see {@link View.nameTag}
*/
nameTag?: NameTagObject | string;
/**
* Allow rotation around the X and Y axis (Vertical and Horizontal).
* @defaultValue true
*/
enableRotation?: boolean;
/**
* Allow rotation around the X axis (vertical).
* @defaultValue true
*/
allowRotateX?: boolean;
/**
* Allow rotation around the Y axis (horizontal).
* @defaultValue true
*/
allowRotateY?: boolean;
/**
* Allow zooming.
* @defaultValue true
*/
allowZoom?: boolean;
}
/**
* The View renders the player on a canvas.
*/
export declare class View {
/** The canvas where the renderer draws its output. */
readonly canvas: HTMLCanvasElement;
readonly scene: Scene;
readonly camera: PerspectiveCamera;
readonly renderer: WebGLRenderer;
/** Mouse control component (OrbitControls). */
readonly controls: OrbitControls;
/** The player object (skin, cape, elytra, ears). */
readonly playerObject: PlayerObject;
/** Group that wraps the player object for centering. */
readonly playerWrapper: Group;
readonly globalLight: AmbientLight;
readonly cameraLight: PointLight;
readonly composer: EffectComposer;
readonly renderPass: RenderPass;
readonly fxaaPass: ShaderPass;
readonly skinCanvas: HTMLCanvasElement;
readonly capeCanvas: HTMLCanvasElement;
readonly earsCanvas: HTMLCanvasElement;
private skinTexture;
private capeTexture;
private earsTexture;
private backgroundTexture;
private _disposed;
private _renderPaused;
private _zoom;
private isUserRotating;
/**
* Whether to rotate the player along the y axis.
*
* @defaultValue `false`
*/
autoRotate: boolean;
/**
* The angular velocity of the player, in rad/s.
*
* @defaultValue `1.0`
* @see {@link autoRotate}
*/
autoRotateSpeed: number;
private _animation;
private clock;
private animationID;
private onContextLost;
private onContextRestored;
private _pixelRatio;
private devicePixelRatioQuery;
private onDevicePixelRatioChange;
private _nameTag;
constructor(options?: ViewOptions);
/** Update the size and pixel ratio of the composer and FXAA pass. */
private updateComposerSize;
/** Create or update the skin texture from the skin canvas. */
private recreateSkinTexture;
/** Create or update the cape texture from the cape canvas. */
private recreateCapeTexture;
/** Create or update the ears texture from the ears canvas. */
private recreateEarsTexture;
/**
* Load a skin texture.
* @param source
* - The skin image or canvas.
* @param options - Loading options.
*/
loadSkin(empty: null): void;
loadSkin<S extends TextureSource | RemoteImage>(source: S, options?: SkinLoadOptions): S extends TextureSource ? void : Promise<void>;
/** Hide and dispose the current skin texture. */
resetSkin(): void;
/**
* Load a cape texture.
* @param source - The cape image or canvas.
* @param options - Loading options.
*/
loadCape(empty: null): void;
loadCape<S extends TextureSource | RemoteImage>(source: S, options?: CapeLoadOptions): S extends TextureSource ? void : Promise<void>;
/** Hide and dispose the current cape texture. */
resetCape(): void;
/**
* Load an ear texture.
* @param source - The ear image or canvas.
* @param options - Loading options.
*/
loadEars(empty: null): void;
loadEars<S extends TextureSource | RemoteImage>(source: S, options?: EarsLoadOptions): S extends TextureSource ? void : Promise<void>;
/** Hide and dispose the current ears texture. */
resetEars(): void;
/** Load a panorama background. */
loadPanorama<S extends TextureSource | RemoteImage>(source: S): S extends TextureSource ? void : Promise<void>;
/**
* Load a background texture.
* @param source - The background image or canvas.
* @param mapping - Optional texture mapping.
*/
loadBackground<S extends TextureSource | RemoteImage>(source: S, mapping?: Mapping): S extends TextureSource ? void : Promise<void>;
/** Animation and rendering loop. */
private draw;
/** Render the scene to the canvas (does not advance animation). */
render(): void;
/** Set the viewer size in pixels. */
setSize(width: number, height: number): void;
/** Dispose all resources and event listeners. */
dispose(): void;
get disposed(): boolean;
/** Whether rendering and animations are paused. */
get renderPaused(): boolean;
set renderPaused(value: boolean);
get width(): number;
set width(newWidth: number);
get height(): number;
set height(newHeight: number);
get background(): null | Color | Texture;
set background(value: null | ColorRepresentation | Texture);
/** Adjust camera distance based on FOV and zoom. */
adjustCameraDistance(): void;
/** Reset camera to default pose and distance. */
resetCameraPose(): void;
get fov(): number;
set fov(value: number);
get zoom(): number;
set zoom(value: number);
get pixelRatio(): number | "match-device";
set pixelRatio(newValue: number | "match-device");
/**
* The animation that is currently playing, or `null` if no animation is playing.
* Setting this property to a different value will change the current animation.
* The player's pose and the progress of the new animation will be reset before playing.
* Setting this property to `null` will stop the current animation and reset the player's pose.
*/
get animation(): PlayerAnimation | null;
set animation(animation: PlayerAnimation | null);
/**
* The name tag to display above the player, or `null` if there is none.
* When setting this property to a `string` value, a {@link NameTagObject}
* will be automatically created with default options.
*
* @example
* view.nameTag = "Norch";
* view.nameTag = new NameTagObject("hello", { textStyle: "yellow" });
* view.nameTag = null;
*/
get nameTag(): NameTagObject | null;
set nameTag(newVal: NameTagObject | string | null);
/** Reset the model's rotation to default. */
resetModelRotation(): void;
}