XDUPlayer/Js/Common.js

346 lines
8.3 KiB
JavaScript

'use strict';
let rootUrl = `${window.location.protocol}//${window.location.host}/`;
const baseDimensions = {width: 1334, height: 750};
const screenRatio = 9/16;
const CUSTOM = {
custom: 'Custom',
stock: 'Stock'
}
class commonFunctions {
static getFileText(file) {
return new Promise((resolve, reject) => {
try
{
fetch(file)
.then((success) => {
if(success.status !== 200) { reject(success); return; }
success.text()
.then((text) => {
resolve(text);
});
}, (failure) => {
reject(failure);
});
} catch(error) {
reject(error);
}
});
}
static getFileJson(file) {
return new Promise((resolve, reject) => {
try
{
fetch(file)
.then((success) => {
if(success.status !== 200) { reject(success); return; }
success.json()
.then((json) => {
resolve(json);
});
}, (failure) => {
reject(failure);
});
} catch(error) {
reject(error);
}
});
}
static readQueryParameters() {
let params = {};
let indexOfStart = window.location.href.indexOf("?");
let toCheck = window.location.href.slice(indexOfStart + 1);
let name = "";
let value = "";
let nameStep = true;
for(let i = 0; i < toCheck.length; ++i) {
if(toCheck[i] === "=") {
name = name.toLowerCase();
params[decodeURIComponent(name)] = "";
nameStep = false
continue;
}
if(toCheck[i] === "&") {
params[name] = decodeURIComponent(value);
name = "";
value = "";
nameStep = true;
continue;
}
if(nameStep) {
name += toCheck[i];
} else {
value += toCheck[i];
}
}
params[name] = decodeURIComponent(value);
return params;
}
static readLine(line, headers) {
if(line.startsWith('//')) {
return {comment: line};
} else if(!line) {
return undefined;
} else {
let split = line.split('\t');
let newEntry = {};
for(let i = 0; i < split.length; ++i) {
let x = split[i].trim();
newEntry[headers[i]] = x;
}
return newEntry;
}
}
static lerp(start, end, t, type = "linear") {
switch(type) {
default:
case "linear":
break;
case "sin":
t = t * (Math.PI / 2);
t = Math.sin(t);
break;
case "fullsin":
t = t * Math.PI;
t = Math.sin(t);
break;
case "fullwait":
t = -(Math.pow((2*t-1), 4)) + 1;
break;
case "square":
t = Math.pow(t, 2);
break;
case "exp":
t = Math.pow(t, 1/4);
break;
case "sqrt":
t = Math.sqrt(t);
break;
//Some of the stuff here is just kinda arbitrary
case "dampsin":
t = (1 * (Math.pow(0.3, t)) * Math.sin((2*Math.PI*t/1.0) + 0)) / 1.25;
if(t < -0.45) {
t = -0.45;
}
break;
case "punch": {
if (t === 0 || t === 1)
return start;
let change = end - start;
let num = 0.3;
let rad = Math.PI * 2;
let num2 = num / rad * Math.asin(0);
return change * Math.pow(2, -10 * t) * Math.sin((t * 1 - num2) * rad / num);
}
//http://www.gizma.com/easing/
case "quadout": {
let change = end - start;
return -change * t*(t-2) + start;
}
case "quadinout": {
let change = end - start;
t = t * 2;
if (t < 1) { return change/2*t*t + start; }
t--;
return -change/2 * (t*(t-2) - 1) + start;
}
}
return (1 - t) * start + t * end;
//-(2*x-1)^4 +1
}
static getColorFromName(name) {
if(!name) { return { color: 0xFFFFFF, alpha: 1 } }
if(name.startsWith('#')) {
let alpha = '';
let color = '';
name = name.substring(1);
if(name.length === 8) {
color = parseInt(name.slice(0, 6), 16);
alpha = parseInt(name.slice(6, 8), 16) / 255;
} else {
color = parseInt(name, 16);
alpha = 1;
}
return { color, alpha };
} else {
switch(name.toLowerCase()) {
default:
case 'black':
return { color: 0x000000, alpha: 1 };
case 'white':
return { color: 0xFFFFFF, alpha: 1 };
case 'silver':
return { color: 0xD7D7D7, alpha: 1 };
}
}
}
static hexToRgb(hex) {
let r = (hex >> 16) & 255;
let g = (hex >> 8) & 255;
let b = hex & 255;
return [r/255, g/255, b/255];
}
static componentToHex(c) {
var hex = parseInt(c).toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
static rgbToHex(rgb) {
return `#${this.componentToHex(rgb[0] * 255)}${this.componentToHex(rgb[1]* 255)}${this.componentToHex(rgb[2]* 255)}`;
}
static convertUtageTextTags(text) {
text = text.replace(/<speed.*?>|<\/speed>/g, "");
text = text.replace(/\\n/g, "<br/>")
//rewrite ruby tags to normal html format
let rubyMatches = text.match(/<ruby=.*?<\/ruby>/g);
if(rubyMatches) {
for(let i = 0; i < rubyMatches.length; ++i) {
let m = rubyMatches[i];
let rText = '';
let innerText = '';
let startR = false;
let startI = false;
for(let j = 0; j < m.length; ++j) {
if(m[j] === '<' && j !== 0) { startI = false; }
if(startI) {
innerText+= m[j];
}
if(m[j] === '>') { startR = false; startI = true; }
if(startR) {
rText += m[j];
}
if(m[j] === '=') { startR = true; }
}
text = text.replace(m, `<ruby>${innerText}<rt>${rText}</rt></ruby>`);
}
}
//convert size tags to spans with font size
let sizeMatches = text.match(/<size=.*?>/g);
if(sizeMatches) {
for(let i = 0; i < sizeMatches.length; ++i) {
let m = sizeMatches[i];
let size = m.match(/\d{1,3}/);
if(size[0]) {
let s = Number(size[0]) - 1;
text = text.replace(m, `<span style="font-size:${s}px;">`);
}
}
}
text = text.replace('</size>', '</span>')
return text;
}
static getNewResolution(baseRes, screenWidth, screenHeight, minusHeight) {
let retval = { width: 0, height: 0 };
if(screenWidth >= screenHeight) {
let newPer = (screenHeight - (minusHeight || 0)) / baseRes.height;
retval.height = baseRes.height * newPer;
retval.width = baseRes.width * newPer;
if(retval.width > screenWidth) {
newPer = screenWidth / baseRes.width;
retval.height = baseRes.height * newPer;
retval.width = baseRes.width * newPer;
}
} else if (screenHeight > screenWidth) {
let newPer = screenWidth / baseRes.width;
retval.height = baseRes.height * newPer;
retval.width = baseRes.width * newPer;
}
return retval;
}
static getAnchorFromCharPivot(pivot) {
let x = 0.5;
let y = 0.5;
let sp = pivot.split(" ");
for(let p of sp) {
if(p.startsWith("x=")) {
x = Number(p.substring(2));
} else if(p.startsWith("y=")) {
y = Number(p.substring(2));
//The y pivot from utage is based from the bottom so it needs to be flipped
y = 1 - y;
}
}
return {x, y};
}
static getPropertiesFromTweenCommand(props, reverseY = true) {
let retval = {};
let indexX = props.indexOf("x=");
if(indexX !== -1) {
retval.x = "";
for(let i = indexX + 2; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.x += props[i];
}
retval.x = Number(retval.x);
}
let indexY = props.indexOf("y=");
if(indexY !== -1) {
retval.y = "";
for(let i = indexY+ 2; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.y += props[i];
}
retval.y = reverseY ? -Number(retval.y) : Number(retval.y);
}
let indexT = props.indexOf("time=");
if(indexT !== -1) {
retval.time = "";
for(let i = indexT + 5; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.time += props[i];
}
retval.time = Number(retval.time) * 1000;
}
let indexD = props.indexOf("delay=");
if(indexD !== -1) {
retval.delay = "";
for(let i = indexD + 6; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.delay += props[i];
}
retval.delay = Number(retval.delay) * 1000;
}
let indexA = props.indexOf("alpha=");
if(indexA !== -1) {
retval.alpha = "";
for(let i = indexA + 6; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.alpha += props[i];
}
retval.alpha = Number(retval.alpha);
}
let indexS = props.indexOf("speed=");
if(indexS !== -1) {
retval.speed = "";
for(let i = indexS + 6; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.speed += props[i];
}
retval.speed = Number(retval.speed);
}
let indexC = props.indexOf("color=");
if(indexC !== -1) {
retval.color = "";
for(let i = indexC + 6; i < props.length; ++i) {
if(props[i] == " ") { break; }
retval.color += props[i];
}
}
return retval;
}
}