diff --git a/README.md b/README.md
index c7dc389..43578dc 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,9 @@ Three.js powered Minecraft skin viewer.
// Change camera FOV
skinViewer.fov = 70;
+ // Zoom out
+ skinViewer.zoom = 0.5;
+
// Control objects with your mouse!
let control = skinview3d.createOrbitControls(skinViewer);
control.enableRotate = true;
diff --git a/examples/index.html b/examples/index.html
index 56b15af..90efcae 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -118,6 +118,7 @@
+
@@ -367,6 +368,7 @@
document.getElementById("canvas_width").addEventListener("change", e => skinViewer.width = e.target.value);
document.getElementById("canvas_height").addEventListener("change", e => skinViewer.height = e.target.value);
document.getElementById("fov").addEventListener("change", e => skinViewer.fov = e.target.value);
+ document.getElementById("zoom").addEventListener("change", e => skinViewer.zoom = e.target.value);
document.getElementById("global_animation_speed").addEventListener("change", e => skinViewer.animations.speed = e.target.value);
document.getElementById("animation_pause_resume").addEventListener("click", () => skinViewer.animations.paused = !skinViewer.animations.paused);
document.getElementById("rotate_animation").addEventListener("change", e => {
@@ -466,6 +468,7 @@
skinViewer.width = document.getElementById("canvas_width").value;
skinViewer.height = document.getElementById("canvas_height").value;
skinViewer.fov = document.getElementById("fov").value;
+ skinViewer.zoom = document.getElementById("zoom").value;
skinViewer.animations.speed = document.getElementById("global_animation_speed").value;
if (document.getElementById("rotate_animation").checked) {
rotateAnimation = skinViewer.animations.add(skinview3d.RotatingAnimation);
diff --git a/src/viewer.ts b/src/viewer.ts
index f2d3c5a..79a8f86 100644
--- a/src/viewer.ts
+++ b/src/viewer.ts
@@ -63,6 +63,13 @@ export interface SkinViewerOptions {
* The distance between the object and the camera is automatically computed.
*/
fov?: number;
+
+ /**
+ * Zoom ratio of the player. Default is 0.9.
+ * 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 view.
+ */
+ zoom?: number;
}
export class SkinViewer {
@@ -82,6 +89,7 @@ export class SkinViewer {
private _disposed: boolean = false;
private _renderPaused: boolean = false;
+ private _zoom: number;
private animationID: number | null;
private onContextLost: (event: Event) => void;
@@ -104,7 +112,6 @@ export class SkinViewer {
this.scene = new Scene();
this.camera = new PerspectiveCamera();
- this.camera.position.z = 60;
this.renderer = new WebGLRenderer({
canvas: this.canvas,
@@ -140,6 +147,8 @@ export class SkinViewer {
if (options.panorama !== undefined) {
this.loadPanorama(options.panorama);
}
+ this.camera.position.z = 1;
+ this._zoom = options.zoom === undefined ? 0.9 : options.zoom;
this.fov = options.fov === undefined ? 50 : options.fov;
if (options.renderPaused === true) {
@@ -342,17 +351,35 @@ export class SkinViewer {
}
}
+ adjustCameraDistance(): void {
+ let distance = 4.5 + 16.5 / Math.tan(this.fov / 180 * Math.PI / 2) / this.zoom;
+
+ // limit distance between 10 ~ 256 (default min / max distance of OrbitControls)
+ if (distance < 10) {
+ distance = 10;
+ } else if (distance > 256) {
+ distance = 256;
+ }
+
+ this.camera.position.multiplyScalar(distance / this.camera.position.length());
+ this.camera.updateProjectionMatrix();
+ }
+
get fov(): number {
return this.camera.fov;
}
set fov(value: number) {
this.camera.fov = value;
- let distance = 4 + 20 / Math.tan(value / 180 * Math.PI / 2);
- if (distance < 10) {
- distance = 10;
- }
- this.camera.position.multiplyScalar(distance / this.camera.position.length());
- this.camera.updateProjectionMatrix();
+ this.adjustCameraDistance();
+ }
+
+ get zoom(): number {
+ return this._zoom;
+ }
+
+ set zoom(value: number) {
+ this._zoom = value;
+ this.adjustCameraDistance();
}
}