预加载图像

时间:2014-04-17 20:51:52

标签: javascript angularjs

我想在我的视图结算之前预先加载Angular 中的图像。我正在使用ui-router,所以我假设它看起来像这样:

 $stateProvider
    .state('home', {
        url: '/',
        templateUrl: './views/home.html',
        controller: 'homeCtrl',
        resolve : {
            Images : ['Images', function(Images) {
                return Images.preload();
            }]
        }
    })

Images.preload()中我想预先处理图像对象,这样一旦状态结算就可以使用它。

1 个答案:

答案 0 :(得分:0)

我编写了一个图像预加载器服务,您可以将其用作解析功能的一部分,然后使用"已完成的"回调做你的决心。

projector.factory('imagePreloader', function() {
  var service = {};


  /**
   * To use the service, inject it into your controller then call:
   *
   * imagePreloader.preLoadImages with the following paremeters
   *
   * @param images - a flat array of image URL's
   * @param strategy - "linear" or "parallel" - linear will load one image at a time in the order they appear in the array. Parallel
   *                    will attempt to load all images at once
   * @param finish_cb - function() - the success callback
   * @param status_cb - function(percent_complete, imageDomelement) - a status function that fires after each image has been loaded
   * @param error_cb - function(err) - error handler that will trigger for any errors
   */

  service.preLoadImages = function(images, strategy, finish_cb, status_cb, error_cb) {

    var image_cnt = images.length;
    var loaded_cnt=0;

    var error_handler = function(err) {
      if (typeof(error_cb) == 'function') {
        error_cb( err );
      }
    }

    if (strategy == 'linear') {

      var loadImage;
      var loadImage = function() {

        var image_loaded_cb = function(ev) {
          loaded_cnt++;

          if (typeof(status_cb) == 'function') {
            status_cb( ~~(100 * loaded_cnt / image_cnt), ev.path[0] );
          }

          if (images.length > 0) {
            next();
          }

          if (loaded_cnt == image_cnt) {
            finish_cb();
          }

        }

        var next = function() {
          var imgUrl = images.shift();
          var image = angular.element(new Image()).bind('load', image_loaded_cb )
            .bind('error', error_handler)
            .attr('src', imgUrl)
        }
        next();

      }();

    } else if (strategy =='parallel') {

      var image_loaded_cb = function(ev) {
        loaded_cnt++;
        if (typeof(status_cb) == 'function') {
          status_cb( ~~(100 * loaded_cnt / image_cnt), ev.path[0] );
        }

        if (loaded_cnt == image_cnt) {
          finish_cb();
        }
      }

      angular.forEach(images, function(imgUrl) {

        var image = angular.element(new Image()).bind('load', image_loaded_cb )
          .bind('error', error_handler)
          .attr('src', imgUrl)

      });

    } else {
      throw new Error('Invalid strategy. Should either be "parallel" or "linear"')
    }
  }


  return service;
});

然后使用该服务,您可以像任何其他角度服务/工厂一样使用它:

app.controller('HomeController', function($scope, $http, $timeout, $location, imagePreloader) {



  //testing image preloader

  var images = [
    'https://www.google.com/images/srpr/logo11w.png',
    'https://s.yimg.com/pw/images/sohp_2014/trees_noblur.jpg',
    'http://i2.cdn.turner.com/cnnnext/dam/assets/130419165742-dzhokar-tsarnaev-vk-exlarge-169.jpg'];

  var status_cb = function(status_pct, img) { console.log('Done percent:', status_pct, img )};

  var finish_cb = function() { console.log("All done!"); }

  imagePreloader.preLoadImages(images, 'parallel', finish_cb, status_cb);

});