-
Notifications
You must be signed in to change notification settings - Fork 4
/
gerber-viewer.js
120 lines (95 loc) · 3.23 KB
/
gerber-viewer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
SCALE = 1.; // The scale we render things at. Units are whatever Leaflet uses per millimetre.
// The CRS we use for displaying maps. It's like the Simple CRS but has a scale factor.
L.CRS.SimpleScaled = L.extend({}, L.CRS, {
projection: L.Projection.LonLat,
transformation: new L.Transformation(SCALE, 0, -SCALE, 0),
scale: function (zoom) {
return Math.pow(1.5, zoom);
}
});
// warning and error markers
L.Icon.Warning = L.icon({
iconUrl: 'images/warning.png',
iconSize: [41, 36],
popupAnchor: [0, -16]
});
// warning and error markers
L.Icon.Error = L.icon({
iconUrl: 'images/error.png',
iconSize: [41, 36],
popupAnchor: [0, -16]
});
function boardInfoLoaded() {
// called when the board info XHR updates status
if(this.readyState != 4)
return;
if(this.status != 200)
return;
// at this point we can assume the board info was loaded.
var info = JSON.parse(this.responseText);
var layerObjects = {}, map = this.map;
var layerLoaded = function(l) {
// called when the layer SVG has been loaded.
// check whether all layers have loaded
for(var i in layerObjects) {
if(!layerObjects[i]._loaded)
return;
}
// if so, find the total bounds of the board and zoom to it
var boardBounds = L.latLngBounds([]);
for(var i in layerObjects) {
boardBounds.extend(layerObjects[i].getBounds());
}
map.fitBounds(boardBounds);
}
// add layers
for(var i=0; i<info.layers.length; i++) {
var layer = info.layers[i];
var l = new GerberLayer(i, this.map, layer, layerLoaded);
layerObjects[layer.name] = l;
this.map.addLayer(l);
}
L.control.layers([], layerObjects).addTo(this.map);
for(var i=0; i<info.notes.length; i++) {
var note = info.notes[i];
var item = L.DomUtil.create("li", "note " + note.type, this.notes);
if(!note.pos) {
item.innerHTML = "<b>global " + note.type + ":</b><br>" + note.message;
} else {
item.innerHTML = "<b>" + note.type + " at (" + note.pos[0] + "," + note.pos[1] +"):</b><br>" + note.message;
// add a marker
var markerPos = L.latLng(note.pos[1], note.pos[0]); // latLng are effectively (y,x) so reverse
var marker;
switch(note.type) {
case "warning":
marker = L.marker(markerPos, {icon: L.Icon.Warning}).addTo(this.map);
marker.bindPopup("<b>warning:</b> " + note.message);
break;
case "error":
marker = L.marker(markerPos, {icon: L.Icon.Error}).addTo(this.map);
marker.bindPopup("<b>error:</b> " + note.message);
break;
}
item.marker = marker;
item.addEventListener("click", function() { this.marker.openPopup(); });
}
}
}
function loadViewers() {
var viewers = document.getElementsByClassName("board-viewer");
Array.prototype.forEach.call(viewers, function(viewer) {
// request board data file
var request = new XMLHttpRequest();
request.addEventListener("readystatechange", boardInfoLoaded);
request.open('GET', viewer.dataset.boardUrl);
// add map in preparation
var div = viewer.getElementsByClassName("map")[0];
var notes = viewer.getElementsByClassName("notes")[0];
var map = L.map(div, {crs: L.CRS.SimpleScaled}).setView(L.latLng(50,50), 0);
request.viewer = viewer;
request.map = map;
request.notes = notes;
request.send();
} );
}
document.addEventListener("DOMContentLoaded", loadViewers);