clickable export button + fix filename export in metadata
parent
e09fc596f3
commit
9179c468eb
|
@ -1,16 +1,18 @@
|
||||||
export class FileHandler {
|
export class FileHandler {
|
||||||
public static ProcessImages = (fileList: FileList): Promise<string[]> => {
|
public static ProcessImages = (fileList: FileList): Promise<[string[], string[]]> => {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const filenames: string[] = [];
|
const processedFilenames: string[] = [];
|
||||||
|
const originalFilenames: string[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < fileList.length; i++) {
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
const file = fileList[i];
|
const file = fileList[i];
|
||||||
const filename = await FileHandler.ProcessImage(file);
|
const filename = await FileHandler.ProcessImage(file);
|
||||||
|
|
||||||
filenames.push(filename);
|
processedFilenames.push(filename);
|
||||||
|
originalFilenames.push(file.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(filenames);
|
resolve([ processedFilenames, originalFilenames ]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
61
app/page.ts
61
app/page.ts
|
@ -69,6 +69,11 @@ export class Page {
|
||||||
info.classList.toggle('hidden');
|
info.classList.toggle('hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const exportButton = document.getElementById('exportButton') as HTMLElement;
|
||||||
|
exportButton.addEventListener('click', () => {
|
||||||
|
this.ExportData();
|
||||||
|
});
|
||||||
|
|
||||||
this.outputMessage = document.getElementById('outputMessage') as HTMLElement;
|
this.outputMessage = document.getElementById('outputMessage') as HTMLElement;
|
||||||
|
|
||||||
this.message = document.getElementById('message') as HTMLElement;
|
this.message = document.getElementById('message') as HTMLElement;
|
||||||
|
@ -190,27 +195,7 @@ export class Page {
|
||||||
|
|
||||||
case 83: {
|
case 83: {
|
||||||
if (document.activeElement === document.body) {
|
if (document.activeElement === document.body) {
|
||||||
this.pinHandler.UpdateAnimationPinNames();
|
this.ExportData();
|
||||||
|
|
||||||
if (this.ProjectHasNeccesaryData()) {
|
|
||||||
const zip = new JSZip();
|
|
||||||
// name of project
|
|
||||||
const name = this.filenameInput.value;
|
|
||||||
// .anim file
|
|
||||||
zip.file(name + '.anim', JSON.stringify(this.animationData));
|
|
||||||
// pngs
|
|
||||||
const filenames = this.frameHandler.GetFilenames();
|
|
||||||
for (let i = 0; i < filenames.length; i++) {
|
|
||||||
const filedata = filenames[i].split('base64,')[1];
|
|
||||||
const padding = i.toString().padStart(3, '0');
|
|
||||||
zip.file(name + '_' + padding.toString() + '.png', filedata, { base64: true });
|
|
||||||
}
|
|
||||||
// save zip
|
|
||||||
zip.generateAsync({ type: 'blob' }).then((content) => {
|
|
||||||
// see FileSaver.js
|
|
||||||
saveAs(content, name + '.zip');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,6 +204,30 @@ export class Page {
|
||||||
document.addEventListener('keydown', keyDown);
|
document.addEventListener('keydown', keyDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExportData() {
|
||||||
|
this.pinHandler.UpdateAnimationPinNames();
|
||||||
|
|
||||||
|
if (this.ProjectHasNeccesaryData()) {
|
||||||
|
const zip = new JSZip();
|
||||||
|
// name of project
|
||||||
|
const name = this.filenameInput.value;
|
||||||
|
// .anim file
|
||||||
|
zip.file(name + '.anim', JSON.stringify(this.animationData));
|
||||||
|
// pngs
|
||||||
|
const filenames = this.frameHandler.GetFilenames();
|
||||||
|
for (let i = 0; i < filenames.length; i++) {
|
||||||
|
const filedata = filenames[i].split('base64,')[1];
|
||||||
|
const padding = i.toString().padStart(3, '0');
|
||||||
|
zip.file(name + '_' + padding.toString() + '.png', filedata, { base64: true });
|
||||||
|
}
|
||||||
|
// save zip
|
||||||
|
zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||||
|
// see FileSaver.js
|
||||||
|
saveAs(content, name + '.zip');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ProjectHasNeccesaryData(): boolean {
|
private ProjectHasNeccesaryData(): boolean {
|
||||||
this.outputMessage.innerText = '';
|
this.outputMessage.innerText = '';
|
||||||
this.outputMessage.classList.remove('errorMessage');
|
this.outputMessage.classList.remove('errorMessage');
|
||||||
|
@ -284,14 +293,14 @@ export class Page {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const filenames = await FileHandler.ProcessImages(event.dataTransfer!.files);
|
const [ processedFilenames, originalFilenames ] = await FileHandler.ProcessImages(event.dataTransfer!.files);
|
||||||
this.frameHandler.loadFrames(filenames);
|
this.frameHandler.loadFrames(processedFilenames);
|
||||||
|
|
||||||
const newFrames: IFrame[] = [];
|
const newFrames: IFrame[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < filenames.length; i++) {
|
for (let i = 0; i < originalFilenames.length; i++) {
|
||||||
newFrames.push({
|
newFrames.push({
|
||||||
filename: i.toString()
|
filename: originalFilenames[i].toString()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +310,7 @@ export class Page {
|
||||||
this.frameHandler.TogglePlayingAnimation();
|
this.frameHandler.TogglePlayingAnimation();
|
||||||
|
|
||||||
const imageElement = new Image();
|
const imageElement = new Image();
|
||||||
imageElement.src = filenames[0];
|
imageElement.src = processedFilenames[0];
|
||||||
imageElement.onload = () => {
|
imageElement.onload = () => {
|
||||||
this.canvasHandler.ResizeCanvas(imageElement.width, imageElement.height);
|
this.canvasHandler.ResizeCanvas(imageElement.width, imageElement.height);
|
||||||
};
|
};
|
||||||
|
|
|
@ -293,3 +293,16 @@ $pin-button-size: 75px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#exportButton {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
font-size: 30px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,16 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="helpButton">?</div>
|
<div id="helpButton">?</div>
|
||||||
|
<div id="info" class="hidden">
|
||||||
|
<div class="instruction">
|
||||||
|
<p>Drag a group of images onto the page to load them</p>
|
||||||
|
<p><b>Arrow Keys</b> - Advance frames</p>
|
||||||
|
<p><b>Spacebar</b> - Play/Pause Animation</p>
|
||||||
|
<p><b>S</b> - Export</p>
|
||||||
|
<p>Add pins with the <b>+</b> button</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="dropZone">
|
<div id="dropZone">
|
||||||
<div id="allTop">
|
<div id="allTop">
|
||||||
<div id="top">
|
<div id="top">
|
||||||
|
@ -41,15 +51,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="addpin" class="pinButtonContainer">+</div>
|
<div id="addpin" class="pinButtonContainer">+</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="info" class="hidden">
|
<div id="outputMessage"></div>
|
||||||
<div class="instruction">
|
<div id="exportButton">
|
||||||
<p>Drag a group of images onto the page to load them</p>
|
Export
|
||||||
<p><b>Arrow Keys</b> - Advance frames</p>
|
|
||||||
<p><b>Spacebar</b> - Play/Pause Animation</p>
|
|
||||||
<p><b>S</b> - Export</p>
|
|
||||||
<p>Add pins with the <b>+</b> button</p>
|
|
||||||
</div>
|
|
||||||
<div id="outputMessage"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue