我正在构建一个有动画的应用程序,我需要它更好地工作。我希望能够在指定的动画间隔内完成一系列的div,并一次显示一个。我希望每个系列都有自己的速度和电视。
,这是我到目前为止所拥有的(也复制到下面):http://jsfiddle.net/ollerac/shkq7/
基本上,我在寻找一种将setInterval放在animatedBox属性上的方法,这样我就可以用自定义属性创建一个新的animatedBox。但每次我试着这样做,它都会破裂。
<div ng-app ng-controller="BoxController">
<div class="layer" ng-repeat="layer in animatedBox.layers" ng-style="{ 'backgroundColor': layer.color}" ng-show="layer == animatedBox.selectedLayer"></div>
</div>JAVASCRIPT
function buildBox () {
return {
color: '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
}
}
function BoxController ($scope) {
$scope.animatedBox = {
layers: [],
selectedLayer: null
};
for (var i = 0; i < 5; i++) {
$scope.animatedBox.layers.push(buildBox());
}
var i = -1;
setInterval(function () {
$scope.$apply(function() {
i++;
if (i < $scope.animatedBox.layers.length) {
$scope.animatedBox.displayThisLayer = $scope.animatedBox.layers[i];
} else {
i = 0;
$scope.animatedBox.selectedLayer = $scope.animatedBox.layers[i];
}
});
}, 500);
}CSS
.layer {
width: 30px;
height: 30px;
position: absolute;
}*更新*
下面是我想做的更多事情:
更新的jsFiddle:http://jsfiddle.net/ollerac/shkq7/2/
function buildBox () {
return {
color: '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
}
}
function BoxController ($scope) {
$scope.animatedBox = {
layers: [],
selectedLayer: null,
selectedLayerIndex: -1,
updateSelectedLayer: function () {
var self = this;
if (self.layers.length) {
$scope.$apply(function() {
self.selectedLayerIndex++;
if (self.selectedLayerIndex < self.layers.length) {
self.selectedLayer = self.layers[self.selectedLayerIndex];
} else {
self.selectedLayerIndex = 0;
self.selectedLayer = self.layers[self.selectedLayerIndex];
}
});
}
}
};
for (var i = 0; i < 5; i++) {
$scope.animatedBox.layers.push(buildBox());
}
setInterval(function () {
$scope.animatedBox.updateSelectedLayer();
}, 500);
}因此,现在对象更新自己的selectedLayer属性。,但是,我仍然需要调用单独调用更新的setInterval,以便让它更新。但我希望这个对象能够自我更新,并且完全独立。你能想出个好办法吗因为我真的很困惑.
我想这更像是一个普通的javascript问题,但我认为可能有一种有角度的方法来处理这种情况,比如可能使用指令或其他什么是合适的。
如有任何建议,将不胜感激。
发布于 2013-07-06 17:25:39
你是对的,我相信指令是正确的解决办法。(顺便说一句,这是一个很有趣的工作。:)
当遇到这样的问题时,我通常从编写HTML和控制器开始,如果一切都正常的话,我希望可以编写它们。对于这个例子,下面是我最后得出的结论。
<div ng-controller="BoxController">
<div animated-boxes="colors"></div>
</div>app.value('randomColor', function() {
var red = Math.floor(Math.random() * 255);
var green = Math.floor(Math.random() * 255);
var blue = Math.floor(Math.random() * 255);
return "rgb(" + red + "," + green + "," + blue + ")";
});
app.controller('BoxController', function($scope, randomColor) {
$scope.colors = [ randomColor(), randomColor() ];
});在这里,控制器只负责设置作用域上的一些基本数据--一个颜色数组;DOM非常简单,只将该数组传递给一个名为animated-boxes的数组。randomColor已被移动到服务中,因此可以更容易地重用和测试。(我也对它做了一些修改,这样就不会产生坏的十六进制值。)
现在,唯一不起作用的部分是这个叫做animated-boxes的东西。当您想要与DOM交互或在使用HTML属性时触发某些行为时,我们将转到一个指令。
我们将定义我们的指令,注入$timeout服务,因为我们知道我们想做基于计时器的事情。指令的结果将只是一个对象。
app.directive('animatedBoxes', function($timeout) {
return {
};
});由于我们希望指令是独立的,并且不想搞乱它包含的外部作用域,所以我们将给它一个隔离作用域(请参阅指令文档获取更多信息,但基本上这意味着除了通过我们指定的变量之外,我们没有附加到指令所在的作用域)。
因为我们希望通过HTML属性访问传递给指令的值,所以我们将在该值上设置一个双向作用域绑定;我们将称之为colors。
app.directive('animatedBoxes', function($timeout) {
return {
scope: {
colors: '=animatedBoxes'
}
};
});我们将给它一个简单的模板,它在colors上循环,每种颜色输出一个div。我们的ng-show指出,只有当作用域值selected等于$index时才能显示div,$index是ng-repeat循环当前迭代的数组索引。
app.directive('animatedBoxes', function($timeout) {
return {
scope: {
colors: '=animatedBoxes'
},
template: "<div><div class='layer' ng-repeat='color in colors' " +
"ng-style='{backgroundColor: color}' ng-show='selected == $index'>" +
"</div></div>"
};
});现在是链接函数--处理指令逻辑的函数。首先,我们希望跟踪显示的框;在我们的ng-show中,我们使用了selected。我们还想跟踪我们有多少个盒子;我们将在指令的范围内使用$watch来跟上这个过程。
link: function(scope, elem, attrs) {
scope.selected = 0;
var count = 0;
scope.$watch('colors', function(value) {
// whenever the value of `colors`, which is the array
// of colors passed into the directive, changes, update
// our internal count of colors
if (value) count = value.length;
else count = 0; // if `colors` is falsy, set count to 0
}, true); // `true` ensures we watch the values in the array,
// not just the object reference
}最后,我们需要经常通过每一个盒子。我们将用$timeout来实现这一点,这是setTimeout的一个版本,其中包含了一个范围$apply调用(它做了一些其他的事情,但我们现在并不关心这个问题)。
var nextBox = function() {
if (scope.selected >= count - 1) scope.selected = 0;
else scope.selected++;
// recursively use `$timeout` instead of `setInterval`
$timeout(nextBox, 500);
};
// kick off the directive by launching the first `nextBox`
nextBox();如果将整个指令放在一起,您将得到以下代码(注释已删除):
app.directive('animatedBoxes', function($timeout) {
return {
scope: {
colors: '=animatedBoxes'
},
template: "<div><div class='layer' ng-repeat='color in colors' " +
"ng-style='{backgroundColor: color}' ng-show='selected == $index'>" +
"</div></div>",
link: function(scope, elem, attrs) {
scope.selected = 0;
var count = 0;
scope.$watch('colors', function(value) {
if (value) count = value.length;
else count = 0;
}, true);
var nextBox = function() {
if (scope.selected >= count - 1) scope.selected = 0;
else scope.selected++;
$timeout(nextBox, 500);
};
nextBox();
}
};
});一个完整的工作示例,包括注释和一个小的调试区域,您可以在这里看到colors的值并与其交互(因此您可以看到指令如何响应控制器中的更改),可以在这里找到:http://jsfiddle.net/BinaryMuse/g6A6Y/。
现在您已经具备了这个功能,请考虑应用这些知识,通过DOM传递指令,使其具有可变的速度,就像我们在colors中所做的那样。这是我的结果:http://jsfiddle.net/BinaryMuse/cHHKn/
https://stackoverflow.com/questions/17503975
复制相似问题