Skip to content

Commit 36ffd7b

Browse files
Aditya SarnaAditya Sarna
authored andcommitted
feat(menu): add Export as PNG using html2canvas
1 parent 1a5d7f4 commit 36ffd7b

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

frontend/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
"sass": "^1.50.0",
3434
"typescript": "^4.1.2",
3535
"web-vitals": "^1.0.1"
36+
,
37+
"html2canvas": "^1.4.1"
3638
},
3739
"scripts": {
3840
"start": "PORT=4000 react-scripts start",
@@ -62,3 +64,4 @@
6264
"@types/lodash.clonedeep": "^4.5.9"
6365
}
6466
}
67+

frontend/src/components/menu/index.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AppBar, Button, Toolbar, useTheme } from '@material-ui/core';
22
import { ClickEvent, Menu, MenuItem, SubMenu } from '@szhsin/react-menu';
3+
import html2canvas from 'html2canvas';
34
import React, { ChangeEvent } from 'react';
45
import logo from '../../assets/images/logo.png';
56
import { PROJECT_FILE_EXTENSION } from '../../core/constants';
@@ -196,6 +197,33 @@ function MenuBar(props: MenuBarProps) {
196197
}
197198
}
198199

200+
/**
201+
* Export the current canvas as a PNG image.
202+
* Captures the element with id 'canvas-container' using html2canvas and triggers a download.
203+
*/
204+
const exportAsPNG = (_event: ClickEvent) => {
205+
const container = document.getElementById('canvas-container');
206+
if (!container) {
207+
alert('Canvas area not found.');
208+
return;
209+
}
210+
// Use promise chain so handler remains synchronous for the menu component
211+
html2canvas(container as HTMLElement, { backgroundColor: null })
212+
.then((canvas: HTMLCanvasElement) => {
213+
const url = canvas.toDataURL('image/png');
214+
const link = document.createElement('a');
215+
link.href = url;
216+
link.download = editor.getName() + '.png';
217+
document.body.appendChild(link);
218+
link.click();
219+
document.body.removeChild(link);
220+
})
221+
.catch((err: any) => {
222+
console.error('Error exporting canvas as PNG:', err);
223+
alert('Could not export canvas as PNG. See console for details.');
224+
});
225+
}
226+
199227
/**
200228
* Recursive helper function to generate menu options for the Blocks menu.
201229
* @param blocks Map containing Blocks menu structure
@@ -235,6 +263,7 @@ function MenuBar(props: MenuBarProps) {
235263
<MenuItem onClick={saveBlock}>Save Block</MenuItem>
236264
<MenuItem onClick={addAsBlock}>Add as block</MenuItem>
237265
<MenuItem onClick={buildAndDownload}>Build and Download</MenuItem>
266+
<MenuItem onClick={exportAsPNG}>Export as PNG</MenuItem>
238267
</Menu>
239268
<Menu
240269
menuButton={<Button className='menu-button'>Edit</Button>}

0 commit comments

Comments
 (0)