Rename repo to 'skinview3d'

This commit is contained in:
yushijinhun 2017-10-01 15:47:40 +08:00
parent 1df1bc33fa
commit dfe194abcb
No known key found for this signature in database
GPG Key ID: 5BC167F73EA558E4
4 changed files with 76 additions and 129 deletions

View File

@ -1,7 +1,5 @@
# skinpreview3d.js # skinview3d
A Three.js powered Minecraft skin viewer. Three.js powered Minecraft skin viewer.
The code was originally created by [Kent Rasmussen](https://github.com/earthiverse). You can find out more about his project [here](https://github.com/earthiverse/3D-Minecraft-Skin-Viewer).
# Features # Features
* 1.8 Skins * 1.8 Skins
@ -9,32 +7,6 @@ The code was originally created by [Kent Rasmussen](https://github.com/earthiver
* Capes * Capes
* Slim arms * Slim arms
# Dependencies
* [Three.js](https://github.com/mrdoob/three.js/)
* [jQuery](https://jquery.com/) (Optional)
# Usage
HTML
```html
<div id="skin_container"></div>
```
JS
```js
$(() => {
$("#skin_container").skinPreview3d({
skinUrl: "img/hatsune_miku.png",
capeUrl: "img/mojang_cape.png",
slim: true,
width: 600,
height: 600
});
});
```
# Demos
* [Native javascript](https://hacksore.github.io/skinpreview3d.js/demo_purejs.html)
* [jQuery](https://hacksore.github.io/skinpreview3d.js/demo_jquery.html)
# License # License
* `/img/mojang_cape.png` Copyright Mojang AB. [Link](https://minecraft.gamepedia.com/File:MojangCape2016.png) * `/img/mojang_cape.png` Copyright Mojang AB. [Link](https://minecraft.gamepedia.com/File:MojangCape2016.png)
* `/img/hatsune_miku.png` Copyright xilefian. [Link](http://www.minecraftforum.net/forums/mapping-and-modding/skins/2646900-hatsune-miku-skin-1-9-transparency-layers) * `/img/hatsune_miku.png` Copyright xilefian. [Link](http://www.minecraftforum.net/forums/mapping-and-modding/skins/2646900-hatsune-miku-skin-1-9-transparency-layers)

View File

@ -2,23 +2,23 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>skinpreview3d.js example using pure javascript</title> <title>skinview3d example</title>
</head> </head>
<body> <body>
<div id="skin_container"></div> <div id="skin_container"></div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script type="text/javascript" src="js/skinpreview3d.js"></script> <script type="text/javascript" src="js/skinview3d.js"></script>
<script> <script>
let skinViewer = new skinpreview3d.SkinViewer({ let skinViewer = new skinview3d.SkinViewer({
domElement: document.getElementById("skin_container"), domElement: document.getElementById("skin_container"),
slim: true, slim: true,
width: 600, width: 600,
height: 600, height: 600,
skinUrl: "img/hatsune_miku.png", skinUrl: "img/hatsune_miku.png",
capeUrl: "img/mojang_cape.png", capeUrl: "img/mojang_cape.png",
animation: skinpreview3d.WalkAnimation animation: skinview3d.WalkAnimation
}); });
// change the skin and cape // change the skin and cape
@ -30,7 +30,7 @@
// skinViewer.height = 400; // skinViewer.height = 400;
// this enables the mouse control feature // this enables the mouse control feature
let control = new skinpreview3d.SkinControl(skinViewer); let control = new skinview3d.SkinControl(skinViewer);
// this makes the animation paused // this makes the animation paused
// skinViewer.animationPaused = true; // skinViewer.animationPaused = true;

View File

@ -1,28 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>skinpreview3d.js example using jquery</title>
</head>
<body>
<div id="skin_container"></div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script type="text/javascript" src="js/skinpreview3d.js"></script>
<script>
$(() => {
$("#skin_container").skinPreview3d({
skinUrl: "img/hatsune_miku.png",
capeUrl: "img/mojang_cape.png",
slim: true,
// disableControl: true, // This disables the mouse control feature
width: 600,
height: 600,
animation: skinpreview3d.WalkAnimation
});
});
</script>
</body>
</html>

View File

@ -1,12 +1,28 @@
/* /**
* skinpreview3d.js * skinview3d <https://github.com/to2mbn/skinview3d>
* https://github.com/Hacksore/skinpreview3d.js *
* Copyright (C) 2017 the original author or authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
let skinview3d = new function(){
'use strict'; /**
* @author yushijinhun <https://github.com/yushijinhun>
// namespace skinpreview3d * @author Hacksore <https://github.com/Hacksore>
let skinpreview3d = new function(){ * @author Kent Rasmussen <https://github.com/earthiverse>
*/
"use strict";
let copyImage = (context, sX, sY, w, h, dX, dY, flipHorizontal) => { let copyImage = (context, sX, sY, w, h, dX, dY, flipHorizontal) => {
let imgData = context.getImageData(sX, sY, w, h); let imgData = context.getImageData(sX, sY, w, h);
@ -368,11 +384,11 @@ let skinpreview3d = new function(){
this.slim = slim; this.slim = slim;
this.skin = new skinpreview3d.SkinObject(slim, layer1Material, layer2Material); this.skin = new skinview3d.SkinObject(slim, layer1Material, layer2Material);
this.skin.visible = false; this.skin.visible = false;
this.add(this.skin); this.add(this.skin);
this.cape = new skinpreview3d.CapeObject(capeMaterial); this.cape = new skinview3d.CapeObject(capeMaterial);
this.cape.position.z = -2; this.cape.position.z = -2;
this.cape.position.y = -4; this.cape.position.y = -4;
this.cape.rotation.x = 25*Math.PI/180; this.cape.rotation.x = 25*Math.PI/180;
@ -405,13 +421,13 @@ let skinpreview3d = new function(){
// texture // texture
this.skinImg = new Image(); this.skinImg = new Image();
this.skinCanvas = document.createElement('canvas'); this.skinCanvas = document.createElement("canvas");
this.skinTexture = new THREE.Texture(this.skinCanvas); this.skinTexture = new THREE.Texture(this.skinCanvas);
this.skinTexture.magFilter = THREE.NearestFilter; this.skinTexture.magFilter = THREE.NearestFilter;
this.skinTexture.minFilter = THREE.NearestMipMapNearestFilter; this.skinTexture.minFilter = THREE.NearestMipMapNearestFilter;
this.capeImg = new Image(); this.capeImg = new Image();
this.capeCanvas = document.createElement('canvas'); this.capeCanvas = document.createElement("canvas");
this.capeTexture = new THREE.Texture(this.capeCanvas); this.capeTexture = new THREE.Texture(this.capeCanvas);
this.capeTexture.magFilter = THREE.NearestFilter; this.capeTexture.magFilter = THREE.NearestFilter;
this.capeTexture.minFilter = THREE.NearestMipMapNearestFilter; this.capeTexture.minFilter = THREE.NearestMipMapNearestFilter;
@ -429,27 +445,27 @@ let skinpreview3d = new function(){
this.renderer = new THREE.WebGLRenderer({angleRot: true, alpha: true, antialias: false}); this.renderer = new THREE.WebGLRenderer({angleRot: true, alpha: true, antialias: false});
this.renderer.setSize(300, 300); // default size this.renderer.setSize(300, 300); // default size
this.renderer.context.getShaderInfoLog = () => ''; // shut firefox up this.renderer.context.getShaderInfoLog = () => ""; // shut firefox up
this.domElement.appendChild(this.renderer.domElement); this.domElement.appendChild(this.renderer.domElement);
this.playerObject = new skinpreview3d.PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial); this.playerObject = new skinview3d.PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial);
this.scene.add(this.playerObject); this.scene.add(this.playerObject);
// texture loading // texture loading
this.skinImg.crossOrigin = ''; this.skinImg.crossOrigin = "";
this.skinImg.onerror = () => console.log('Failed loading ' + this.skinImg.src); this.skinImg.onerror = () => console.log("Failed loading " + this.skinImg.src);
this.skinImg.onload = () => { this.skinImg.onload = () => {
let isOldFormat = false; let isOldFormat = false;
if (this.skinImg.width !== this.skinImg.height) { if (this.skinImg.width !== this.skinImg.height) {
if (this.skinImg.width === 2*this.skinImg.height) { if (this.skinImg.width === 2*this.skinImg.height) {
isOldFormat = true; isOldFormat = true;
} else { } else {
console.log('Bad skin size'); console.log("Bad skin size");
return; return;
} }
} }
let skinContext = this.skinCanvas.getContext('2d'); let skinContext = this.skinCanvas.getContext("2d");
if(isOldFormat){ if(isOldFormat){
let width = this.skinImg.width; let width = this.skinImg.width;
this.skinCanvas.width = width; this.skinCanvas.width = width;
@ -471,17 +487,17 @@ let skinpreview3d = new function(){
this.playerObject.skin.visible = true; this.playerObject.skin.visible = true;
}; };
this.capeImg.crossOrigin = ''; this.capeImg.crossOrigin = "";
this.capeImg.onerror = () => console.log('Failed loading ' + this.capeImg.src); this.capeImg.onerror = () => console.log("Failed loading " + this.capeImg.src);
this.capeImg.onload = () => { this.capeImg.onload = () => {
if (this.capeImg.width !== 2*this.capeImg.height) { if (this.capeImg.width !== 2*this.capeImg.height) {
console.log('Bad cape size'); console.log("Bad cape size");
return; return;
} }
this.capeCanvas.width = this.capeImg.width; this.capeCanvas.width = this.capeImg.width;
this.capeCanvas.height = this.capeImg.height; this.capeCanvas.height = this.capeImg.height;
let capeContext = this.capeCanvas.getContext('2d'); let capeContext = this.capeCanvas.getContext("2d");
capeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height); capeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height);
capeContext.drawImage(this.capeImg, 0, 0, this.capeCanvas.width, this.capeCanvas.height); capeContext.drawImage(this.capeImg, 0, 0, this.capeCanvas.width, this.capeCanvas.height);
@ -562,7 +578,7 @@ let skinpreview3d = new function(){
/** /**
* The MIT License * The MIT License
* *
* Copyright © 2010-2017 three.js authors * Copyright (C) 2010-2017 three.js authors
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -785,20 +801,20 @@ let skinpreview3d = new function(){
}(); }();
this.dispose = function () { this.dispose = function () {
scope.domElement.removeEventListener('contextmenu', onContextMenu, false); scope.domElement.removeEventListener("contextmenu", onContextMenu, false);
scope.domElement.removeEventListener('mousedown', onMouseDown, false); scope.domElement.removeEventListener("mousedown", onMouseDown, false);
scope.domElement.removeEventListener('wheel', onMouseWheel, false); scope.domElement.removeEventListener("wheel", onMouseWheel, false);
scope.domElement.removeEventListener('touchstart', onTouchStart, false); scope.domElement.removeEventListener("touchstart", onTouchStart, false);
scope.domElement.removeEventListener('touchend', onTouchEnd, false); scope.domElement.removeEventListener("touchend", onTouchEnd, false);
scope.domElement.removeEventListener('touchmove', onTouchMove, false); scope.domElement.removeEventListener("touchmove", onTouchMove, false);
document.removeEventListener('mousemove', onMouseMove, false); document.removeEventListener("mousemove", onMouseMove, false);
document.removeEventListener('mouseup', onMouseUp, false); document.removeEventListener("mouseup", onMouseUp, false);
window.removeEventListener('keydown', onKeyDown, false); window.removeEventListener("keydown", onKeyDown, false);
//scope.dispatchEvent({ type: 'dispose' }); // should this be added here? //scope.dispatchEvent({ type: "dispose" }); // should this be added here?
}; };
// //
@ -807,9 +823,9 @@ let skinpreview3d = new function(){
let scope = this; let scope = this;
let changeEvent = { type: 'change' }; let changeEvent = { type: "change" };
let startEvent = { type: 'start' }; let startEvent = { type: "start" };
let endEvent = { type: 'end' }; let endEvent = { type: "end" };
let STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 }; let STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };
@ -896,7 +912,7 @@ let skinpreview3d = new function(){
panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix); panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
} else { } else {
// camera neither orthographic nor perspective // camera neither orthographic nor perspective
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.'); console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
scope.enablePan = false; scope.enablePan = false;
} }
}; };
@ -910,7 +926,7 @@ let skinpreview3d = new function(){
scope.object.updateProjectionMatrix(); scope.object.updateProjectionMatrix();
zoomChanged = true; zoomChanged = true;
} else { } else {
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.'); console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
scope.enableZoom = false; scope.enableZoom = false;
} }
} }
@ -923,7 +939,7 @@ let skinpreview3d = new function(){
scope.object.updateProjectionMatrix(); scope.object.updateProjectionMatrix();
zoomChanged = true; zoomChanged = true;
} else { } else {
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.'); console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
scope.enableZoom = false; scope.enableZoom = false;
} }
} }
@ -1098,8 +1114,8 @@ let skinpreview3d = new function(){
event.preventDefault(); event.preventDefault();
if (state !== STATE.NONE) { if (state !== STATE.NONE) {
document.addEventListener('mousemove', onMouseMove, false); document.addEventListener("mousemove", onMouseMove, false);
document.addEventListener('mouseup', onMouseUp, false); document.addEventListener("mouseup", onMouseUp, false);
scope.dispatchEvent(startEvent); scope.dispatchEvent(startEvent);
} }
} }
@ -1128,8 +1144,8 @@ let skinpreview3d = new function(){
function onMouseUp(event) { function onMouseUp(event) {
if (scope.enabled === false) return; if (scope.enabled === false) return;
handleMouseUp(event); handleMouseUp(event);
document.removeEventListener('mousemove', onMouseMove, false); document.removeEventListener("mousemove", onMouseMove, false);
document.removeEventListener('mouseup', onMouseUp, false); document.removeEventListener("mouseup", onMouseUp, false);
scope.dispatchEvent(endEvent); scope.dispatchEvent(endEvent);
state = STATE.NONE; state = STATE.NONE;
} }
@ -1221,16 +1237,16 @@ let skinpreview3d = new function(){
// //
scope.domElement.addEventListener('contextmenu', onContextMenu, false); scope.domElement.addEventListener("contextmenu", onContextMenu, false);
scope.domElement.addEventListener('mousedown', onMouseDown, false); scope.domElement.addEventListener("mousedown", onMouseDown, false);
scope.domElement.addEventListener('wheel', onMouseWheel, false); scope.domElement.addEventListener("wheel", onMouseWheel, false);
scope.domElement.addEventListener('touchstart', onTouchStart, false); scope.domElement.addEventListener("touchstart", onTouchStart, false);
scope.domElement.addEventListener('touchend', onTouchEnd, false); scope.domElement.addEventListener("touchend", onTouchEnd, false);
scope.domElement.addEventListener('touchmove', onTouchMove, false); scope.domElement.addEventListener("touchmove", onTouchMove, false);
window.addEventListener('keydown', onKeyDown, false); window.addEventListener("keydown", onKeyDown, false);
// force an update at start // force an update at start
@ -1246,7 +1262,7 @@ let skinpreview3d = new function(){
this.enableAnimationControl = true; this.enableAnimationControl = true;
this.skinViewer = skinViewer; this.skinViewer = skinViewer;
this.orbitControls = new skinpreview3d.OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); this.orbitControls = new skinview3d.OrbitControls(skinViewer.camera, skinViewer.renderer.domElement);
this.orbitControls.enablePan = false; this.orbitControls.enablePan = false;
this.orbitControls.target = new THREE.Vector3(0, -12 ,0); this.orbitControls.target = new THREE.Vector3(0, -12 ,0);
this.orbitControls.minDistance = 10; this.orbitControls.minDistance = 10;
@ -1259,26 +1275,13 @@ let skinpreview3d = new function(){
this.skinViewer.animationPaused = !this.skinViewer.animationPaused; this.skinViewer.animationPaused = !this.skinViewer.animationPaused;
} }
}; };
this.skinViewer.domElement.addEventListener('contextmenu', this.animationPauseListener, false); this.skinViewer.domElement.addEventListener("contextmenu", this.animationPauseListener, false);
} }
dispose(){ dispose(){
this.skinViewer.domElement.removeEventListener('contextmenu', this.animationPauseListener, false); this.skinViewer.domElement.removeEventListener("contextmenu", this.animationPauseListener, false);
this.orbitControls.dispose(); this.orbitControls.dispose();
} }
}; };
}(); }();
if(window.jQuery){
(function($) {
$.fn.skinPreview3d = function (jqueryOptions) {
let options = Object.create(jqueryOptions);
options.domElement = this.get(0);
let skinViewer = new skinpreview3d.SkinViewer(options);
if(options.disableControl !== true)
skinViewer.control = new skinpreview3d.SkinControl(skinViewer);
};
} (window.jQuery));
}