簡體   English   中英

使用Canvas和ForEach處理異步呼叫

[英]Handling Async Calls with Canvas and ForEach

我試圖了解如何利用angular的$ q庫顯示基於畫布繪圖的圖像,然后使用.toDataURL()進行轉換;

基本上我想:

  1. 循環$scope.targetImages圖像( $scope.targetImages
  2. 畫在畫布上
  3. 使用.toDataURL()將它們轉換為圖像,並將其存儲在( $scope.outputImages );中。
  4. 使用ng-repeat顯示圖像

問題在於,函數.toDataURL()在執行之前可能需要花費一些時間,從而導致步驟4的延遲調用,因此什么也不顯示。

我嘗試了以下方法,但是在轉換所有圖像之前仍可以解決。

現在,當我第二次調用drawCanvas ()時,將顯示圖像。

    // 1
    $scope.targetImages= {}

    drawCanvas().then(function(data){
      console.log("done: " + new Date())
      console.log(data)
      $scope.outputImages = data;
      $scope.previewMode = false; // switch views, display canvas, remove preview
    });


    function drawCanvas() {

    var defer = $q.defer();

    var targetImages = {} 
    angular.forEach($scope.targetImages , function(imageObj, key) {

      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      var img = new Image();
      img.src = imageObj.nativeURL;
      img.onload = start

      // 2
      function start() {

        ctx.drawImage(img, 0, 0, img.width, img.height);

        outputImages[key] = {
          IID: key,
          dataURL: canvas.toDataURL()
        }

      } // start

    }); // for loop target images

    defer.resolve(outputImages);
    return defer.promise;

    } // draw canvas

並顯示為:

<img ng-show="!previewMode" ng-src="{{image.dataURL || ''}}" style="width: 100vw; max-width: 600px;">

首先,定義一個將圖像繪制到畫布上並返回結果承諾的函數:

function drawToCanvas(nativeURL) {
    return $q(function (resolve) {
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        var img = new Image();

        img.src = nativeURL;
        img.onload = function () {
            ctx.drawImage(img, 0, 0, img.width, img.height);

            resolve(canvas.toDataURL());
        };
    });
}

然后,解決方案變為:

$scope.targetImages = [];

function drawCanvas() {
    // pResults is an array of promises
    var pResults = $scope.targetImages.map(function (imageObj) {
        return drawToCanvas(imageObj.nativeURL);
    });

    return $q.all(pResults);
}

drawCanvas().then(function(data) {
    // data is an array of imageUrls
    console.log("done: " + new Date())
    console.log(data)
    $scope.outputImages = data;
    $scope.previewMode = false; 
    // switch views, display canvas, remove preview
});

為簡化起見,我已將$scope.targetImages$scope.outputImages更改為數組而不是對象,但是如果您需要的話,不難再回到為它們使用對象的角度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM