2015-09-29 16 views
0

我已經構建了一個angularJS應用程序,在此應用程序中,SVG文件表示用戶選擇的服裝。我有一個下載按鈕(當前)將第一個SVG作爲PNG保存到數據庫中,並使用視圖來顯示此「預覽」。將多個SVG保存爲文本,然後獲取數據URLURL

我創建的指令看起來是這樣的:

.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; 
    }; 
}]) 

這對於單個SVG文件工作正常,但現在客戶要求我爲每個標題下的多個SVG執行此操作,他們希望將其全部放在一個PNG中。 我還沒有做很多與canvasing的工作,所以我不知道這是否可以完成。 有誰知道我可能會做到這一點?

+0

只需創建一個變量,你每次都會遞增圖像已經加載並且只有當這個變量=== svgDocs.length-1時才調用toDataURL()。另外,你不需要創建Blob和ObjectUrls來繪製你的svgs,一個簡單的dataURL就足夠了(你可以使用'data:image/svg + xml; charset = utf8'+ encodeURIComponent(new XMLSerializer())。 serializeToString(yourSVGElement))')。 – Kaiido

回答

0

好吧,所以我想出了自己使用承諾。 基本上我創建了一個名爲drawImage的方法,它允許我爲每個SVG繪製圖像。 要確保所有圖像繪製之前,我調用toDataURL我做函數返回一個承諾,一旦圖像加載我解決承諾。 然後,我只是使用$ q.all來獲取dataURL並將數據保存到我的數據庫。 的方法是這樣的:

// 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); 
     }); 

    }) 
}; 

顯然,這裏缺少的代碼,但是這個代碼回答我的問題,剩下的只是讓我的服務工作:)

相關問題