skinview3d-node 3.4.2-node.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './process.js';
3
+ export * from './load-image.js';
@@ -0,0 +1,7 @@
1
+ import { Canvas, Image } from 'skia-canvas';
2
+ import { DataTexture } from 'three';
3
+ export type RemoteImage = string | Buffer | {
4
+ src: string;
5
+ };
6
+ export declare function loadImage(source: RemoteImage): Promise<Image>;
7
+ export declare function canvas2DataTexture(canvas: Canvas): DataTexture;
@@ -0,0 +1,7 @@
1
+ import { TextureCanvas, TextureSource, ModelType } from './types.js';
2
+ export declare function loadSkinToCanvas(canvas: TextureCanvas, image: TextureSource): void;
3
+ export declare function loadCapeToCanvas(canvas: TextureCanvas, image: TextureSource): void;
4
+ export declare function inferModelType(canvas: TextureCanvas): ModelType;
5
+ export declare function loadEarsToCanvas(canvas: TextureCanvas, image: TextureSource): void;
6
+ export declare function loadEarsToCanvasFromSkin(canvas: TextureCanvas, image: TextureSource): void;
7
+ export declare function loadArmorToCanvas(canvas: TextureCanvas, layer1Image: TextureSource | null | undefined, layer2Image: TextureSource | null | undefined): void;
@@ -0,0 +1,5 @@
1
+ import { Canvas, Image } from 'skia-canvas';
2
+ export type TextureCanvas = Canvas;
3
+ export type TextureSource = TextureCanvas | Image;
4
+ export type ModelType = 'default' | 'slim';
5
+ export declare function isTextureSource(value: unknown): value is TextureSource;
@@ -0,0 +1,328 @@
1
+ import { type ModelType, type RemoteImage, type TextureSource } from './utils/index.js';
2
+ import { Color, type ColorRepresentation, PointLight, Group, PerspectiveCamera, Scene, Texture, WebGLRenderer, AmbientLight, type Mapping } from 'three';
3
+ import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
4
+ import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
5
+ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
6
+ import { PlayerAnimation } from './animation.js';
7
+ import { type BackEquipment, PlayerObject } from './model.js';
8
+ import { NameTagObject } from './nametag.js';
9
+ import { Canvas, ExportFormat, ExportOptions } from 'skia-canvas';
10
+ import gl from 'gl';
11
+ export interface LoadOptions {
12
+ /**
13
+ * Whether to make the object visible after the texture is loaded.
14
+ *
15
+ * @defaultValue `true`
16
+ */
17
+ makeVisible?: boolean;
18
+ }
19
+ export interface SkinLoadOptions extends LoadOptions {
20
+ /**
21
+ * The model of the player (`"default"` for normal arms, and `"slim"` for slim arms).
22
+ *
23
+ * When set to `"auto-detect"`, the model will be inferred from the skin texture.
24
+ *
25
+ * @defaultValue `"auto-detect"`
26
+ */
27
+ model?: ModelType | 'auto-detect';
28
+ /**
29
+ * Whether to display the ears drawn on the skin texture.
30
+ *
31
+ * - `true` - Display the ears drawn on the skin texture.
32
+ * - `"load-only"` - Loads the ear texture, but do not make them visible.
33
+ * You can make them visible later by setting `PlayerObject.ears.visible` to `true`.
34
+ * - `false` - Do not load or show the ears.
35
+ *
36
+ * @defaultValue `false`
37
+ */
38
+ ears?: boolean | 'load-only';
39
+ }
40
+ export interface CapeLoadOptions extends LoadOptions {
41
+ /**
42
+ * The equipment (`"cape"` or `"elytra"`) to show when the cape texture is loaded.
43
+ *
44
+ * If `makeVisible` is set to false, this option will have no effect.
45
+ *
46
+ * @defaultValue `"cape"`
47
+ */
48
+ backEquipment?: BackEquipment;
49
+ }
50
+ export interface EarsLoadOptions extends LoadOptions {
51
+ /**
52
+ * The type of the provided ear texture.
53
+ *
54
+ * - `"standalone"` means the provided texture is a 14x7 image that only contains the ears.
55
+ * - `"skin"` means the provided texture is a skin texture with ears, and we will use its ear part.
56
+ *
57
+ * @defaultValue `"standalone"`
58
+ */
59
+ textureType?: 'standalone' | 'skin';
60
+ }
61
+ export interface SkinViewerOptions {
62
+ /**
63
+ * The canvas where the renderer draws its output.
64
+ *
65
+ * @defaultValue If unspecified, a new canvas element will be created.
66
+ */
67
+ canvas?: Canvas;
68
+ ctx?: ReturnType<typeof gl>;
69
+ /**
70
+ * The CSS width of the canvas.
71
+ */
72
+ width?: number;
73
+ /**
74
+ * The CSS height of the canvas.
75
+ */
76
+ height?: number;
77
+ /**
78
+ * The pixel ratio of the canvas.
79
+ *
80
+ * When set to `"match-device"`, the current device pixel ratio will be used,
81
+ * and it will be automatically updated when the device pixel ratio changes.
82
+ *
83
+ * @defaultValue `"match-device"`
84
+ */
85
+ pixelRatio?: number;
86
+ /**
87
+ * The skin texture of the player.
88
+ *
89
+ * @defaultValue If unspecified, the skin will be invisible.
90
+ */
91
+ skin?: RemoteImage | TextureSource;
92
+ /**
93
+ * The model of the player (`"default"` for normal arms, and `"slim"` for slim arms).
94
+ *
95
+ * When set to `"auto-detect"`, the model will be inferred from the skin texture.
96
+ *
97
+ * If the `skin` option is not specified, this option will have no effect.
98
+ *
99
+ * @defaultValue `"auto-detect"`
100
+ */
101
+ model?: ModelType | 'auto-detect';
102
+ /**
103
+ * The cape texture of the player.
104
+ *
105
+ * @defaultValue If unspecified, the cape will be invisible.
106
+ */
107
+ cape?: RemoteImage | TextureSource;
108
+ capeLoadOptions?: CapeLoadOptions;
109
+ /**
110
+ * The ear texture of the player.
111
+ *
112
+ * When set to `"current-skin"`, the ears drawn on the current skin texture (as is specified in the `skin` option) will be shown.
113
+ *
114
+ * To use an individual ear texture, you have to specify the `textureType` and the `source` option.
115
+ * `source` is the texture to use, and `textureType` can be either `"standalone"` or `"skin"`:
116
+ * - `"standalone"` means the provided texture is a 14x7 image that only contains the ears.
117
+ * - `"skin"` means the provided texture is a skin texture with ears, and we will show its ear part.
118
+ *
119
+ * @defaultValue If unspecified, the ears will be invisible.
120
+ */
121
+ ears?: 'current-skin' | {
122
+ textureType: 'standalone' | 'skin';
123
+ source: RemoteImage | TextureSource;
124
+ };
125
+ /**
126
+ * Whether to preserve the buffers until manually cleared or overwritten.
127
+ *
128
+ * @defaultValue `false`
129
+ */
130
+ preserveDrawingBuffer?: boolean;
131
+ /**
132
+ * Whether to pause the rendering and animation loop.
133
+ *
134
+ * @defaultValue `false`
135
+ */
136
+ /**
137
+ * The background of the scene.
138
+ *
139
+ * @defaultValue transparent
140
+ */
141
+ background?: ColorRepresentation | Texture;
142
+ /**
143
+ * The panorama background to use.
144
+ *
145
+ * This option overrides the `background` option.
146
+ */
147
+ panorama?: RemoteImage | TextureSource;
148
+ /**
149
+ * Camera vertical field of view, in degrees.
150
+ *
151
+ * The distance between the player and the camera will be automatically computed from `fov` and `zoom`.
152
+ *
153
+ * @defaultValue `50`
154
+ *
155
+ * @see {@link SkinViewer.adjustCameraDistance}
156
+ */
157
+ fov?: number;
158
+ /**
159
+ * Zoom ratio of the player.
160
+ *
161
+ * This value affects the distance between the object and the camera.
162
+ * When set to `1.0`, the top edge of the player's head coincides with the edge of the canvas.
163
+ *
164
+ * The distance between the player and the camera will be automatically computed from `fov` and `zoom`.
165
+ *
166
+ * @defaultValue `0.9`
167
+ *
168
+ * @see {@link SkinViewer.adjustCameraDistance}
169
+ */
170
+ zoom?: number;
171
+ /**
172
+ * Whether to enable mouse control function.
173
+ *
174
+ * This function is implemented using {@link OrbitControls}.
175
+ * By default, zooming and rotating are enabled, and panning is disabled.
176
+ *
177
+ * @defaultValue `true`
178
+ */
179
+ enableControls?: boolean;
180
+ /**
181
+ * The animation to play on the player.
182
+ *
183
+ * @defaultValue If unspecified, no animation will be played.
184
+ */
185
+ animation?: PlayerAnimation;
186
+ /**
187
+ * The name tag to display above the player.
188
+ *
189
+ * @defaultValue If unspecified, no name tag will be displayed.
190
+ * @see {@link SkinViewer.nameTag}
191
+ */
192
+ nameTag?: NameTagObject | string;
193
+ }
194
+ /**
195
+ * The SkinViewer renders the player on a canvas.
196
+ */
197
+ export declare class SkinViewer {
198
+ /**
199
+ * The canvas where the renderer draws its output.
200
+ */
201
+ readonly canvas: Canvas;
202
+ readonly ctx: ReturnType<typeof gl>;
203
+ readonly scene: Scene;
204
+ readonly camera: PerspectiveCamera;
205
+ readonly renderer: WebGLRenderer;
206
+ /**
207
+ * The OrbitControls component which is used to implement the mouse control function.
208
+ *
209
+ * @see {@link https://threejs.org/docs/#examples/en/controls/OrbitControls | OrbitControls - three.js docs}
210
+ */
211
+ /**
212
+ * The player object.
213
+ */
214
+ readonly playerObject: PlayerObject;
215
+ /**
216
+ * A group that wraps the player object.
217
+ * It is used to center the player in the world.
218
+ */
219
+ readonly playerWrapper: Group;
220
+ readonly globalLight: AmbientLight;
221
+ readonly cameraLight: PointLight;
222
+ readonly composer: EffectComposer;
223
+ readonly renderPass: RenderPass;
224
+ readonly fxaaPass: ShaderPass;
225
+ readonly skinCanvas: Canvas;
226
+ readonly capeCanvas: Canvas;
227
+ readonly earsCanvas: Canvas;
228
+ private skinTexture;
229
+ private capeTexture;
230
+ private earsTexture;
231
+ private backgroundTexture;
232
+ private _disposed;
233
+ private _zoom;
234
+ /**
235
+ * Whether to rotate the player along the y axis.
236
+ *
237
+ * @defaultValue `false`
238
+ */
239
+ autoRotate: boolean;
240
+ /**
241
+ * The angular velocity of the player, in rad/s.
242
+ *
243
+ * @defaultValue `1.0`
244
+ * @see {@link autoRotate}
245
+ */
246
+ autoRotateSpeed: number;
247
+ private _animation;
248
+ private _pixelRatio;
249
+ private _nameTag;
250
+ private nameTagYOffset;
251
+ private _loadPromiseArr;
252
+ /** 读取各部位 */
253
+ readonly ready: Promise<any>;
254
+ constructor(options?: SkinViewerOptions);
255
+ private updateComposerSize;
256
+ private recreateSkinTexture;
257
+ private recreateCapeTexture;
258
+ private recreateEarsTexture;
259
+ loadSkin(empty: null): void;
260
+ loadSkin<S extends TextureSource | RemoteImage>(source: S, options?: SkinLoadOptions): S extends TextureSource ? void : Promise<void>;
261
+ resetSkin(): void;
262
+ loadCape(empty: null): void;
263
+ loadCape<S extends TextureSource | RemoteImage>(source: S, options?: CapeLoadOptions): S extends TextureSource ? void : Promise<void>;
264
+ resetCape(): void;
265
+ loadEars(empty: null): void;
266
+ loadEars<S extends TextureSource | RemoteImage>(source: S, options?: EarsLoadOptions): S extends TextureSource ? void : Promise<void>;
267
+ resetEars(): void;
268
+ loadPanorama<S extends TextureSource | RemoteImage>(source: S): S extends TextureSource ? void : Promise<void>;
269
+ loadBackground<S extends TextureSource | RemoteImage>(source: S, mapping?: Mapping): S extends TextureSource ? void : Promise<void>;
270
+ toRGBA(): Uint8Array;
271
+ toBuffer(format?: ExportFormat, options?: ExportOptions): Buffer<ArrayBufferLike>;
272
+ /**
273
+ * Renders the scene to the canvas.
274
+ * This method does not change the animation progress.
275
+ */
276
+ render(): void;
277
+ renderAnimationFrame(progress: number, binary?: false): (() => Uint8Array);
278
+ renderAnimationFrame(progress: number, binary: true): (() => Buffer);
279
+ renderAnimationLoop(frames?: number, binary?: false): (() => Uint8Array)[];
280
+ renderAnimationLoop(frames: number, binary: true): (() => Buffer)[];
281
+ setSize(width: number, height: number): void;
282
+ dispose(): void;
283
+ get disposed(): boolean;
284
+ /**
285
+ * Whether rendering and animations are paused.
286
+ * Setting this property to true will stop both rendering and animation loops.
287
+ * Setting it back to false will resume them.
288
+ */
289
+ get width(): number;
290
+ set width(newWidth: number);
291
+ get height(): number;
292
+ set height(newHeight: number);
293
+ get background(): null | Color | Texture;
294
+ set background(value: null | ColorRepresentation | Texture);
295
+ adjustCameraDistance(): void;
296
+ resetCameraPose(): void;
297
+ get fov(): number;
298
+ set fov(value: number);
299
+ get zoom(): number;
300
+ set zoom(value: number);
301
+ get pixelRatio(): number;
302
+ set pixelRatio(newValue: number);
303
+ /**
304
+ * The animation that is current playing, or `null` if no animation is playing.
305
+ *
306
+ * Setting this property to a different value will change the current animation.
307
+ * The player's pose and the progress of the new animation will be reset before playing.
308
+ *
309
+ * Setting this property to `null` will stop the current animation and reset the player's pose.
310
+ */
311
+ get animation(): PlayerAnimation | null;
312
+ set animation(animation: PlayerAnimation | null);
313
+ /**
314
+ * The name tag to display above the player, or `null` if there is none.
315
+ *
316
+ * When setting this property to a `string` value, a {@link NameTagObject}
317
+ * will be automatically created with default options.
318
+ *
319
+ * @example
320
+ * ```
321
+ * skinViewer.nameTag = "hello";
322
+ * skinViewer.nameTag = new NameTagObject("hello", { textStyle: "yellow" });
323
+ * skinViewer.nameTag = null;
324
+ * ```
325
+ */
326
+ get nameTag(): NameTagObject | null;
327
+ set nameTag(newVal: NameTagObject | string | null);
328
+ }
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "skinview3d-node",
3
+ "version": "3.4.2-node.1",
4
+ "description": "Three.js powered Minecraft skin viewer for Node.js",
5
+ "main": "libs/skinview3d.cjs",
6
+ "type": "module",
7
+ "exports": {
8
+ "import": "./libs/skinview3d.mjs",
9
+ "require": "./libs/skinview3d.cjs",
10
+ "types": "./libs/skinview3d.d.ts"
11
+ },
12
+ "scripts": {
13
+ "clean": "rimraf libs bundles",
14
+ "build:bundles": "rollup -c --configPlugin=swc3",
15
+ "build:docs": "typedoc src/viewer.ts",
16
+ "build:preview": "vite build",
17
+ "build": "npm-run-all --parallel build:bundles build:preview",
18
+ "format": "prettier src examples eslint.config.js --write",
19
+ "test:lint": "eslint src examples eslint.config.js",
20
+ "test": "npm run test:lint",
21
+ "dev:watch:modules": "tsc -w --preserveWatchOutput --declaration --sourceMap --outDir libs -p .",
22
+ "dev:watch:bundles": "rollup -w --no-watch.clearScreen -c --configPlugin=swc3",
23
+ "dev": "vite",
24
+ "preview": "vite preview",
25
+ "prepublishOnly": "npm run clean && npm run build"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/ltxhhz/skinview3d-node.git"
30
+ },
31
+ "author": "ltxhhz <ltxhhz@gmail.com> (https://github.com/ltxhhz)",
32
+ "contributors": [
33
+ "Sean Boult <sean@boult.me> (https://github.com/Hacksore)",
34
+ "Pig Fang <g-plane@hotmail.com> (https://github.com/g-plane)",
35
+ "printempw <h@prinzeugen.net> (https://github.com/printempw)",
36
+ "Kent Rasmussen <hyprkookeez@gmail.com> (https://github.com/earthiverse)"
37
+ ],
38
+ "license": "MIT",
39
+ "bugs": {
40
+ "url": "https://github.com/ltxhhz/skinview3d-node/issues"
41
+ },
42
+ "homepage": "https://github.com/ltxhhz/skinview3d-node",
43
+ "files": [
44
+ "libs",
45
+ "bundles",
46
+ "assets"
47
+ ],
48
+ "dependencies": {
49
+ "@types/three": "^0.156.0",
50
+ "pngjs": "^7.0.0",
51
+ "skia-canvas": "^3.0.8",
52
+ "skinview-utils": "^0.7.1",
53
+ "three": "^0.156.0"
54
+ },
55
+ "devDependencies": {
56
+ "@rollup/plugin-commonjs": "^21.1.0",
57
+ "@rollup/plugin-node-resolve": "^15.0.2",
58
+ "@rollup/plugin-typescript": "^8.5.0",
59
+ "@swc/core": "^1.3.53",
60
+ "@typescript-eslint/eslint-plugin": "^8.31.1",
61
+ "@typescript-eslint/parser": "^8.31.1",
62
+ "@yushijinhun/three-minifier-rollup": "^0.4.0",
63
+ "eslint": "^9.26.0",
64
+ "eslint-plugin-tsdoc": "^0.2.17",
65
+ "gl": "^8.1.6",
66
+ "jszip": "^3.10.1",
67
+ "local-web-server": "^5.2.1",
68
+ "npm-run-all": "^4.1.5",
69
+ "prettier": "^3.0.3",
70
+ "rimraf": "^3.0.2",
71
+ "rollup": "^3.20.7",
72
+ "rollup-plugin-swc3": "^0.8.1",
73
+ "tslib": "^2.8.1",
74
+ "typedoc": "^0.25.7",
75
+ "typescript": "^5.0.4",
76
+ "vite": "^5.4.7"
77
+ }
78
+ }