mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-24 02:36:00 +00:00
113 lines
2.9 KiB
JavaScript
113 lines
2.9 KiB
JavaScript
import SKIN_SPRITES from './skinSprites';
|
|
import JSZip from '../node_modules/jszip/dist/jszip'; // Hack
|
|
import {parseViscolors, parseIni} from './utils';
|
|
|
|
const bmpUriFromFile = (file) => {
|
|
return `data:image/bmp;base64,${btoa(file.asBinary())}`;
|
|
};
|
|
|
|
// "Promisify" processBuffer
|
|
const getBufferFromFile = (file) => {
|
|
return new Promise((resolve) => {
|
|
file.processBuffer(resolve);
|
|
});
|
|
};
|
|
|
|
const getZipFromBuffer = (buffer) => new JSZip(buffer);
|
|
|
|
const getSpriteSheetFilesFromZip = (zip) => {
|
|
const spriteObjs = SKIN_SPRITES.map((spriteObj) => ({
|
|
...spriteObj,
|
|
file: zip.file(new RegExp(`(/|^)${spriteObj.name}`, 'i'))[0]
|
|
}));
|
|
return spriteObjs.filter((spriteObj) => spriteObj.file);
|
|
};
|
|
|
|
// Extract the CSS rules for a given file, and add them to the object
|
|
const extractCss = (spriteObj) => {
|
|
return new Promise((resolve) => {
|
|
const uri = bmpUriFromFile(spriteObj.file);
|
|
const img = new Image();
|
|
|
|
img.onload = () => {
|
|
const canvas = document.createElement('canvas');
|
|
const images = {};
|
|
spriteObj.sprites.forEach((sprite) => {
|
|
canvas.height = sprite.height;
|
|
canvas.width = sprite.width;
|
|
|
|
const context = canvas.getContext('2d');
|
|
context.drawImage(img, -sprite.x, -sprite.y);
|
|
const image = canvas.toDataURL();
|
|
if (sprite.name) {
|
|
images[sprite.name] = image;
|
|
}
|
|
});
|
|
resolve({...spriteObj, images});
|
|
};
|
|
img.src = uri;
|
|
});
|
|
};
|
|
|
|
// Extract the color data from a VISCOLOR.TXT file and add it to the object
|
|
const extractColors = (spriteObj) => {
|
|
return {
|
|
...spriteObj,
|
|
colors: parseViscolors(spriteObj.file.asText())
|
|
};
|
|
};
|
|
|
|
// Extract the color data from a VISCOLOR.TXT file and add it to the object
|
|
const extractPlaylistStyle = (spriteObj) => {
|
|
return {
|
|
...spriteObj,
|
|
playlistStyle: parseIni(spriteObj.file.asText())
|
|
};
|
|
};
|
|
|
|
const getSkinDataFromFiles = (spriteObjs) => {
|
|
return Promise.all(spriteObjs.map((spriteObj) => {
|
|
switch (spriteObj.name) {
|
|
case 'VISCOLOR':
|
|
return extractColors(spriteObj);
|
|
case 'PLEDIT.TXT':
|
|
return extractPlaylistStyle(spriteObj);
|
|
default:
|
|
return extractCss(spriteObj);
|
|
}
|
|
}));
|
|
};
|
|
|
|
const collectCssAndColors = (spriteObjs) => {
|
|
let images = {};
|
|
let colors = null;
|
|
let playlistStyle = null;
|
|
spriteObjs.forEach((spriteObj) => {
|
|
if (spriteObj.images) {
|
|
images = {...images, ...spriteObj.images};
|
|
}
|
|
if (spriteObj.colors) {
|
|
colors = spriteObj.colors;
|
|
}
|
|
if (spriteObj.playlistStyle) {
|
|
playlistStyle = spriteObj.playlistStyle;
|
|
}
|
|
});
|
|
|
|
return {
|
|
images,
|
|
colors,
|
|
playlistStyle
|
|
};
|
|
};
|
|
|
|
// A promise that, given a File object, returns a skin style object
|
|
const parseSkin = (file) => {
|
|
return getBufferFromFile(file)
|
|
.then(getZipFromBuffer)
|
|
.then(getSpriteSheetFilesFromZip)
|
|
.then(getSkinDataFromFiles)
|
|
.then(collectCssAndColors);
|
|
};
|
|
|
|
module.exports = parseSkin;
|