rewrite demo page

This commit is contained in:
yushijinhun 2020-08-02 21:13:13 +08:00
parent 61fbbd974a
commit 7ac0b5411b
No known key found for this signature in database
GPG Key ID: 5BC167F73EA558E4
2 changed files with 371 additions and 206 deletions

View File

@ -3,29 +3,86 @@
<head>
<meta charset="utf-8">
<title>skinview3d examples</title>
<title>skinview3d demo</title>
<style>
body, html {
background: #ffffff;
color: #000000;
padding: 0;
body {
font-family: "Helvetica Neue", "Helvetica", "Arial", "sans-serif";
}
h1 {
font-size: 1.25em;
}
h2 {
font-size: 1em;
}
h1,
h2 {
margin-bottom: 0;
}
input[type="number"] {
width: 60px;
}
.control {
display: inline-block;
margin-right: 10px;
}
.control-section {
margin-left: 10px;
}
.control-section>h1,
.control-section>h2 {
margin-left: -10px;
}
table {
border-collapse: collapse;
}
table td,
table th {
border: 1px black dashed;
text-align: left;
width: 50px;
}
thead th {
border-top: unset;
}
tbody tr:last-child td,
tbody tr:last-child th {
border-bottom: unset;
}
table th:first-child,
table td:first-child {
border-left: unset;
}
table th:last-child,
table td:last-child {
border-right: unset;
}
table td input[type="checkbox"] {
vertical-align: middle;
margin: 0;
}
canvas {
background: #5a76f3;
width: 100%;
}
.controls {
padding: 0 12px 0 12px;
}
.controls div {
margin: 6px 0 6px;
.error-log {
margin-top: 0;
color: red;
}
h4{
padding: 0;
margin: 0 0 4px 0;
.error-log:empty {
margin: 0;
}
</style>
</head>
@ -34,105 +91,316 @@
<div id="skin_container"></div>
<div class="controls">
<div>
<h4>Animate</h4>
<button type="button" onclick="walk()">Walk</button>
<button type="button" onclick="run()">Run!</button>
<button type="button" onclick="rotate()">Rotate</button>
<button type="button" onclick="pause()">Pause / Resume</button>
<button type="button" onclick="initSkinViewer()">Reset</button>
<br>
<button id="reset_all" type="button" class="control">Reset All</button>
<div class="control-section">
<h1>Canvas Size</h1>
<div class="control">
<label for="canvas_width">Width:</label>
<input id="canvas_width" type="number" value="300">
</div>
<div class="control">
<label for="canvas_height">Height:</label>
<input id="canvas_height" type="number" value="300">
</div>
</div>
Global Animation Speed: x<input type="text" id="speed" value="1" title="1 for default" size="5" />
<button type="button" onclick="setGlobalAnimationSpeed()">Set</button>
<div>
<h4> Animation Mouse Control</h4>
<input type="checkbox" id="rotate" checked="checked" onclick="control.enableRotate = this.checked"><label for="rotate">Enable
Rotate</label>
<input type="checkbox" id="zoom" checked="checked" onclick="control.enableZoom = this.checked"><label for="zoom">Enable
Zoom</label>
<input type="checkbox" id="pan" onclick="control.enablePan = this.checked"><label for="pan">Enable Pan</label>
<div class="control-section">
<h1>Animation</h1>
<div class="control">
<label for="global_animation_speed">Global Speed:</label>
<input id="global_animation_speed" type="number" value="1" step="0.1">
</div>
<button id="animation_pause_resume" type="button" class="control">Pause / Resume</button>
<div>
<h4>Canvas Size</h4>
Width: <input type="text" id="width" value="600" size="5" />
Height: <input type="text" id="height" value="600" size="5" />
<button type="button" onclick="resizeSkinViewer()">Change Size</button>
<h2>Rotate</h2>
<div class="control">
<input id="rotate_animation" type="checkbox">
<label for="rotate_animation">Enable</label>
</div>
<div>
<h4>Layers</h4>
<input id="head" type="checkbox" onclick="togglePart('head')" checked="checked" />
<label for="head">Head</label>
<input id="body" type="checkbox" onclick="togglePart('body')" checked="checked" />
<label for="body">Body</label>
<input id="leftArm" type="checkbox" onclick="togglePart('leftArm')" checked="checked" />
<label for="leftArm">LeftArm</label>
<input id="rightArm" type="checkbox" onclick="togglePart('rightArm')" checked="checked" />
<label for="rightArm">RightArm</label>
<input id="leftLeg" type="checkbox" onclick="togglePart('leftLeg')" checked="checked" />
<label for="leftLeg">LeftLeg</label>
<input id="rightLeg" type="checkbox" onclick="togglePart('rightLeg')" checked="checked" />
<label for="rightLeg">RightLeg</label>
<br />
<input id="head2" type="checkbox" onclick="togglePart('head2')" checked="checked" />
<label for="head2">Head2</label>
<input id="body2" type="checkbox" onclick="togglePart('body2')" checked="checked" />
<label for="body2">Body2</label>
<input id="leftArm2" type="checkbox" onclick="togglePart('leftArm2')" checked="checked" />
<label for="leftArm2">LeftArm2</label>
<input id="rightArm2" type="checkbox" onclick="togglePart('rightArm2')" checked="checked" />
<label for="rightArm2">RightArm2</label>
<input id="leftLeg2" type="checkbox" onclick="togglePart('leftLeg2')" checked="checked" />
<label for="leftLeg2">LeftLeg2</label>
<input id="rightLeg2" type="checkbox" onclick="togglePart('rightLeg2')" checked="checked" />
<label for="rightLeg2">RightLeg2</label>
<div class="control">
<label for="rotate_animation_speed">Speed:</label>
<input id="rotate_animation_speed" type="number" value="1" step="0.1">
</div>
<div>
<h4>Skin</h4>
<select id="skin_url" onchange="reloadTextures()">
<option value="img/1_8_texturemap_redux.png">Texture Map (64x64)</option>
<option value="img/Hacksore.png">Hacksore (64x32)</option>
<option value="img/haka.png">Haka (64x64)</option>
<option value="img/hatsune_miku.png">Hatsune Miku (64x64)</option>
<option value="img/ironman_hd.png">Ironman (256x265)</option>
<option value="img/sethbling.png">Sethbling (64x32)</option>
</select>
</div>
<div>
<h4>Cape</h4>
<select id="cape_url" onchange="reloadTextures()">
<option value="">None</option>
<option value="img/cape.png">Mojang Legacy</option>
<option value="img/mojang_cape.png">Mojang</option>
<option value="img/hd_cape.png">HD Cape</option>
<h2>Walk / Run</h2>
<div class="control">
<input type="radio" id="primary_animation_none" name="primary_animation" value="" checked>
<label for="primary_animation_none">None</label>
<input type="radio" id="primary_animation_walk" name="primary_animation" value="walk">
<label for="primary_animation_walk">Walk</label>
<input type="radio" id="primary_animation_run" name="primary_animation" value="run">
<label for="primary_animation_run">Run</label>
</div>
<div class="control">
<label for="primary_animation_speed">Speed:</label>
<input id="primary_animation_speed" type="number" value="1" step="0.1">
</div>
</div>
</div>
<div class="control-section">
<h1>Mouse Control</h1>
<div class="control">
<input type="checkbox" id="control_rotate" checked>
<label for="control_rotate">Enable Rotate</label>
<input type="checkbox" id="control_zoom" checked>
<label for="control_zoom">Enable Zoom</label>
<input type="checkbox" id="control_pan">
<label for="control_pan">Enable Pan</label>
</div>
</div>
<div class="control-section">
<h1>Skin Layers</h1>
<table id="layers_table" class="control">
<!-- table contents are generated using javascript -->
</table>
</div>
<div class="control-section">
<h1>Textures</h1>
<div>
<div class="control">
<label for="skin_url">Skin URL:</label>
<input id="skin_url" type="text" value="img/1_8_texturemap_redux.png" placeholder="none"
list="default_skins">
<datalist id="default_skins">
<option value="img/1_8_texturemap_redux.png">
<option value="img/Hacksore.png">
<option value="img/haka.png">
<option value="img/hatsune_miku.png">
<option value="img/ironman_hd.png">
<option value="img/sethbling.png">
</datalist>
<input id="skin_url_upload" type="file" accept="image/*" style="display: none;">
<button type="button" class="control"
onclick="document.getElementById('skin_url_upload').click();">Browse...</button>
</div>
<div class="control">
<label for="skin_model">Model:</label>
<select id="skin_model" value="auto-detect">
<option value="auto-detect">Auto detect</option>
<option value="default">Default</option>
<option value="slim">Slim</option>
</select>
</div>
</div>
<script type="text/javascript" src="js/dist/skinview3d.bundle.js"></script>
<script type="text/javascript" src="js/example.js"></script>
<pre id="errorlog_skin" class="error-log"></pre>
<div>
<div class="control">
<label for="cape_url">Cape URL:</label>
<input id="cape_url" type="text" value="" placeholder="none" list="default_capes">
<datalist id="default_capes">
<option value="">
<option value="img/cape.png">
<option value="img/mojang_cape.png">
<option value="img/hd_cape.png">
</datalist>
<input id="cape_url_upload" type="file" accept="image/*" style="display: none;">
<button type="button" class="control"
onclick="document.getElementById('cape_url_upload').click();">Browse...</button>
</div>
</div>
<pre id="errorlog_cape" class="error-log"></pre>
</div>
</div>
<script src="js/dist/skinview3d.bundle.js"></script>
<script>
initSkinViewer();
walk();
const skinParts = ["head", "body", "rightArm", "leftArm", "rightLeg", "leftLeg"];
const skinLayers = ["innerLayer", "outerLayer"];
const availableAnimations = {
walk: skinview3d.WalkingAnimation,
run: skinview3d.RunningAnimation
};
let skinViewer;
let oribitControl;
let rotateAnimation;
let primaryAnimation;
function reloadSkin() {
const url = document.getElementById("skin_url").value;
const errlog = document.getElementById("errorlog_skin");
if (url === "") {
skinViewer.loadSkin(null);
errlog.innerText = "";
} else {
skinViewer.loadSkin(url, document.getElementById("skin_model").value)
.then(() => errlog.innerText = "")
.catch(e => {
errlog.innerText = e.message;
console.error(e);
});
}
}
function reloadCape() {
const url = document.getElementById("cape_url").value;
const errlog = document.getElementById("errorlog_cape");
if (url === "") {
skinViewer.loadCape(null);
errlog.innerText = "";
} else {
skinViewer.loadCape(url)
.then(() => errlog.innerText = "")
.catch(e => {
errlog.innerText = e.message;
console.error(e);
});
}
}
function initializeLayersTable() {
const table = document.getElementById("layers_table");
const thead = document.createElement("thead");
table.appendChild(thead);
const rowHead = document.createElement("tr");
rowHead.appendChild(document.createElement("th"));
thead.appendChild(rowHead);
for (const part of skinParts) {
const cellHead = document.createElement("th");
cellHead.innerText = part;
rowHead.appendChild(cellHead);
}
const tbody = document.createElement("tbody");
table.appendChild(tbody);
for (const layer of skinLayers) {
const row = document.createElement("tr");
tbody.appendChild(row);
const cellLayer = document.createElement("th");
cellLayer.innerText = layer;
row.appendChild(cellLayer);
for (const part of skinParts) {
const cell = document.createElement("td");
row.appendChild(cell);
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.dataset.layer = layer;
checkbox.dataset.part = part;
checkbox.checked = true;
cell.appendChild(checkbox);
}
}
}
function initializeControls() {
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("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 => {
if (e.target.checked && rotateAnimation === null) {
rotateAnimation = skinViewer.animations.add(skinview3d.RotatingAnimation);
rotateAnimation.speed = document.getElementById("rotate_animation_speed").value;
} else if (!e.target.checked && rotateAnimation !== null) {
rotateAnimation.resetAndRemove();
rotateAnimation = null;
}
});
document.getElementById("rotate_animation_speed").addEventListener("change", e => {
if (rotateAnimation !== null) {
rotateAnimation.speed = e.target.value;
}
});
for (const el of document.querySelectorAll('input[type="radio"][name="primary_animation"]')) {
el.addEventListener("change", e => {
if (primaryAnimation !== null) {
primaryAnimation.resetAndRemove();
primaryAnimation = null;
}
if (e.target.value !== "") {
primaryAnimation = skinViewer.animations.add(availableAnimations[e.target.value]);
primaryAnimation.speed = document.getElementById("primary_animation_speed").value;
}
});
}
document.getElementById("primary_animation_speed").addEventListener("change", e => {
if (primaryAnimation !== null) {
primaryAnimation.speed = e.target.value;
}
});
document.getElementById("control_rotate").addEventListener("change", e => oribitControl.enableRotate = e.target.checked);
document.getElementById("control_zoom").addEventListener("change", e => oribitControl.enableZoom = e.target.checked);
document.getElementById("control_pan").addEventListener("change", e => oribitControl.enablePan = e.target.checked);
for (const part of skinParts) {
for (const layer of skinLayers) {
document.querySelector(`#layers_table input[type="checkbox"][data-part="${part}"][data-layer="${layer}"]`)
.addEventListener("change", e => skinViewer.playerObject.skin[part][layer].visible = e.target.checked);
}
}
const skinReader = new FileReader();
skinReader.addEventListener("load", e => {
document.getElementById("skin_url").value = skinReader.result;
reloadSkin();
});
document.getElementById("skin_url_upload").addEventListener("change", e => {
const file = e.target.files[0];
if (file !== undefined) {
skinReader.readAsDataURL(file);
}
});
const capeReader = new FileReader();
capeReader.addEventListener("load", e => {
document.getElementById("cape_url").value = capeReader.result;
reloadCape();
});
document.getElementById("cape_url_upload").addEventListener("change", e => {
const file = e.target.files[0];
if (file !== undefined) {
capeReader.readAsDataURL(file);
}
});
document.getElementById("skin_url").addEventListener("change", () => reloadSkin());
document.getElementById("skin_model").addEventListener("change", () => reloadSkin());
document.getElementById("cape_url").addEventListener("change", () => reloadCape());
document.getElementById("reset_all").addEventListener("click", () => {
skinViewer.dispose();
initializeViewer();
});
}
function initializeViewer() {
skinViewer = new skinview3d.SkinViewer(document.getElementById("skin_container"));
oribitControl = skinview3d.createOrbitControls(skinViewer);
rotateAnimation = null;
primaryAnimation = null;
skinViewer.width = document.getElementById("canvas_width").value;
skinViewer.height = document.getElementById("canvas_height").value;
skinViewer.animations.speed = document.getElementById("global_animation_speed").value;
if (document.getElementById("rotate_animation").checked) {
rotateAnimation = skinViewer.animations.add(skinview3d.RotatingAnimation);
rotateAnimation.speed = document.getElementById("rotate_animation_speed").value;
}
const primaryAnimationName = document.querySelector('input[type="radio"][name="primary_animation"]:checked').value;
if (primaryAnimationName !== "") {
primaryAnimation = skinViewer.animations.add(availableAnimations[primaryAnimationName]);
primaryAnimation.speed = document.getElementById("primary_animation_speed").value;
}
oribitControl.enableRotate = document.getElementById("control_rotate").checked;
oribitControl.enableZoom = document.getElementById("control_zoom").checked;
oribitControl.enablePan = document.getElementById("control_pan").checked;
for (const part of skinParts) {
for (const layer of skinLayers) {
skinViewer.playerObject.skin[part][layer].visible =
document.querySelector(`#layers_table input[type="checkbox"][data-part="${part}"][data-layer="${layer}"]`).checked;
}
}
reloadSkin();
reloadCape();
}
initializeLayersTable();
initializeControls();
initializeViewer();
</script>
</body>
</html>

View File

@ -1,103 +0,0 @@
// Use pure ES5 for max browser compatibility
var skinViewer, control, handles = {}, globalAnimationSpeed = 1;
var skinParts = {}
function el(id) {
return document.getElementById(id);
}
function initSkinViewer() {
if (skinViewer instanceof skinview3d.SkinViewer) {
skinViewer.dispose();
handles = {};
control = undefined;
}
// Reset animation speed
el('speed').value = globalAnimationSpeed = 1;
skinViewer = new skinview3d.SkinViewer(el("skin_container"), {
width: el('width').value,
height: el('height').value
});
reloadTextures();
skinViewer.camera.position.z = 70;
control = skinview3d.createOrbitControls(skinViewer);
var parts = skinViewer.playerObject.skin;
// set inner parts
skinParts.head = parts.head.innerLayer;
skinParts.body = parts.body.innerLayer;
skinParts.leftArm = parts.leftArm.innerLayer;
skinParts.rightArm = parts.rightArm.innerLayer;
skinParts.leftLeg = parts.leftLeg.innerLayer;
skinParts.rightLeg = parts.rightLeg.innerLayer;
// set outter parts
skinParts.head2 = parts.head.outerLayer;
skinParts.body2 = parts.body.outerLayer;
skinParts.leftArm2 = parts.leftArm.outerLayer;
skinParts.rightArm2 = parts.rightArm.outerLayer;
skinParts.leftLeg2 = parts.leftLeg.outerLayer;
skinParts.rightLeg2 = parts.rightLeg.outerLayer;
}
function reloadTextures() {
var skinUrl = el('skin_url').value;
var capeUrl = el('cape_url').value;
skinViewer.loadSkin(skinUrl === "" ? null : skinUrl);
skinViewer.loadCape(capeUrl === "" ? null : capeUrl);
}
function resizeSkinViewer() {
skinViewer.width = el('width').value;
skinViewer.height = el('height').value;
}
function pause() {
skinViewer.animations.paused = !skinViewer.animations.paused;
}
function walk() {
if (handles.run) {
handles.run.remove();
delete handles.run;
}
handles.walk = handles.walk || skinViewer.animations.add(skinview3d.WalkingAnimation);
}
function run() {
if (handles.walk) {
handles.walk.remove();
delete handles.walk;
}
handles.run = handles.run || skinViewer.animations.add(skinview3d.RunningAnimation);
}
function rotate() {
if (handles.rotate) {
handles.rotate.paused = !handles.rotate.paused;
} else {
handles.rotate = skinViewer.animations.add(skinview3d.RotatingAnimation);
}
}
function togglePart(partName) {
skinParts[partName].visible = !skinParts[partName].visible;
}
function setGlobalAnimationSpeed() {
var currentSpeed = el('speed').value;
if (!isNaN(currentSpeed)) {
skinViewer.animations.speed = currentSpeed;
}
}