Skip to content

Commit 576f448

Browse files
authored
Exporting Blocks artwork in PNG (#4280)
* Update toolbar.js for PNG saver * Update activity.js PNG saver * Update index.html for adding new link for exporting as png * Update toolbar.js * creating fun printBlockPng * Update SaveInterface.js calling block artwork png * Removing extra Spaces * Update activity.js * Update activity.js
1 parent fe273d0 commit 576f448

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,7 @@
890890
<li><a id="save-ly"></a></li>
891891
<li><a id="save-mxml"></a></li>
892892
<li><a id="save-blockartwork-svg"></a></li>
893+
<li><a id="save-blockartwork-png"></a></li>
893894
</ul>
894895

895896
<ul id="languagedropdown" class="dropdown-content">

js/SaveInterface.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,20 @@ class SaveInterface {
311311
const svg = "data:image/svg+xml;utf8," + activity.printBlockSVG();
312312
activity.save.download("svg", svg, null);
313313
}
314+
315+
/**
316+
* This method is to save BlockArtwork and download the PNG representation of block artwork from the provided activity.
317+
*
318+
* @param {SaveInterface} activity - The activity object containing block artwork to save.
319+
* @returns {void}
320+
* @method
321+
* @instance
322+
*/
323+
saveBlockArtworkPNG(activity) {
324+
activity.printBlockPNG().then((pngDataUrl) => {
325+
activity.save.download("png", pngDataUrl, null);
326+
})
327+
}
314328

315329
/**
316330
* Save audio recording in WAV format.

js/activity.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,44 @@ class Activity {
10521052
encodeURIComponent(svg)
10531053
);
10541054
};
1055+
1056+
/**
1057+
* @returns {PNG} returns PNG of block artwork
1058+
*/
1059+
this.printBlockPNG = async () => {
1060+
// Setps to convert the SVG to PNG of BlockArtwork
1061+
// Step 1: Generate the SVG content
1062+
// Step 2: Create a Canvas element
1063+
// Step 3: Convert SVG to an Image object
1064+
// Step 4: Draw SVG on the Canvas and export as PNG
1065+
1066+
const svgContent = this.printBlockSVG();
1067+
const canvas = document.createElement('canvas');
1068+
const ctx = canvas.getContext('2d');
1069+
const parser = new DOMParser();
1070+
const svgDoc = parser.parseFromString(decodeURIComponent(svgContent), "image/svg+xml");
1071+
const svgElement = svgDoc.documentElement;
1072+
const width = parseInt(svgElement.getAttribute('width'), 10);
1073+
const height = parseInt(svgElement.getAttribute('height'), 10);
1074+
canvas.width = width;
1075+
canvas.height = height;
1076+
const img = new Image();
1077+
const svgBlob = new Blob([decodeURIComponent(svgContent)], { type: "image/svg+xml;charset=utf-8" });
1078+
const url = URL.createObjectURL(svgBlob);
1079+
return new Promise((resolve, reject) => {
1080+
img.onload = () => {
1081+
ctx.drawImage(img, 0, 0);
1082+
URL.revokeObjectURL(url);
1083+
const pngDataUrl = canvas.toDataURL("image/png");
1084+
resolve(pngDataUrl);
1085+
};
1086+
img.onerror = (err) => {
1087+
URL.revokeObjectURL(url);
1088+
reject(err);
1089+
};
1090+
img.src = url;
1091+
});
1092+
};
10551093

10561094
/*
10571095
* Clears "canvas"
@@ -1525,7 +1563,8 @@ class Activity {
15251563
activity.save.afterSaveLilypondLY.bind(activity.save),
15261564
activity.save.saveAbc.bind(activity.save),
15271565
activity.save.saveMxml.bind(activity.save),
1528-
activity.save.saveBlockArtwork.bind(activity.save)
1566+
activity.save.saveBlockArtwork.bind(activity.save),
1567+
activity.save.saveBlockArtworkPNG.bind(activity.save)
15291568
);
15301569

15311570
// Regenerate palettes
@@ -6645,7 +6684,8 @@ class Activity {
66456684
this.save.saveLilypond.bind(this.save),
66466685
this.save.saveAbc.bind(this.save),
66476686
this.save.saveMxml.bind(this.save),
6648-
this.save.saveBlockArtwork.bind(this.save)
6687+
this.save.saveBlockArtwork.bind(this.save),
6688+
this.save.saveBlockArtworkPNG.bind(this.save)
66496689
);
66506690
this.toolbar.renderPlanetIcon(this.planet, doOpenSamples);
66516691
this.toolbar.renderMenuIcon(showHideAuxMenu);

js/toolbar.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class Toolbar {
8585
["save-ly", _("Save sheet music as Lilypond"), "innerHTML"],
8686
["save-mxml", _("Save sheet music as MusicXML"), "innerHTML"],
8787
["save-blockartwork-svg", _("Save block artwork as SVG"), "innerHTML"],
88+
["save-blockartwork-png", _("Save block artwork as PNG"), "innerHTML"],
8889
["new-project", _("Confirm"), "innerHTML"],
8990
["enUS", _("English (United States)"), "innerHTML"],
9091
["enUK", _("English (United Kingdom)"), "innerHTML"],
@@ -144,6 +145,7 @@ class Toolbar {
144145
_("Save sheet music as ABC"),
145146
_("Save sheet music as Lilypond"),
146147
_("Save block artwork as SVG"),
148+
_("Save block artwork as PNG"),
147149
_("Confirm"),
148150
_("Select language"),
149151
_("Save project as HTML"),
@@ -152,6 +154,7 @@ class Toolbar {
152154
_("Save turtle artwork as SVG"),
153155
_("Save turtle artwork as PNG"),
154156
_("Save block artwork as SVG"),
157+
_("Save block artwork as PNG"),
155158
_("Confirm"),
156159
_("English (United States)"),
157160
_("English (United Kingdom)"),
@@ -208,6 +211,7 @@ class Toolbar {
208211
["save-svg", _("Save turtle artwork as SVG"), "innerHTML"],
209212
["save-png", _("Save turtle artwork as PNG"), "innerHTML"],
210213
["save-blockartwork-svg", _("Save block artwork as SVG"), "innerHTML"],
214+
["save-blockartwork-png", _("Save block artwork as PNG"), "innerHTML"],
211215
["new-project", _("Confirm"), "innerHTML"],
212216
["enUS", _("English (United States)"), "innerHTML"],
213217
["enUK", _("English (United Kingdom)"), "innerHTML"],
@@ -265,6 +269,7 @@ class Toolbar {
265269
_("Save turtle artwork as SVG"),
266270
_("Save turtle artwork as PNG"),
267271
_("Save block artwork as SVG"),
272+
_("Save block artwork as PNG"),
268273
_("Confirm"),
269274
_("English (United States)"),
270275
_("English (United Kingdom)"),
@@ -571,7 +576,8 @@ class Toolbar {
571576
ly_onclick,
572577
abc_onclick,
573578
mxml_onclick,
574-
blockartworksvg_onclick
579+
blockartworksvg_onclick,
580+
blockartworkpng_onclick
575581
) {
576582
const saveButton = docById('saveButton');
577583
const saveButtonAdvanced = docById('saveButtonAdvanced');
@@ -681,6 +687,10 @@ class Toolbar {
681687
saveArtworkSVG.onclick = () => {
682688
blockartworksvg_onclick(this.activity);
683689
};
690+
const saveArtworkPNG = docById('save-blockartwork-png');
691+
saveArtworkPNG.onclick = () => {
692+
blockartworkpng_onclick(this.activity);
693+
};
684694
}
685695
}
686696
}

0 commit comments

Comments
 (0)