Skip to content

Commit

Permalink
Download as ZIP
Browse files Browse the repository at this point in the history
  • Loading branch information
yeoji committed Dec 21, 2023
1 parent ce26b56 commit a7d9c62
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 31 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"sass": "^1.34.0"
},
"dependencies": {
"jquery": "^3.6.0"
"jquery": "^3.6.0",
"jszip": "^3.10.1"
}
}
59 changes: 44 additions & 15 deletions src/cutter/PreviewPanel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $ from 'jquery';
import JSZip from 'jszip';

import Rect from '../spritecow/Rect';
import InlineEdit from '../spritecow/InlineEdit';

class PreviewPanel {
Expand All @@ -16,8 +16,8 @@ class PreviewPanel {
this.$exportButton = this.$settings.find('#exportButton');

this.$spriteCanvas = spriteCanvas.canvas;
this.fileName = 'sprite.png';
this.rect = new Rect(0, 0, 0, 0);
this.fileName = 'sprite';
this.selectedSprites = [];
this._addEditEvents();

this.$exportButton.on('click', this.handleExport.bind(this));
Expand Down Expand Up @@ -48,17 +48,18 @@ class PreviewPanel {

$('<div class="panel-title">Settings</div>').appendTo(container);
$('<div>Name: <span id="fileName" data-inline-edit="file-name"/></div><br/>').appendTo(container);
$('<div><span id="selectedSpritesCount">0</span> sprite(s) selected!</div>').appendTo(container);
$('<div><input id="exportButton" type="button" value="Export" title="Export the selected sprite"></div>').appendTo(container);

return container;
}

update() {
var rect = this.rect;
var rect = this.selectedSprites[this.selectedSprites.length - 1].rect;
const previewCanvas = this.$previewCanvas;
const hiddenCanvas = this.$hiddenExportingCanvas;

this.$settings.find('#fileName').text(this.fileName);
this.$settings.find('#selectedSpritesCount').text(this.selectedSprites.length);
this.$properties.find('#topX').val(rect.x);
this.$properties.find('#topY').val(rect.y);
this.$properties.find('#width').val(rect.width);
Expand All @@ -71,27 +72,55 @@ class PreviewPanel {
this.$spriteCanvas, rect.x, rect.y, rect.width, rect.height,
0, 0, previewCanvas.width, previewCanvas.height
);
};

handleExport() {
if(this.selectedSprites.length > 1) {
this.createZipExport().then(base64 => {
const dataUrl = "data:application/zip;base64," + base64;
this.downloadExport(dataUrl, '.zip');
});
} else {
const image = this.createImageData(this.selectedSprites[0]);
this.downloadExport(image, '.png');
}
}

downloadExport(dataUrl, ext) {
var link = document.createElement('a');
link.download = this.fileName + ext;
link.href = dataUrl;

document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

// we need a hidden canvas that will always match the current selected sprite's height/width so when exporting it is the correct size
createImageData(sprite) {
const rect = sprite.rect;
const hiddenCanvas = this.$hiddenExportingCanvas;
const hiddenCanvasContext = hiddenCanvas.getContext('2d');

hiddenCanvasContext.clearRect(0, 0, hiddenCanvas.width, hiddenCanvas.height);
hiddenCanvas.width = rect.width;
hiddenCanvas.height = rect.height;
hiddenCanvasContext.drawImage(
this.$spriteCanvas, rect.x, rect.y, rect.width, rect.height,
0, 0, hiddenCanvas.width, hiddenCanvas.height
);
};

handleExport() {
const image = this.$hiddenExportingCanvas.toDataURL("image/png");
var link = document.createElement('a');
link.download = this.fileName;
link.href = image;
return hiddenCanvas.toDataURL("image/png");
}

document.body.appendChild(link);
link.click();
document.body.removeChild(link);
createZipExport() {
var zip = new JSZip();

this.selectedSprites.forEach((sprite, i) => {
const base64Image = this.createImageData(sprite).split(';base64,')[1];
zip.file(`${i}.png`, base64Image, {base64: true});
});

return zip.generateAsync({type:"base64"});
}

_addEditEvents() {
Expand Down
6 changes: 1 addition & 5 deletions src/spritecow/SpriteCanvasView.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,6 @@ class SpriteCanvasView {

var SpriteCanvasViewProto = SpriteCanvasView.prototype = new MicroEvent;

SpriteCanvasViewProto._setCurrentRect = function(rect) {
this.trigger('rectChange', rect);
};

SpriteCanvasViewProto._handleSelectedSprite = function(clickedRect, spriteRect) {
if(isKeyDown(SHIFT_KEY)) {
const alreadySelectedSpriteIndex = this._selectedSprites.findIndex(sprite => JSON.stringify(sprite.rect) == JSON.stringify(spriteRect));
Expand All @@ -281,7 +277,7 @@ SpriteCanvasViewProto._handleSelectedSprite = function(clickedRect, spriteRect)
this._selectedSprites = [this._selectSprite(clickedRect, spriteRect)];
}

this._setCurrentRect(spriteRect);
this.trigger('selectedSpritesChange', this._selectedSprites);
}

SpriteCanvasViewProto._selectSprite = function(clickedRect, spriteRect) {
Expand Down
22 changes: 14 additions & 8 deletions src/spritecow/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,22 @@ import PreviewPanel from '../cutter/PreviewPanel';
pageLayout.toAppView();
});

spriteCanvasView.bind('rectChange', function(rect) {
previewPanel.rect = rect;
spriteCanvasView.bind('selectedSpritesChange', function(selectedSprites) {
if(selectedSprites.length === 0) {
return;
}

previewPanel.selectedSprites = selectedSprites;
previewPanel.update();

if (rect.width === spriteCanvas.canvas.width && rect.height === spriteCanvas.canvas.height) {
// if the rect is the same size as the whole canvas,
// it's probably because the background is set wrong
// let's be kind...
toolbarTop.feedback( 'Incorrect background colour set?', true );
}
selectedSprites.forEach(({rect}) => {
if (rect.width === spriteCanvas.canvas.width && rect.height === spriteCanvas.canvas.height) {
// if the rect is the same size as the whole canvas,
// it's probably because the background is set wrong
// let's be kind...
toolbarTop.feedback( 'Incorrect background colour set?', true );
}
});
});

spriteCanvasView.bind('bgColorHover', function(color) {
Expand Down
26 changes: 24 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2802,6 +2802,11 @@ ieee754@^1.1.4:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==

immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==

import-fresh@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
Expand Down Expand Up @@ -3227,6 +3232,16 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"

jszip@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
dependencies:
lie "~3.3.0"
pako "~1.0.2"
readable-stream "~2.3.6"
setimmediate "^1.0.5"

kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
Expand Down Expand Up @@ -3259,6 +3274,13 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"

lie@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
dependencies:
immediate "~3.0.5"

lodash.clone@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
Expand Down Expand Up @@ -3686,7 +3708,7 @@ pako@^0.2.5:
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=

pako@~1.0.5:
pako@~1.0.2, pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
Expand Down Expand Up @@ -4658,7 +4680,7 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"

setimmediate@^1.0.4:
setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
Expand Down

0 comments on commit a7d9c62

Please sign in to comment.