Move skin/cape loading to utils.js

This commit is contained in:
yushijinhun 2018-07-05 10:56:21 +08:00
parent 867660f2ee
commit a4bd8bc706
No known key found for this signature in database
GPG Key ID: 5BC167F73EA558E4
2 changed files with 61 additions and 54 deletions

View File

@ -47,9 +47,9 @@ function computeSkinScale(width) {
return width / 64.0; return width / 64.0;
} }
function convertSkinTo1_8(skinContext, width) { function convertSkinTo1_8(context, width) {
let scale = computeSkinScale(width); let scale = computeSkinScale(width);
let copySkin = (sX, sY, w, h, dX, dY, flipHorizontal) => copyImage(skinContext, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal); let copySkin = (sX, sY, w, h, dX, dY, flipHorizontal) => copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal);
copySkin(4, 16, 4, 4, 20, 48, true); // Top Leg copySkin(4, 16, 4, 4, 20, 48, true); // Top Leg
copySkin(8, 16, 4, 4, 24, 48, true); // Bottom Leg copySkin(8, 16, 4, 4, 24, 48, true); // Bottom Leg
@ -65,7 +65,57 @@ function convertSkinTo1_8(skinContext, width) {
copySkin(52, 20, 4, 12, 44, 52, true); // Back Arm copySkin(52, 20, 4, 12, 44, 52, true); // Back Arm
} }
function isSlimSkin(skinContext, width) { function loadSkinToCanvas(canvas, image) {
let isOldFormat = false;
if (image.width !== image.height) {
if (image.width === 2 * image.height) {
isOldFormat = true;
} else {
throw `Bad skin size: ${image.width}x${image.height}`;
}
}
let context = canvas.getContext("2d");
if (isOldFormat) {
let sideLength = image.width;
canvas.width = sideLength;
canvas.height = sideLength;
context.clearRect(0, 0, sideLength, sideLength);
context.drawImage(image, 0, 0, sideLength, sideLength / 2.0);
convertSkinTo1_8(context, sideLength);
} else {
canvas.width = image.width;
canvas.height = image.height;
context.clearRect(0, 0, image.width, image.height);
context.drawImage(image, 0, 0, canvas.width, canvas.height);
}
}
function loadCapeToCanvas(canvas, image) {
let isOldFormat = false;
if (image.width !== 2 * image.height) {
if (image.width * 17 == image.height * 22) {
// width/height = 22/17
isOldFormat = true;
} else {
throw `Bad cape size: ${image.width}x${image.height}`;
}
}
let context = canvas.getContext("2d");
if (isOldFormat) {
let width = image.width * 64 / 22;
canvas.width = width;
canvas.height = width / 2;
} else {
canvas.width = image.width;
canvas.height = image.height;
}
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0, image.width, image.height);
}
function isSlimSkin(canvas) {
// Detects whether the skin is default or slim. // Detects whether the skin is default or slim.
// //
// The right arm area of *default* skins: // The right arm area of *default* skins:
@ -107,12 +157,13 @@ function isSlimSkin(skinContext, width) {
// If there is a transparent pixel in any of the 4 unused areas, the skin must be slim, // If there is a transparent pixel in any of the 4 unused areas, the skin must be slim,
// as transparent pixels are not allowed in the first layer. // as transparent pixels are not allowed in the first layer.
let scale = computeSkinScale(width); let scale = computeSkinScale(canvas.width);
let checkArea = (x, y, w, h) => hasTransparency(skinContext, x * scale, y * scale, w * scale, h * scale); let context = canvas.getContext("2d");
let checkArea = (x, y, w, h) => hasTransparency(context, x * scale, y * scale, w * scale, h * scale);
return checkArea(50, 16, 2, 4) || return checkArea(50, 16, 2, 4) ||
checkArea(54, 20, 2, 12) || checkArea(54, 20, 2, 12) ||
checkArea(42, 48, 2, 4) || checkArea(42, 48, 2, 4) ||
checkArea(46, 52, 2, 12); checkArea(46, 52, 2, 12);
} }
export { convertSkinTo1_8, isSlimSkin }; export { isSlimSkin, loadSkinToCanvas, loadCapeToCanvas };

