【问题标题】:Electron - Page is refreshed when converting HTML5 canvas to jpegElectron - 将 HTML5 画布转换为 jpeg 时刷新页面
【发布时间】:2018-05-29 07:56:28
【问题描述】:

我有一个使用 Electron 平台 和 Javascript 的桌面应用程序,我在其中使用以下方法将 HTML5 画布转换为 JPEG:

<a id="download" download="Path.jpg">Download JPG</a>

那么,

function download(){ 
    dt = 'data:text/plain,foo'; 
    this.href=dt; }

这刷新了我的整个应用程序。

由于用户在画布上绘图,我不想刷新页面,只允许下载图像,然后用户可以继续在画布上绘图。

关于我做错了什么以及如何改变这种行为的任何指针?

下图是一个屏幕截图,您可以在其中看到画布后面绘制了一个蓝色方块。当我点击保存按钮时,画布和整个页面都会被刷新。

【问题讨论】:

  • 尝试使用您的数据 url 打开一个新的选项卡/窗口,而不是替换当前的 url
  • 你能分享你的画布代码或创建你的sn-p
  • 嗨 @Kaiido 这是一个使用 Electron 平台的桌面应用程序
  • 呵呵,傻我我错过了那部分......当你做function download(){ dt = 'data:text/plain,foo'; this.href=dt;}时也会发生同样的情况吗?如果是这样,您可以删除问题的所有 canvas 和 three.js 部分,因为这将是一个与 canvas、jpeg、three.js 完全无关的 Electron 错误
  • 您是否要在 three.js 中拍摄当前场景的快照?

标签: javascript html electron


【解决方案1】:

我猜您正在尝试拍摄您的 three.js 场景的快照。您可以使用 FileSaver.js 将图像下载到本地计算机。

这里是 FileSaver.js https://github.com/eligrey/FileSaver.js/的链接

在您的代码中包含 FileSaver.js

你所要做的就是,

1) 将画布转换为 dataurl(将为您提供 base64 编码图像)

2) 将base64数据转成blob

3) 将 blob 下载到本地计算机

将base64转换为blob的函数

var base64ToBlob : function( b64Data, contentType, sliceSize ) {
    return new Promise( function( resolve, reject ){
        contentType = contentType || '';
        sliceSize = sliceSize || 512;
        try{
            //converting each byte in the b64Data to a single character using the atob() method.
            var byteCharacters = atob(b64Data);
            var byteArrays = [];
            // a set of 'sliceSize' number of characters are processed at a time. 
            for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
                //slice holds a set of 'sliceSize' number of characters from the byteCharacters array.
                var slice = byteCharacters.slice(offset, offset + sliceSize);   
                //converting each character in 'slice' to the ASCII code.
                var byteNumbers = new Array(slice.length);
                for (var i = 0; i < slice.length; i++) {
                    byteNumbers[i] = slice.charCodeAt(i);
                }
                //creating a typed array structure using the ASCII codes of the characters.
                var byteArray = new Uint8Array(byteNumbers);
                byteArrays.push(byteArray);
            }
            //now byteArrays holds the whole bytes converted to the ASCII character codes
            //convert the typed array to the blob
            var blob = new Blob( byteArrays, { type : contentType } );
            resolve( blob );
        }
        catch( error ){
            reject( error );
        }
    } );
}

像这样改变你的下载功能,

function download() {
    var dt = canvas.toDataURL('image/jpeg');
    //this.href = dt; //this line is causing the page redirection
    base64ToBlob( dt, 'image/png', 512 ).then( function( file ){ 
        FileSaver.saveAs(file, "image.png");//or use just saveAs( file, "image.png" )
    }, function( error ){
        console.log( error );
    } );
}

【讨论】:

  • 这仍然会刷新页面。正如@Kaiido 所说的那样,即使function download(){ dt = 'data:text/plain,foo';} 也会刷新页面,所以这可能与 Electron 有关。
  • 你还在用 this.href = dt 吗?
  • 问题在于 Electron 对 download 属性的实现... FileSaver 在可用时使用此属性,而问题与画布无关。 (当我在这里时,请注意您在 jpeg 和 png 之间混合了 Blob 的 mimetype,并且您实际上在最新的浏览器中不需要这个 base64ToBlob 函数,有一个 canvas.toBlob 方法
  • @Kaiido ,我不知道这是否正确,如果问题出在'a'元素中的下载属性'Download JPG' 如果我们将其更改为按钮并在单击时执行“下载”功能(根据我建议的代码),它会起作用吗?。
  • @HariV FileSaver.js 内部使用&lt;a download&gt; 可用时,这里会可用,所以bug还是会出现。
【解决方案2】:
var anchorEvent = document.getElementById("download");
anchorEvent.addEventListener("click", function () {
    var dt = canvas.toDataURL('image/jpeg');
    this.href = dt;
    event.preventDefault();
});

event.preventDefault();是您的页面不会刷新的原因。它会阻止您使用按钮的默认刷新功能。

【讨论】:

  • OP 想要默认行为:开始下载他们的文件。
  • 好的,我认为页面正在刷新,即使在下载文件之后也是如此。这是因为每当我们附加一个事件监听器时,它的默认行为是在执行功能后刷新。
猜你喜欢
  • 2011-09-01
  • 1970-01-01
  • 2018-11-23
  • 2014-12-31
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
相关资源
最近更新 更多