Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用文本将多个SVG保存到画布,然后获取数据URL_Javascript_Angularjs_Html_Canvas_Svg - Fatal编程技术网

Javascript 使用文本将多个SVG保存到画布,然后获取数据URL

Javascript 使用文本将多个SVG保存到画布,然后获取数据URL,javascript,angularjs,html,canvas,svg,Javascript,Angularjs,Html,Canvas,Svg,我构建了一个angularJS应用程序,在这个应用程序中,SVG文件表示用户选择的服装。我有一个下载按钮,当前将第一个SVG作为PNG保存到数据库中,我使用一个视图来显示此预览 我创建的指令如下所示: .directive('kdExport', function () { return { restrict: 'A', scope: { target: '@kdExport', team: '='

我构建了一个angularJS应用程序,在这个应用程序中,SVG文件表示用户选择的服装。我有一个下载按钮,当前将第一个SVG作为PNG保存到数据库中,我使用一个视图来显示此预览

我创建的指令如下所示:

.directive('kdExport', function () {

    return {
        restrict: 'A',
        scope: {
            target: '@kdExport',
            team: '='
        },
        controller: 'ExportImageController',
        link: function (scope, element, attrs, controller) {

            console.log(scope.team);

            // Bind to the onclick event of our button
            element.bind('click', function (e) {

                // Prevent the default action
                e.preventDefault();

                // Generate the image
                controller.generateImage(scope.target, scope.team, function (preview) {

                    // Create our url
                    var url = '/kits/preview/' + preview.id;

                    // Open a new window
                    window.open(url, '_blank');
                });
            });
        }
    };
})
.controller('ExportImageController', ['PreviewService', function (service) {
    var self = this;

    // Function to remove the hidden layers of an SVG document
    var removeHidden = function (element) {

        // Get the element children
        var children = element.children(),
            i = children.length;

        // If we have any children
        if (children.length) {

            // For each child
            for (i; i >= 0; i--) {

                // Get our child
                var child = angular.element(children[i - 1]);

                // Remove hidden from the child's children
                removeHidden(child);

                // Finally, if this child has the class "hidden"
                if (child.hasClass("hidden")) {

                    // Remove the child
                    child.remove();
                }
            }
        }
    };

    // Public function to generate the image
    self.generateImage = function (element, team, onSuccess) {

        // Get our SVG
        var target = document.getElementById(element),
            container = target.getElementsByClassName('svg-document')[0],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Create our data
        var data = clone.innerHTML,
            svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

        // Get our context
        var canvas = document.getElementById('canvas'),
            ctx = canvas.getContext('2d');

        // Create our image
        var DOMURL = window.URL || window.webkitURL || window,
            url = DOMURL.createObjectURL(svg),
            img = new Image();

        // When the image has loaded
        img.onload = function () {

            canvas.width = 1000;
            canvas.height = 500;

            // Draw our image using the context
            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 1000, 500);
            DOMURL.revokeObjectURL(url);

            // Get our URL as a base64 string
            var dataURL = canvas.toDataURL("image/png");

            // Create our model
            var model = {
                teamName: team.name,
                sport: team.sport,
                data: dataURL
            };

            // Create our preview
            service.create(model).then(function (response) {

                // Invoke our success callback
                onSuccess(response);
            });
        }

        // Set the URL of the image
        img.src = url;
    };
}])
// Private function for drawing our images
var drawImage = function (canvas, ctx, clone) {

    // Defer our promise
    var deferred = $q.defer();

    // Create our data
    var data = clone.innerHTML,
        svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

    // Create our image
    var DOMURL = window.URL || window.webkitURL || window,
        url = DOMURL.createObjectURL(svg),
        img = new Image();

    // When the image has loaded
    img.onload = function () {

        // Get our location
        getNextLocation(canvas.width, canvas.height, img);

        // Draw our image using the context (Only draws half the image because I don't want to show the back)
        ctx.drawImage(img, 0, 0, img.width / 2, img.height, location.x, location.y, location.width, location.height);
        DOMURL.revokeObjectURL(url);

        // Resolve our promise
        deferred.resolve();
    }

    // Set the URL of the image
    img.src = url;

    // Return our promise
    return deferred.promise;
};

// Public function to generate the image
self.generateImage = function (element, team, onSuccess) {

    // Get our SVG
    var target = document.getElementById('totals'),
        containers = angular.element(target.getElementsByClassName('svg-document'));

    // Get our context
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');

    // Set our canvas height and width
    canvas.width = 2000;
    canvas.height = calculateCanvasHeight(containers.length);

    // Create our array of promises
    var promises = [];

    // For each container
    for (var i = 0; i < containers.length; i++) {

        // Get our container
        var container = containers[i],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Add our promise to the array
        promises.push(drawImage(canvas, ctx, clone));
    }

    // When all promises have resolve
    $q.all(promises).then(function () {

        // Get our URL as a base64 string
        var dataURL = canvas.toDataURL("image/png");

        // Create our model
        var model = {
            teamName: team.name,
            sport: team.sport,
            data: dataURL
        };

        // Create our preview
        self.create(model).then(function (response) {

            // Invoke our success callback
            onSuccess(response);
        });

    })
};
控制器如下所示:

.directive('kdExport', function () {

    return {
        restrict: 'A',
        scope: {
            target: '@kdExport',
            team: '='
        },
        controller: 'ExportImageController',
        link: function (scope, element, attrs, controller) {

            console.log(scope.team);

            // Bind to the onclick event of our button
            element.bind('click', function (e) {

                // Prevent the default action
                e.preventDefault();

                // Generate the image
                controller.generateImage(scope.target, scope.team, function (preview) {

                    // Create our url
                    var url = '/kits/preview/' + preview.id;

                    // Open a new window
                    window.open(url, '_blank');
                });
            });
        }
    };
})
.controller('ExportImageController', ['PreviewService', function (service) {
    var self = this;

    // Function to remove the hidden layers of an SVG document
    var removeHidden = function (element) {

        // Get the element children
        var children = element.children(),
            i = children.length;

        // If we have any children
        if (children.length) {

            // For each child
            for (i; i >= 0; i--) {

                // Get our child
                var child = angular.element(children[i - 1]);

                // Remove hidden from the child's children
                removeHidden(child);

                // Finally, if this child has the class "hidden"
                if (child.hasClass("hidden")) {

                    // Remove the child
                    child.remove();
                }
            }
        }
    };

    // Public function to generate the image
    self.generateImage = function (element, team, onSuccess) {

        // Get our SVG
        var target = document.getElementById(element),
            container = target.getElementsByClassName('svg-document')[0],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Create our data
        var data = clone.innerHTML,
            svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

        // Get our context
        var canvas = document.getElementById('canvas'),
            ctx = canvas.getContext('2d');

        // Create our image
        var DOMURL = window.URL || window.webkitURL || window,
            url = DOMURL.createObjectURL(svg),
            img = new Image();

        // When the image has loaded
        img.onload = function () {

            canvas.width = 1000;
            canvas.height = 500;

            // Draw our image using the context
            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 1000, 500);
            DOMURL.revokeObjectURL(url);

            // Get our URL as a base64 string
            var dataURL = canvas.toDataURL("image/png");

            // Create our model
            var model = {
                teamName: team.name,
                sport: team.sport,
                data: dataURL
            };

            // Create our preview
            service.create(model).then(function (response) {

                // Invoke our success callback
                onSuccess(response);
            });
        }

        // Set the URL of the image
        img.src = url;
    };
}])
// Private function for drawing our images
var drawImage = function (canvas, ctx, clone) {

    // Defer our promise
    var deferred = $q.defer();

    // Create our data
    var data = clone.innerHTML,
        svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

    // Create our image
    var DOMURL = window.URL || window.webkitURL || window,
        url = DOMURL.createObjectURL(svg),
        img = new Image();

    // When the image has loaded
    img.onload = function () {

        // Get our location
        getNextLocation(canvas.width, canvas.height, img);

        // Draw our image using the context (Only draws half the image because I don't want to show the back)
        ctx.drawImage(img, 0, 0, img.width / 2, img.height, location.x, location.y, location.width, location.height);
        DOMURL.revokeObjectURL(url);

        // Resolve our promise
        deferred.resolve();
    }

    // Set the URL of the image
    img.src = url;

    // Return our promise
    return deferred.promise;
};

// Public function to generate the image
self.generateImage = function (element, team, onSuccess) {

    // Get our SVG
    var target = document.getElementById('totals'),
        containers = angular.element(target.getElementsByClassName('svg-document'));

    // Get our context
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');

    // Set our canvas height and width
    canvas.width = 2000;
    canvas.height = calculateCanvasHeight(containers.length);

    // Create our array of promises
    var promises = [];

    // For each container
    for (var i = 0; i < containers.length; i++) {

        // Get our container
        var container = containers[i],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Add our promise to the array
        promises.push(drawImage(canvas, ctx, clone));
    }

    // When all promises have resolve
    $q.all(promises).then(function () {

        // Get our URL as a base64 string
        var dataURL = canvas.toDataURL("image/png");

        // Create our model
        var model = {
            teamName: team.name,
            sport: team.sport,
            data: dataURL
        };

        // Create our preview
        self.create(model).then(function (response) {

            // Invoke our success callback
            onSuccess(response);
        });

    })
};
这对于单个SVG文档很好,但现在客户要求我对多个SVG执行此操作,每个SVG下都有一个标题,他们希望所有SVG都包含在一个PNG中。 我没有做过很多拉票的工作,所以我不确定这是否可以做到。
有人知道我该如何做到这一点吗?

好的,所以我自己用承诺解决了这个问题。 基本上,我创建了一个名为drawImage的方法,该方法允许我为每个SVG绘制一个图像。 为了确保在调用toDataURL之前绘制了所有图像,我让函数返回一个承诺,一旦加载了图像,我就解决了这个承诺。 然后我使用$q.all来获取数据URL并将数据保存到我的数据库中。 方法如下所示:

.directive('kdExport', function () {

    return {
        restrict: 'A',
        scope: {
            target: '@kdExport',
            team: '='
        },
        controller: 'ExportImageController',
        link: function (scope, element, attrs, controller) {

            console.log(scope.team);

            // Bind to the onclick event of our button
            element.bind('click', function (e) {

                // Prevent the default action
                e.preventDefault();

                // Generate the image
                controller.generateImage(scope.target, scope.team, function (preview) {

                    // Create our url
                    var url = '/kits/preview/' + preview.id;

                    // Open a new window
                    window.open(url, '_blank');
                });
            });
        }
    };
})
.controller('ExportImageController', ['PreviewService', function (service) {
    var self = this;

    // Function to remove the hidden layers of an SVG document
    var removeHidden = function (element) {

        // Get the element children
        var children = element.children(),
            i = children.length;

        // If we have any children
        if (children.length) {

            // For each child
            for (i; i >= 0; i--) {

                // Get our child
                var child = angular.element(children[i - 1]);

                // Remove hidden from the child's children
                removeHidden(child);

                // Finally, if this child has the class "hidden"
                if (child.hasClass("hidden")) {

                    // Remove the child
                    child.remove();
                }
            }
        }
    };

    // Public function to generate the image
    self.generateImage = function (element, team, onSuccess) {

        // Get our SVG
        var target = document.getElementById(element),
            container = target.getElementsByClassName('svg-document')[0],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Create our data
        var data = clone.innerHTML,
            svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

        // Get our context
        var canvas = document.getElementById('canvas'),
            ctx = canvas.getContext('2d');

        // Create our image
        var DOMURL = window.URL || window.webkitURL || window,
            url = DOMURL.createObjectURL(svg),
            img = new Image();

        // When the image has loaded
        img.onload = function () {

            canvas.width = 1000;
            canvas.height = 500;

            // Draw our image using the context
            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 1000, 500);
            DOMURL.revokeObjectURL(url);

            // Get our URL as a base64 string
            var dataURL = canvas.toDataURL("image/png");

            // Create our model
            var model = {
                teamName: team.name,
                sport: team.sport,
                data: dataURL
            };

            // Create our preview
            service.create(model).then(function (response) {

                // Invoke our success callback
                onSuccess(response);
            });
        }

        // Set the URL of the image
        img.src = url;
    };
}])
// Private function for drawing our images
var drawImage = function (canvas, ctx, clone) {

    // Defer our promise
    var deferred = $q.defer();

    // Create our data
    var data = clone.innerHTML,
        svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });

    // Create our image
    var DOMURL = window.URL || window.webkitURL || window,
        url = DOMURL.createObjectURL(svg),
        img = new Image();

    // When the image has loaded
    img.onload = function () {

        // Get our location
        getNextLocation(canvas.width, canvas.height, img);

        // Draw our image using the context (Only draws half the image because I don't want to show the back)
        ctx.drawImage(img, 0, 0, img.width / 2, img.height, location.x, location.y, location.width, location.height);
        DOMURL.revokeObjectURL(url);

        // Resolve our promise
        deferred.resolve();
    }

    // Set the URL of the image
    img.src = url;

    // Return our promise
    return deferred.promise;
};

