我使用AngularJS预取缓存客户端中的图像,然后我想为这些预取图像设置动画。
我的预取代码:
$scope.prefetch=function(limit) {
for (var i=0; i<limit; i++) {
var date = new Date($scope.dt);
if ($scope.fileFlag == false) {
if ($scope.viewmodel.timeResolution == 'yearly')
date = new Date(date.setFullYear(date.getFullYear() + i));
else if ($scope.viewmodel.timeResolution == 'monthly')
date = new Date(date.setMonth(date.getMonth() + i));
else if ($scope.viewmodel.timeResolution == 'daily') {
date = new Date(date.setDate(date.getDate() + i));
}
} else {
date = $scope.files[$scope.files.indexOf($scope.idSelectedVote) + i];
}
console.log( $http.get(site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + date + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap, {'cache': true}));
}
};
然后我做这样的事情来播放这些图像
$scope.play=function(limit) {
for (var i=0; i<limit; i++) {
$scope.map.src= site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
$scope.sleepFor(500);
}
};
$scope.sleepFor = function( sleepDuration ) {
var now = new Date().getTime();
while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
}
我的问题是当我拨打play(4)
时,它只显示第一张和最后一张图片,而不是动画。有关如何改进此代码或不同方法的任何想法,以便我可以做到这一点?
答案 0 :(得分:4)
你的sleepFor
是一个空闲的循环:你旋转并且什么也不做,但你阻止任何其他的工作完成。这不是Javascript在一段时间内延迟工作的方式,也不是安排函数在以后运行的方式。在Javascript中我们使用window.setTimeout
- 在Angular中,我们提供了方便的$timeout
服务来提供:
$scope.play = function(limit) {
for (var i=0; i < limit; i++) {
$scope.map.src = site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
var nextFrameMs = 500;
$timeout($scope.play, nextFrameMs);
}
};
在您的示例中,只要向您提供$scope
- 假设这是在控制器中,您将有一些像module.controller($scope, ...)
这样的行 - 您必须注入$timeout
服务能够使用它。
其他资源:
答案 1 :(得分:2)
您必须使用间隔,否则您的代码将阻止执行其他代码
使用Angular的内置$interval
服务是解决方案:
var playInterval;
$scope.play = function(limit) {
var interval = 1000 / 20; //20 frames per second
var i = 0;
$interval.cancel(playInterval); //stop previous animations if any
if(i < limit) {
$scope.map.src = getSrc(i++);
var cache = $interval(function() {
if(i >= limit) {
return $interval.cancel(playInterval); //or you can replace with `i = 0;` to loop the animation
}
$scope.map.src = getSrc(i++);
}, interval);
}
};
function getSrc(i) {
return site_url + "mwf/" + $scope.viewmodel.dataSet + "/" + $scope.viewmodel.varName + "/" + $scope.viewmodel.region + "/" + parseInt(date)+i + "/map/?vMin=" + $scope.VMin + "&vMax=" + $scope.VMax + "&type=" + $scope.viewmodel.type + "&cmap=" + $scope.viewmodel.colorMap;
}