Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
refactor: export to png
Browse files Browse the repository at this point in the history
  • Loading branch information
TheReincarnator authored and Jumace committed Apr 19, 2018
1 parent b580efb commit 2b07559
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 61 deletions.
115 changes: 54 additions & 61 deletions src/electron/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,38 @@ import {
} from 'electron';
import { ElementLocationCommand } from '../store/command/element-location-command';
import * as FileExtraUtils from 'fs-extra';
import { Page } from '../store/page/page';
import { PageElement } from '../store/page/page-element';
import * as PathUtils from 'path';
import { PngExporter } from '../export/png-exporter';
import * as ProcessUtils from 'process';
import { Store } from '../store/store';
const { screen, Menu, shell, app, dialog } = remote;
const { Menu, shell, app, dialog } = remote;

function getPageFileName(): string {
return (Store.getInstance().getCurrentPage() as Page).getName();
}

function querySaveFilePath(
title: string,
typeName: string,
defaultName: string,
extension: string,
callback: (path: string) => void
): void {
dialog.showSaveDialog(
{
title,
defaultPath: `${defaultName}.${extension}`,
filters: [{ name: typeName, extensions: [extension] }]
},
path => {
if (path) {
callback(path);
}
}
);
}

export function createMenu(): void {
const store = Store.getInstance();
Expand Down Expand Up @@ -90,6 +117,32 @@ export function createMenu(): void {
{
type: 'separator'
},
{
label: '&Export',
submenu: [
{
label: 'Export page as PNG',
enabled: !isSplashscreen,
click: () => {
const pageFileName = getPageFileName();
querySaveFilePath(
'Export PNG as',
'PNG Image',
pageFileName,
'png',
(path: string) => {
const webview = document.getElementById('preview') as WebviewTag;
PngExporter.exportToPng(path, webview);
}
);
}
}
]
},
{
type: 'separator',
visible: process.platform !== 'darwin'
},
{
label: 'Se&ttings',
visible: process.platform !== 'darwin',
Expand All @@ -98,66 +151,6 @@ export function createMenu(): void {
shell.openItem(store.getPreferencesPath());
}
},
{
label: 'Export page as PNG',
enabled: !isSplashscreen,
click: () => {
const webview = document.getElementById('preview') as WebviewTag;

// code that gets executed inside the webview to get
// the actual size of the preview body
const code = `
bodyTag = document.querySelector('body');
r = {};
r.pageHeight = bodyTag.getBoundingClientRect().height;
r.pageWidth = bodyTag.getBoundingClientRect().width;
r;
`;

webview.executeJavaScript(code, false, webviewSize => {
// set the height of the webview tag to the preview body height
// This is needed because capturePage can not capture anything that renders
// outside the webview area (https://github.com/electron/electron/issues/9845)
webview.style.height = webviewSize.pageHeight;

// Delay the page capture to make sure that the style height changes are done.
// This is only needed because of the change in height in the above line
setTimeout(() => {
const scaleFactor = screen.getPrimaryDisplay().scaleFactor;
webview.capturePage(
{
x: 0,
y: 0,
// round the numbers to remove possible floating numbers
// also multiply by scaleFactor for devices with higher pixel ratio:
// https://github.com/electron/electron/issues/8314
width: Math.round(webviewSize.pageWidth * scaleFactor),
height: Math.round(webviewSize.pageHeight * scaleFactor)
},
capture => {
const pngBuffer: Buffer = capture.toPNG();

dialog.showSaveDialog(
{
filters: [{ name: 'Untitled', extensions: ['png'] }]
},
filename => {
// reset the webview height
webview.style.height = '100%';

if (!filename) {
return;
}

FileExtraUtils.writeFileSync(filename, pngBuffer);
}
);
}
);
}, 100);
});
}
},
{
type: 'separator',
visible: process.platform !== 'darwin'
Expand Down
47 changes: 47 additions & 0 deletions src/export/png-exporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { remote, WebviewTag } from 'electron';
import * as FileExtraUtils from 'fs-extra';

export class PngExporter {
public static exportToPng(path: string, webview: WebviewTag): void {
// code that gets executed inside the webview to get
// the actual size of the preview body
const code = `
bodyTag = document.querySelector('body');
({
pageHeight: bodyTag.getBoundingClientRect().height,
pageWidth: bodyTag.getBoundingClientRect().width
});
`;

webview.executeJavaScript(code, false, webviewSize => {
// set the height of the webview tag to the preview body height
// This is needed because capturePage can not capture anything that renders
// outside the webview area (https://github.com/electron/electron/issues/9845)
webview.style.height = webviewSize.pageHeight;

// Delay the page capture to make sure that the style height changes are done.
// This is only needed because of the change in height in the above line
setTimeout(() => {
const scaleFactor = remote.screen.getPrimaryDisplay().scaleFactor;
webview.capturePage(
{
x: 0,
y: 0,
// round the numbers to remove possible floating numbers
// also multiply by scaleFactor for devices with higher pixel ratio:
// https://github.com/electron/electron/issues/8314
width: Math.round(webviewSize.pageWidth * scaleFactor),
height: Math.round(webviewSize.pageHeight * scaleFactor)
},
capture => {
const pngBuffer: Buffer = capture.toPNG();
FileExtraUtils.writeFileSync(path, pngBuffer);

// reset the webview height
webview.style.height = '100%';
}
);
}, 100);
});
}
}

0 comments on commit 2b07559

Please sign in to comment.