// Public function to generate the image
self.generateImage = function (element, team, onSuccess) {

    // Get our SVG
    var target = document.getElementById('totals'),
        containers = angular.element(target.getElementsByClassName('svg-document'));

    // Get our context
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');

    // Set our canvas height and width
    canvas.width = 2000;
    canvas.height = calculateCanvasHeight(containers.length);

    // Create our array of promises
    var promises = [];

    // For each container
    for (var i = 0; i < containers.length; i++) {

        // Get our container
        var container = containers[i],
            clone = container.cloneNode(true);

        // Remove hidden layers
        removeHidden(angular.element(clone));

        // Add our promise to the array
        promises.push(drawImage(canvas, ctx, clone));
    }

    // When all promises have resolve
    $q.all(promises).then(function () {

        // Get our URL as a base64 string
        var dataURL = canvas.toDataURL("image/png");

        // Create our model
        var model = {
            teamName: team.name,
            sport: team.sport,
            data: dataURL
        };

        // Create our preview
        self.create(model).then(function (response) {

            // Invoke our success callback
            onSuccess(response);
        });

    })
};

显然这里缺少代码,但这段代码回答了我的问题,其余的代码只是让我的服务正常工作:

只需创建一个变量,每次加载图像时都会增加该变量,并且仅当该变量===svgDocs.length-1时才调用toDataURL。此外,您不需要创建blob和objecturl来绘制svg,一个简单的dataURL就足够了,您可以使用“data:image/svg+xml;charset=utf8,“+encodeuricomponent新的XMLSerializer.serializeToStringyourSVGElement。