我正在建立一个网站来计算网格中两个点之间的最短路径 使用AngularJS。
我已经有了算法,我可以为路径着色,但是我想要在tile(setTimeout(1000))之后对路径进行着色。
在这里进行了长时间的搜索后,我发现了如何在for循环中设置setTime,但是现在只有在鼠标单击后才会改变它们的颜色(不知道为什么)。
示例:第一个瓷砖更改颜色 - > 3秒后&鼠标点击 - > 4块瓷砖改变了颜色。 (等等时间过去了。)
我虽然是因为事件监听器,但我在使用它们之后删除了它们。
编辑:
function colorThePath(tile) {
tile.color = "purple";
}
for (var i = 0; i < shortestPath.length - 1; i++) {
if (shortestPath[i] == 'East') {
$interval(function() {
colorThePath(self.board[self.startTile.x][self.startTile.y + 1])
}, 2000, 1);
self.startTile = self.board[self.startTile.x][self.startTile.y + 1];
} else if (shortestPath[i] == 'South') {
self.board[self.startTile.x + 1][self.startTile.y].color = "purple";
self.startTile = self.board[self.startTile.x + 1][self.startTile.y];
} else if (shortestPath[i] == 'West') {
self.board[self.startTile.x][self.startTile.y - 1].color = "purple";
self.startTile = self.board[self.startTile.x][self.startTile.y - 1];
} else if (shortestPath[i] == 'North') {
self.board[self.startTile.x - 1][self.startTile.y].color = "purple";
self.startTile = self.board[self.startTile.x - 1][self.startTile.y];
}
}
“着色”发生在“go”功能中(在js文件的末尾)。
HTML code:
<!doctype html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>Main</title>
<!-- angular -->
<script src="../scripts/angular.js"></script>
<script type="text/javascript" src="../scripts/angular-ui-router.js"></script>
<!-- Angular Material style sheet -->
<link rel="stylesheet"
href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<!-- Angular Material Library -->
<script
src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
<script type="text/javascript" src="../scripts/MainRoute.js"></script>
<script type="text/javascript" src="../scripts/mainController.js"></script>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="../css/a.css"></link>
</head>
<body ng-controller="mainController as m">
<div id="navBar">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a ng-click="m.start()">Start</a></li>
<li><a ng-click="m.end()">End</a></li>
<li><a ng-click="m.go()">Go!</a></li>
</ul>
</div>
</nav>
</div>
<div>
<table id="table">
<tr ng-repeat="r in m.board">
<td ng-repeat="x in r track by x.id" style="background-color: {{x.color}}" ng-click="m.changeColor(x.id)" id="{{x.id}}">{{x.id}}</td>
</tr>
</table>
</div>
</body>
</html>
JS / Angular Code:
! - begin snippet:js hide:false console:true babel:false - &gt;
(function() {
var module = angular.module("myApp");
module.controller("mainController", mainControllerCTOR)
function mainControllerCTOR() {
this.board;
this.startTile;
this.endTile;
var self = this;
function Tile(x, y) {
this.id = x + "," + y;
this.x = x;
this.y = y;
this.pressed = false;
this.color = "yellow";
this.secret = 'Empty';
}
window.onload = function() {
self.board = [];
for (var i = 0; i < 12; i++) {
self.board[i] = [];
for (var j = 0; j < 12; j++) {
self.board[i][j] = new Tile(i, j);
}
}
}
this.changeColor = function(id) {
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 12; j++) {
if (self.board[i][j].id == id) {
if (self.board[i][j].color == "yellow") {
self.board[i][j].color = "blue";
self.board[i][j].secret = 'Obstacle';
} else {
self.board[i][j].color = 'yellow';
self.board[i][j].secret = 'Empty';
}
}
}
}
}
this.chooseStart = function(event) {
var tile = document.getElementById(event.target.id);
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 12; j++) {
if (self.board[i][j].id == tile.id) {
self.board[i][j].color = "green";
self.board[i][j].secret = 'Start';
self.startTile = self.board[i][j];
}
}
}
tile.innerHTML = "start"
var table = document.getElementById("table");
table.removeEventListener('click', self.chooseStart);
}
this.start = function() {
var table = document.getElementById("table");
table.addEventListener('click', self.chooseStart);
}
this.chooseEnd = function(event) {
var tile = document.getElementById(event.target.id);
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 12; j++) {
if (self.board[i][j].id == tile.id) {
self.board[i][j].color = "red";
self.board[i][j].secret = 'Goal';
self.endTile = self.board[i][j];
}
}
}
tile.innerHTML = "end";
var table = document.getElementById("table");
table.removeEventListener('click', self.chooseEnd);
}
this.end = function() {
var table = document.getElementById("table");
table.addEventListener('click', self.chooseEnd);
}
// =======================================================================
// Breadth-First Search - Greg Trowbridge JS algorithm
// =======================================================================
var findShortestPath = function(startCoordinates, grid) {
var distanceFromTop = startCoordinates[0];
var distanceFromLeft = startCoordinates[1];
var location = {
distanceFromTop : distanceFromTop,
distanceFromLeft : distanceFromLeft,
path : [],
status : 'Start'
};
var queue = [ location ];
while (queue.length > 0) {
var currentLocation = queue.shift();
var newLocation = exploreInDirection(currentLocation, 'North',
grid);
if (newLocation.status === 'Goal') {
return newLocation.path;
} else if (newLocation.status === 'Valid') {
queue.push(newLocation);
}
var newLocation = exploreInDirection(currentLocation, 'East',
grid);
if (newLocation.status === 'Goal') {
return newLocation.path;
} else if (newLocation.status === 'Valid') {
queue.push(newLocation);
}
var newLocation = exploreInDirection(currentLocation, 'South',
grid);
if (newLocation.status === 'Goal') {
return newLocation.path;
} else if (newLocation.status === 'Valid') {
queue.push(newLocation);
}
var newLocation = exploreInDirection(currentLocation, 'West',
grid);
if (newLocation.status === 'Goal') {
return newLocation.path;
} else if (newLocation.status === 'Valid') {
queue.push(newLocation);
}
}
return false;
};
var locationStatus = function(location, grid) {
var gridSize = grid.length;
var dft = location.distanceFromTop;
var dfl = location.distanceFromLeft;
if (location.distanceFromLeft < 0
|| location.distanceFromLeft >= gridSize
|| location.distanceFromTop < 0
|| location.distanceFromTop >= grid.size) {
return 'Invalid';
} else if (grid[dft][dfl] === 'Goal') {
return 'Goal';
} else if (grid[dft][dfl] !== 'Empty') {
return 'Blocked';
} else {
return 'Valid';
}
};
var exploreInDirection = function(currentLocation, direction, grid) {
var newPath = currentLocation.path.slice();
newPath.push(direction);
var dft = currentLocation.distanceFromTop;
var dfl = currentLocation.distanceFromLeft;
if (direction === 'North') {
dft -= 1;
} else if (direction === 'East') {
dfl += 1;
} else if (direction === 'South') {
dft += 1;
} else if (direction === 'West') {
dfl -= 1;
}
var newLocation = {
distanceFromTop : dft,
distanceFromLeft : dfl,
path : newPath,
status : 'Unknown'
};
newLocation.status = locationStatus(newLocation, grid);
if (newLocation.status === 'Valid') {
grid[newLocation.distanceFromTop][newLocation.distanceFromLeft] = 'Visited';
}
return newLocation;
};
// =======================================================================
this.go = function() {
var grid = [];
for (var j = 0; j < 12; j++) {
grid[j] = self.board[j].slice();
}
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 12; j++) {
grid[i][j] = grid[i][j].secret;
}
}
var x = new Number(self.startTile.x);
var y = new Number(self.startTile.y);
var shortestPath = findShortestPath([ x, y ], grid);
console.log(shortestPath);
function colorThePath(i) {
if (shortestPath[i] == 'East') {
self.board[self.startTile.x][self.startTile.y + 1].color = "purple";
self.startTile = self.board[self.startTile.x][self.startTile.y + 1];
} else if (shortestPath[i] == 'South') {
self.board[self.startTile.x + 1][self.startTile.y].color = "purple";
self.startTile = self.board[self.startTile.x + 1][self.startTile.y];
} else if (shortestPath[i] == 'West') {
self.board[self.startTile.x][self.startTile.y - 1].color = "purple";
self.startTile = self.board[self.startTile.x][self.startTile.y - 1];
} else if (shortestPath[i] == 'North') {
self.board[self.startTile.x - 1][self.startTile.y].color = "purple";
self.startTile = self.board[self.startTile.x - 1][self.startTile.y];
}
if (--i > -1) {
setTimeout(function() {
colorThePath(i);
}, 1000);
}
}
colorThePath(shortestPath.length - 1);
};
}
})();
答案 0 :(得分:0)
如果没有检查所有逻辑,Angular摘要循环不会注意到setTimeout触发的事件,你应该使用$ timeout。 https://coderwall.com/p/udpmtq/angularjs-use-timeout-not-settimeout