I am in the process of creating a web interface for an online board game. My goal is to load a Snap.svg map using Snap.load asynchronously.
Once the map is loaded, I intend to attach a watch to a scope property and apply colors to the map based on that property (which is an object). Here's the code snippet:
.controller('GameCtrl', [
'$scope'
'$routeParams'
'GameService'
(
$scope
$routeParams
GameService
) ->
$scope.game = GameService.get($routeParams.gameId)
$scope.map = Snap("#map")
Snap.load("img/classical.svg", (data) ->
console.log "Loaded map!"
data.select("#provinces").attr
style: ""
provinces = data.selectAll("#provinces path")
for province in provinces
province.attr
style: ""
fill: "#FFFFFF"
"fill-opacity": "0"
$scope.map.append(data)
deregisterWatch = $scope.$watch('game', ->
console.debug "Game loaded!", $scope.game.data.Id
for provinceName,unit of $scope.game.data.Phase.Units
provinceName = provinceName.replace '/', '-'
province = $scope.map.select("##{provinceName}")
province.attr
style: ""
fill: powers[unit.Nation].colour
"fill-opacity": "0.8"
deregisterWatch()
)
)
])
My current challenge is how to separate the map into its own "class" or file while still allowing it to access the $scope
for setting the watch after loading.
My initial thought is to extract the map and pass the scope as a parameter:
define([
'snap'
], (
Snap
) ->
'use strict'
Map = ($scope, selector, svgPath) ->
that = {}
that.provinces = {}
...
that.snap = Snap(selector)
Snap.load(svgPath, (data) ->
console.log "Loaded map in Map!"
data.select("#provinces").attr
style: ""
provinces = data.selectAll("#provinces path")
for province in provinces
that.provinces[province.attr("id")] = province
province.attr
style: ""
fill: "#FFFFFF"
"fill-opacity": "0"
that.snap.append(data)
deregisterWatch = $scope.$watch('game', ->
console.debug "Game loaded!", $scope.game.data.Id
for provinceName,unit of $scope.game.data.Phase.Units
provinceName = provinceName.replace '/', '-'
that.colourProvince(provinceName, that.powerColors[unit.Nation].colour)
deregisterWatch()
)
)
that.colourProvince = (abbr, colour) ->
...
return that
return Map
)
I believe there may be a better way to handle this within AngularJS. Should I consider using a directive, or do you have any other suggestions?