Skip to content

Commit

Permalink
Exporting Blocks artwork in PNG (#4280)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
omsuneri authored Jan 21, 2025
1 parent fe273d0 commit 576f448
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@
<li><a id="save-ly"></a></li>
<li><a id="save-mxml"></a></li>
<li><a id="save-blockartwork-svg"></a></li>
<li><a id="save-blockartwork-png"></a></li>
</ul>

<ul id="languagedropdown" class="dropdown-content">
Expand Down
14 changes: 14 additions & 0 deletions js/SaveInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,20 @@ class SaveInterface {
const svg = "data:image/svg+xml;utf8," + activity.printBlockSVG();
activity.save.download("svg", svg, null);
}

/**
* This method is to save BlockArtwork and download the PNG representation of block artwork from the provided activity.
*
* @param {SaveInterface} activity - The activity object containing block artwork to save.
* @returns {void}
* @method
* @instance
*/
saveBlockArtworkPNG(activity) {
activity.printBlockPNG().then((pngDataUrl) => {
activity.save.download("png", pngDataUrl, null);
})
}

/**
* Save audio recording in WAV format.
Expand Down
44 changes: 42 additions & 2 deletions js/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,44 @@ class Activity {
encodeURIComponent(svg)
);
};

/**
* @returns {PNG} returns PNG of block artwork
*/
this.printBlockPNG = async () => {
// Setps to convert the SVG to PNG of BlockArtwork
// Step 1: Generate the SVG content
// Step 2: Create a Canvas element
// Step 3: Convert SVG to an Image object
// Step 4: Draw SVG on the Canvas and export as PNG

const svgContent = this.printBlockSVG();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const parser = new DOMParser();
const svgDoc = parser.parseFromString(decodeURIComponent(svgContent), "image/svg+xml");
const svgElement = svgDoc.documentElement;
const width = parseInt(svgElement.getAttribute('width'), 10);
const height = parseInt(svgElement.getAttribute('height'), 10);
canvas.width = width;
canvas.height = height;
const img = new Image();
const svgBlob = new Blob([decodeURIComponent(svgContent)], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svgBlob);
return new Promise((resolve, reject) => {
img.onload = () => {
ctx.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
const pngDataUrl = canvas.toDataURL("image/png");
resolve(pngDataUrl);
};
img.onerror = (err) => {
URL.revokeObjectURL(url);
reject(err);
};
img.src = url;
});
};

/*
* Clears "canvas"
Expand Down Expand Up @@ -1525,7 +1563,8 @@ class Activity {
activity.save.afterSaveLilypondLY.bind(activity.save),
activity.save.saveAbc.bind(activity.save),
activity.save.saveMxml.bind(activity.save),
activity.save.saveBlockArtwork.bind(activity.save)
activity.save.saveBlockArtwork.bind(activity.save),
activity.save.saveBlockArtworkPNG.bind(activity.save)
);

// Regenerate palettes
Expand Down Expand Up @@ -6645,7 +6684,8 @@ class Activity {
this.save.saveLilypond.bind(this.save),
this.save.saveAbc.bind(this.save),
this.save.saveMxml.bind(this.save),
this.save.saveBlockArtwork.bind(this.save)
this.save.saveBlockArtwork.bind(this.save),
this.save.saveBlockArtworkPNG.bind(this.save)
);
this.toolbar.renderPlanetIcon(this.planet, doOpenSamples);
this.toolbar.renderMenuIcon(showHideAuxMenu);
Expand Down
12 changes: 11 additions & 1 deletion js/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class Toolbar {
["save-ly", _("Save sheet music as Lilypond"), "innerHTML"],
["save-mxml", _("Save sheet music as MusicXML"), "innerHTML"],
["save-blockartwork-svg", _("Save block artwork as SVG"), "innerHTML"],
["save-blockartwork-png", _("Save block artwork as PNG"), "innerHTML"],
["new-project", _("Confirm"), "innerHTML"],
["enUS", _("English (United States)"), "innerHTML"],
["enUK", _("English (United Kingdom)"), "innerHTML"],
Expand Down Expand Up @@ -144,6 +145,7 @@ class Toolbar {
_("Save sheet music as ABC"),
_("Save sheet music as Lilypond"),
_("Save block artwork as SVG"),
_("Save block artwork as PNG"),
_("Confirm"),
_("Select language"),
_("Save project as HTML"),
Expand All @@ -152,6 +154,7 @@ class Toolbar {
_("Save turtle artwork as SVG"),
_("Save turtle artwork as PNG"),
_("Save block artwork as SVG"),
_("Save block artwork as PNG"),
_("Confirm"),
_("English (United States)"),
_("English (United Kingdom)"),
Expand Down Expand Up @@ -208,6 +211,7 @@ class Toolbar {
["save-svg", _("Save turtle artwork as SVG"), "innerHTML"],
["save-png", _("Save turtle artwork as PNG"), "innerHTML"],
["save-blockartwork-svg", _("Save block artwork as SVG"), "innerHTML"],
["save-blockartwork-png", _("Save block artwork as PNG"), "innerHTML"],
["new-project", _("Confirm"), "innerHTML"],
["enUS", _("English (United States)"), "innerHTML"],
["enUK", _("English (United Kingdom)"), "innerHTML"],
Expand Down Expand Up @@ -265,6 +269,7 @@ class Toolbar {
_("Save turtle artwork as SVG"),
_("Save turtle artwork as PNG"),
_("Save block artwork as SVG"),
_("Save block artwork as PNG"),
_("Confirm"),
_("English (United States)"),
_("English (United Kingdom)"),
Expand Down Expand Up @@ -571,7 +576,8 @@ class Toolbar {
ly_onclick,
abc_onclick,
mxml_onclick,
blockartworksvg_onclick
blockartworksvg_onclick,
blockartworkpng_onclick
) {
const saveButton = docById('saveButton');
const saveButtonAdvanced = docById('saveButtonAdvanced');
Expand Down Expand Up @@ -681,6 +687,10 @@ class Toolbar {
saveArtworkSVG.onclick = () => {
blockartworksvg_onclick(this.activity);
};
const saveArtworkPNG = docById('save-blockartwork-png');
saveArtworkPNG.onclick = () => {
blockartworkpng_onclick(this.activity);
};
}
}
}
Expand Down

0 comments on commit 576f448

Please sign in to comment.