javascript - 用于创建 Canvas 并下载为图像的 Angular 指令

标签 javascript angularjs

我使用 Angular 1.5.6,我想创建一个 HTML Canvas (不在 DOM 中)并作为图像下载。我是用纯javascript完成的,你可以看到 fiddle here 。 fiddle 代码是:

var canvas = document.createElement("canvas");
canvas.width = 100;
canvas.height = 100;
var ctx = canvas.getContext('2d');

/**
 * Demonstrates how to download a canvas an image with a single
 * direct click on a link.
 */
function doCanvas() {
    /* draw something */
    ctx.fillStyle = '#f90';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#fff';
    ctx.font = '20px sans-serif';
    ctx.fillText('some text', 10, canvas.height / 2 - 15);
}

/**
 * This is the function that will take care of image extracting and
 * setting proper filename for the download.
 * IMPORTANT: Call it from within a onclick event.
*/
function downloadCanvas(link) {
    link.href = canvas.toDataURL();
    link.download = 'test.png';
}

/** 
 * The event handler for the link's onclick event. We give THIS as a
 * parameter (=the link element)
*/
document.getElementById('download').addEventListener('click', function() {
    downloadCanvas(this);
}, false);

/**
 * Draw something to canvas
 */
doCanvas();

但是,我正在努力让它在 Angular 指令中工作。我的指令是:

angular.module('myApp.analyse')
        .directive('export', exportGates);

function exportGates($location) {

    function createCanvas(gates) {

            var canvas = document.createElement("canvas");
            canvas.width = 600;
            canvas.height = 600;
            var ctx = canvas.getContext('2d');

            ctx.fillStyle = '#f90';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = '#fff';
            ctx.font = '20px sans-serif';
            ctx.fillText('some text', 10, canvas.height / 2 - 15);

            return canvas;
    }

    return {
        restrict: 'E',
        templateUrl: 'analyse/directives/export.tpl.html',

        link: function(scope, element, attrs) {

            element.bind('click', function () {

                var canvas = createCanvas(scope.gates);

                element.href = canvas.toDataURL();
                element.download = 'export.png';                        

            });
        }
    }
}

问题似乎是在我的第一个示例中,对 addEventListener 的回调传递了“this”,这是我需要附加 href 和下载属性以在单击时自动下载的链接。我认为我的指令链接方法中的“元素”是我需要附加 href 和下载属性的内容,但显然不是。我怎样才能让它工作?

最佳答案

该元素实际上是 jQLite 元素的实例,它类似于 jQuery 元素,您可以尝试从中找到其中的链接并执行下载过程你的 Canvas 。

但是,我有一个更好的解决方案,不需要现有链接,而是创建您自己的链接并分派(dispatch)对其的点击,甚至无需将其添加到 DOM。

以下代码片段实现了此解决方案。

function saveCanvasAs(canvas, fileName) {
    // get image data and transform mime type to application/octet-stream
    var canvasDataUrl = canvas.toDataURL()
            .replace(/^data:image\/[^;]*/, 'data:application/octet-stream');
    var link = document.createElement('a'); // create an anchor tag

    // set parameters for downloading
    link.setAttribute('href', canvasDataUrl);
    link.setAttribute('target', '_blank');
    link.setAttribute('download', fileName);

    // compat mode for dispatching click on your anchor
    if (document.createEvent) {
        var evtObj = document.createEvent('MouseEvents');
        evtObj.initEvent('click', true, true);
        link.dispatchEvent(evtObj);
    } else if (link.click) {
        link.click();
    }
}

最后,您可以在指令中调用它,如下所示:

...
var canvas = createCanvas(scope.gates);
saveCanvasAs(canvas, 'export.png');
...

关于javascript - 用于创建 Canvas 并下载为图像的 Angular 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40291734/

相关文章:

javascript - 类似 jQuery "isHTML5Error"的函数

javascript - jQuery 多语言脚本

javascript - If 语句 - 如何减少代码量。 (循环?数组?)Javascript

javascript - 如何在不更改标记的情况下隐藏 AngularJS 中的内容

angularjs - Electron + AngularJS View 未找到

javascript - 追加数据时应用程序卡住

javascript - 更改加载图像不适用于多个元素

javascript - Laravel Vue.js 事件未触发

javascript - 注入(inject)第一个 Angular Factory

javascript - 在javascript中合并数组内的数组