View File

@ -1,7 +1,7 @@
import * as THREE from "three"; import * as THREE from "three";
import { PlayerObject } from "./model"; import { PlayerObject } from "./model";
import { invokeAnimation } from "./animation"; import { invokeAnimation } from "./animation";
import { convertSkinTo1_8, isSlimSkin} from "./utils"; import { loadSkinToCanvas,loadCapeToCanvas, isSlimSkin } from "./utils";
class SkinViewer { class SkinViewer {
constructor(options) { constructor(options) {
@ -49,33 +49,10 @@ class SkinViewer {
this.skinImg.crossOrigin = "anonymous"; this.skinImg.crossOrigin = "anonymous";
this.skinImg.onerror = () => console.error("Failed loading " + this.skinImg.src); this.skinImg.onerror = () => console.error("Failed loading " + this.skinImg.src);
this.skinImg.onload = () => { this.skinImg.onload = () => {
let isOldFormat = false; loadSkinToCanvas(this.skinCanvas, this.skinImg);
if (this.skinImg.width !== this.skinImg.height) {
if (this.skinImg.width === 2 * this.skinImg.height) {
isOldFormat = true;
} else {
console.error("Bad skin size");
return;
}
}
let skinContext = this.skinCanvas.getContext("2d");
if (isOldFormat) {
let width = this.skinImg.width;
this.skinCanvas.width = width;
this.skinCanvas.height = width;
skinContext.clearRect(0, 0, width, width);
skinContext.drawImage(this.skinImg, 0, 0, width, width / 2.0);
convertSkinTo1_8(skinContext, width);
} else {
this.skinCanvas.width = this.skinImg.width;
this.skinCanvas.height = this.skinImg.height;
skinContext.clearRect(0, 0, this.skinCanvas.width, this.skinCanvas.height);
skinContext.drawImage(this.skinImg, 0, 0, this.skinCanvas.width, this.skinCanvas.height);
}
if (this.detectModel) { if (this.detectModel) {
this.playerObject.skin.slim = isSlimSkin(skinContext, this.skinCanvas.width); this.playerObject.skin.slim = isSlimSkin(this.skinCanvas);
} }
this.skinTexture.needsUpdate = true; this.skinTexture.needsUpdate = true;
@ -88,28 +65,7 @@ class SkinViewer {
this.capeImg.crossOrigin = "anonymous"; this.capeImg.crossOrigin = "anonymous";
this.capeImg.onerror = () => console.error("Failed loading " + this.capeImg.src); this.capeImg.onerror = () => console.error("Failed loading " + this.capeImg.src);
this.capeImg.onload = () => { this.capeImg.onload = () => {
let isOldFormat = false; loadCapeToCanvas(this.capeCanvas, this.capeImg);
if (this.capeImg.width !== 2 * this.capeImg.height) {
if (this.capeImg.width * 17 == this.capeImg.height * 22) {
// width/height = 22/17
isOldFormat = true;
} else {
console.error("Bad cape size");
return;
}
}
let capeContext = this.capeCanvas.getContext("2d");
if (isOldFormat) {
let width = this.capeImg.width * 64 / 22;
this.capeCanvas.width = width;
this.capeCanvas.height = width / 2;
} else {
this.capeCanvas.width = this.capeImg.width;
this.capeCanvas.height = this.capeImg.height;
}
capeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height);
capeContext.drawImage(this.capeImg, 0, 0, this.capeImg.width, this.capeImg.height);
this.capeTexture.needsUpdate = true; this.capeTexture.needsUpdate = true;
this.capeMaterial.needsUpdate = true; this.capeMaterial.needsUpdate = true;