|
1 <!DOCTYPE HTML> |
|
2 <html xmlns="http://www.w3.org/1999/xhtml"> |
|
3 <head> |
|
4 <!-- There is, at present, no official xsd for (X)HTML5. A pity. Usefulness would depend on the parser and extensions made by the site. --> |
|
5 <title>Hedgewars Graves</title> |
|
6 |
|
7 <style type="text/css"> |
|
8 * {padding: 0; margin: 0; } |
|
9 body |
|
10 { |
|
11 background: url('//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Themes/Nature/Sky.png') fixed no-repeat bottom left; |
|
12 background-color: #0B203D; |
|
13 color: #FFD902; |
|
14 -moz-background-size: 200%; |
|
15 background-size: 100% 100%; |
|
16 font-family: sans-serif; |
|
17 } |
|
18 form, p |
|
19 { |
|
20 background-color: #0B203D; |
|
21 padding: 1em; |
|
22 margin: 1em; |
|
23 border-style: solid; |
|
24 border-radius: 5px; |
|
25 border-width: 2px; |
|
26 border-color: #FFD902; |
|
27 } |
|
28 h1 { |
|
29 text-shadow: 0 0 2px white; |
|
30 color: black; |
|
31 margin:10px; |
|
32 } |
|
33 a { |
|
34 color: #BFBED0; |
|
35 text-decoration: none; |
|
36 } |
|
37 .grave |
|
38 { |
|
39 margin-top: 12px; |
|
40 margin-left: 20px; |
|
41 float: left; |
|
42 height: 32px; |
|
43 width: 32px; |
|
44 color: transparent; |
|
45 } |
|
46 .girder |
|
47 { |
|
48 width: 100%; |
|
49 height: 30px; |
|
50 clear: left; |
|
51 background-image: url('//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Themes/Nature/Girder.png'); |
|
52 background-repeat: repeat-x; |
|
53 } |
|
54 .hide { visibility: hidden; } |
|
55 a div |
|
56 { |
|
57 margin-top: -5px; |
|
58 height: 32px; |
|
59 width: 32px; |
|
60 } |
|
61 </style> |
|
62 <script type="application/ecmascript"> |
|
63 //<![CDATA[ |
|
64 var IS_LOCAL=false; // set to true to fetch graves locally. Useful for testing. |
|
65 var graves; |
|
66 if (IS_LOCAL) { |
|
67 /* JavaScript version of a sprite sheet - this could be pretty trivially done in pure HTML, but maintenance |
|
68 would be easier with a server-side portion. list of sprites could be gotten from server, but would require XSS whitelisting */ |
|
69 // Last updated: 1.0.0 |
|
70 graves=["Badger","Bone","bp2","bubble","Cherry","chest","Clover","coffin", |
|
71 "deadhog","dragonball","Duck2","Earth","Egg","eyecross","Flower","Ghost", |
|
72 "Grave","heart","money","mouton1","octopus","Old_Apple","pi","plant2", |
|
73 "plant3","Plinko","pokeball","pyramid","ring","Rip","Rubberduck","Simple", |
|
74 "Simple_reversed","skull","star","Statue","TV","Whisky","Yin_and_Yang"]; |
|
75 } |
|
76 else |
|
77 { |
|
78 graves = []; |
|
79 } |
|
80 |
|
81 var themes = { |
|
82 // Last updated: 1.0.0 |
|
83 "Art":1, |
|
84 "Beach":1, |
|
85 "Bamboo":1, |
|
86 "Bath":1, |
|
87 //"Blox":0, //unused, has no Sky.png or Border.png |
|
88 "Brick":0, |
|
89 "Cake":0, |
|
90 "Castle":1, |
|
91 "Cave":1, |
|
92 "City":1, |
|
93 "Cheese":0, |
|
94 "Christmas":1, |
|
95 "Compost":1, |
|
96 "CrazyMission":0, |
|
97 "Deepspace":0, |
|
98 "Desert":1, |
|
99 "EarthRise":0, |
|
100 "Eyes":0, |
|
101 "Freeway":0, |
|
102 "Fruit":1, |
|
103 "Halloween":1, |
|
104 "Hell":0, |
|
105 "Hoggywood":1, |
|
106 "Island":0, |
|
107 "Jungle":1, |
|
108 "Golf":1, |
|
109 "Nature":1, |
|
110 "Olympics":1, |
|
111 "Planes":0, |
|
112 "Sheep":1, |
|
113 "Snow":1, |
|
114 "Stage":1, |
|
115 "Underwater":1}; |
|
116 var girder; |
|
117 var animationInterval; |
|
118 |
|
119 on_xml_loaded = function(ex) |
|
120 { |
|
121 var resp = this.responseText; |
|
122 var r = />([^<]*).png</g; |
|
123 var x; |
|
124 while(x = r.exec(resp)) |
|
125 { |
|
126 graves.push(x[1]); |
|
127 } |
|
128 on_graves_loaded(); |
|
129 } |
|
130 |
|
131 on_xml_error = function() |
|
132 { |
|
133 var p = document.createElement("p"); |
|
134 p.appendChild(document.createTextNode("ERROR: List of graves could not be fetched from the server!")); |
|
135 document.body.appendChild(p); |
|
136 } |
|
137 |
|
138 window.onload = function() |
|
139 { |
|
140 // Load list of graves |
|
141 if (!IS_LOCAL) { |
|
142 // Request list of graves from repository URL |
|
143 var xml=new XMLHttpRequest(); |
|
144 xml.open("GET", "//hg.hedgewars.org/hedgewars/file/tip/share/hedgewars/Data/Graphics/Graves/"); |
|
145 xml.addEventListener("error", on_xml_error); |
|
146 xml.onload = on_xml_loaded; |
|
147 xml.send(); |
|
148 } |
|
149 else |
|
150 { |
|
151 on_graves_loaded(); |
|
152 } |
|
153 } |
|
154 |
|
155 on_graves_loaded = function() |
|
156 { |
|
157 // Render girders |
|
158 var s = document.styleSheets[0].cssRules; |
|
159 for(var i=0;i<s.length;i++) |
|
160 { |
|
161 if (s[i].selectorText.toLowerCase() === ".girder") |
|
162 girder = s[i]; |
|
163 } |
|
164 |
|
165 var a = document.createElement("a"); |
|
166 var g = document.createElement("div"); |
|
167 g.className="girder"; |
|
168 a.className="grave"; |
|
169 a.appendChild(document.createElement("div")); |
|
170 a.lastChild.appendChild(document.createTextNode("")); |
|
171 |
|
172 // Render graves |
|
173 var missingGraves = []; |
|
174 var img; |
|
175 var j = 0; |
|
176 var toDelete = []; |
|
177 for (var i=0;i<graves.length;i++) |
|
178 { |
|
179 var h = document.body.appendChild(a.cloneNode(true)); |
|
180 if (IS_LOCAL) |
|
181 h.href = "../share/hedgewars/Data/Graphics/Graves/"+graves[i]+".png"; |
|
182 else |
|
183 h.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Graves/"+graves[i]+".png"; |
|
184 |
|
185 h.lastChild.style.backgroundImage = 'url("'+h.href+'")'; |
|
186 h.lastChild.lastChild.data = graves[i]; |
|
187 h.title = graves[i]; |
|
188 h.idle = Math.floor(Math.random()*16); |
|
189 if (j%8 === 7 || i === graves.length-1) |
|
190 document.body.appendChild(g.cloneNode(false)); |
|
191 j++; |
|
192 } |
|
193 |
|
194 // Quick and dirty animation |
|
195 animationInterval = setInterval(animateGraves, 128); |
|
196 |
|
197 // Theme selection drop-down list |
|
198 var form = document.body.appendChild(document.createElement("form")); |
|
199 |
|
200 var opt = document.createElement("option"); |
|
201 opt.appendChild(document.createTextNode("")); |
|
202 |
|
203 var label = document.createElement("label"); |
|
204 label.htmlFor = "theme_select"; |
|
205 label.appendChild(document.createTextNode("Theme: ")); |
|
206 form.appendChild(label); |
|
207 |
|
208 var sel = form.appendChild(document.createElement("select")); |
|
209 sel.id = "theme_select"; |
|
210 sel.onchange = switchTheme; |
|
211 for(var theme in themes) |
|
212 { |
|
213 sel.appendChild(opt.cloneNode(true)); |
|
214 sel.lastChild.value = theme; |
|
215 sel.lastChild.lastChild.data = theme; |
|
216 if(theme === "Nature") |
|
217 sel.lastChild.selected = true; |
|
218 } |
|
219 form.appendChild(document.createElement("br")); |
|
220 |
|
221 // Checkbox: Switch animation |
|
222 var chk = document.createElement("input"); |
|
223 chk.id = "anim"; |
|
224 chk.type = "checkbox"; |
|
225 chk.onclick = switchAnim; |
|
226 chk.checked = true; |
|
227 form.appendChild(chk); |
|
228 label = document.createElement("label"); |
|
229 label.htmlFor = "anim"; |
|
230 label.appendChild(document.createTextNode("Animate graves")); |
|
231 form.appendChild(label); |
|
232 |
|
233 form.appendChild(document.createElement("br")); |
|
234 |
|
235 // Checkbox: Hide girders |
|
236 chk = document.createElement("input"); |
|
237 chk.id = "hide_girders"; |
|
238 chk.type = "checkbox"; |
|
239 chk.onclick = hideGirders; |
|
240 chk.checked = true; |
|
241 form.appendChild(chk); |
|
242 label = document.createElement("label"); |
|
243 label.htmlFor = "hide_girders"; |
|
244 label.appendChild(document.createTextNode("Show girders")); |
|
245 form.appendChild(label); |
|
246 |
|
247 document.body.appendChild(form); |
|
248 |
|
249 |
|
250 } |
|
251 |
|
252 function animateGraves() |
|
253 { |
|
254 var a = document.getElementsByTagName("a"); |
|
255 for (var i=0;i<a.length;i++) |
|
256 { |
|
257 if (a[i].className !== "grave") |
|
258 continue; |
|
259 // Cycle thru animation frames |
|
260 |
|
261 var maskName = a[i].title; |
|
262 // Grave |
|
263 a[i].firstChild.style.backgroundPosition=Math.floor(a[i].idle/16)*-32+"px "+(a[i].idle%16)*-32+"px"; |
|
264 |
|
265 // Next frame |
|
266 a[i].idle++; |
|
267 if (a[i].idle > 15) |
|
268 a[i].idle = 0; |
|
269 } |
|
270 } |
|
271 |
|
272 // Turn on or off grave animation |
|
273 function switchAnim() |
|
274 { |
|
275 if (animationInterval) |
|
276 { |
|
277 clearInterval(animationInterval); |
|
278 animationInterval = null; |
|
279 } |
|
280 else animationInterval = setInterval(animateGraves, 128); |
|
281 } |
|
282 |
|
283 // Turn on or off girders |
|
284 function hideGirders() |
|
285 { |
|
286 var g = document.getElementsByClassName("girder"); |
|
287 for(var i=0;i<g.length;i++) |
|
288 if (this.checked) |
|
289 g[i].className = "girder"; |
|
290 else |
|
291 g[i].className = "girder hide"; |
|
292 |
|
293 } |
|
294 |
|
295 // Select theme according to drop-down list value |
|
296 function switchTheme() |
|
297 { |
|
298 var prefix; |
|
299 if (!IS_LOCAL) |
|
300 prefix = "//hg.hedgewars.org/hedgewars/raw-file/tip"; |
|
301 else |
|
302 prefix = ".."; |
|
303 document.body.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Sky.png")'; |
|
304 if (themes[this.value]) |
|
305 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Girder.png")'; |
|
306 else |
|
307 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Graphics/Girder.png")'; |
|
308 } |
|
309 //]]> |
|
310 </script> |
|
311 </head> |
|
312 <body> |
|
313 <h1>List of Hedgewars graves</h1> |
|
314 <noscript> |
|
315 <p><strong>ERROR</strong>: We're so sorry, but this webpage only works with JavaScript enabled. It seems JavaScript is disabled or not supported in your browser.<br/> |
|
316 Normally, this webpage would display an animated preview of the graves in Hedgewars.</p> |
|
317 </noscript> |
|
318 </body> |
|
319 </html> |