misc/hats_js_anim.xhtml
branchtransitional_engine
changeset 16008 72c71c385579
parent 15978 20adaa127663
equal deleted inserted replaced
16007:96d0e6149d3d 16008:72c71c385579
    32 }
    32 }
    33 a {
    33 a {
    34     color: #BFBED0;
    34     color: #BFBED0;
    35     text-decoration: none;
    35     text-decoration: none;
    36 }
    36 }
    37 .hat
    37 .hat, .hatLocal
    38 {
    38 {
    39     margin-top: 12px;
    39     margin-top: 12px;
    40     margin-left: 20px;
    40     margin-left: 20px;
    41     float: left;
    41     float: left;
    42     height: 32px;
    42     height: 32px;
    43     width: 32px;
    43     width: 32px;
    44     color: transparent;
    44     color: transparent;
       
    45 }
       
    46 .hat
       
    47 {
    45     background-image: url("//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hedgehog/Idle.png");
    48     background-image: url("//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hedgehog/Idle.png");
       
    49 }
       
    50 .hatLocal
       
    51 {
       
    52     background-image: url("../share/hedgewars/Data/Graphics/Hedgehog/Idle.png");
    46 }
    53 }
    47 .girder
    54 .girder
    48 {
    55 {
    49     width: 100%;
    56     width: 100%;
    50     height: 30px;
    57     height: 30px;
    60     width: 32px;
    67     width: 32px;
    61 }
    68 }
    62     </style>
    69     </style>
    63     <script type="application/ecmascript">
    70     <script type="application/ecmascript">
    64 //<![CDATA[
    71 //<![CDATA[
    65 var IS_LOCAL=false; // set to true to fetch hats locally. Useful for testing.
    72 let IS_LOCAL=false; // set to true to fetch graves locally. Useful for testing.
    66 var masks;
    73 let masks;
    67 if (IS_LOCAL) {
    74 if (IS_LOCAL) {
    68 /* JavaScript version of a sprite sheet - this could be pretty trivially done in pure HTML, but maintenance
    75 /* JavaScript version of a sprite sheet - this could be pretty trivially done in pure HTML, but maintenance
    69 would be easier with a server-side portion. list of sprites could be gotten from server, but would require XSS whitelisting */
    76 would be easier with a server-side portion. list of sprites could be gotten from server, but would require XSS whitelisting */
    70 // Last updated: 1.0.0
    77 // Last updated: 1.0.0
    71 masks = ['4gsuif','AkuAku','android','angel','anzac','Bandit','barrelhider','bb_bob','bb_bub','bb_cororon','bb_kululun','beefeater','beefeaterhat','bishop','bobby','bobby2v','bubble','bushhider','cap_blue','cap_green','cap_junior','cap_red','cap_thinking','cap_yellow','car','chef','chuckl','clown','clown-copper','clown-crossed','constructor','Coonskin3','Cowboy','cratehider','crown','cyborg1','cyborg2','cyclops','Dan','Dauber','DayAndNight','Disguise','dish_Ladle','dish_SauceBoatSilver','dish_Teacup','dish_Teapot','doctor','Dragon','dwarf','eastertop','Einstein','Elvis','Eva_00b','Eva_00y','Evil','flag_french','flag_germany','flag_italy','flag_usa','footballhelmet','fr_apple','fr_banana','fr_lemon','fr_orange','fr_pumpkin','fr_tomato','Gasmask','Glasses','hair_blue','hair_green','hair_grey','hair_orange','hair_pink','hair_purple','hair_red','hair_yellow','HogInTheHat','hogpharoah','IndianChief','InfernalHorns','Jason','jester','Joker','judo','kiss_criss','kiss_frehley','kiss_simmons','kiss_stanley','knight','lambda','lambdahat','Laminaria','lamp','laurel','leprechaun','mechanicaltoy','MegaHogX','metalband','Meteorhelmet','mexicansunbrero','mickey_ears','Moustache','Moustache_glasses','mp3','Mummy','mv_Spidey','mv_Venom','naruto','NinjaFull','NinjaStraight','NinjaTriangle','noface','ntd_Falcon','ntd_Kirby','ntd_Link','ntd_Samus','nurse','nursehat','OldMan','Pantsu','pinksunhat','pirate_bandana','pirate_eyepatch','pirate_hat','pirate_jack','pirate_jack_bandana','Plunger',
    78 masks = ['4gsuif','AkuAku','android','angel','anzac','Bandit','barrelhider','bb_bob','bb_bub','bb_cororon','bb_kululun','beefeater','beefeaterhat','bishop','bobby','bobby2v','bubble','bushhider','cap_blue','cap_green','cap_junior','cap_red','cap_thinking','cap_yellow','car','chef','chuckl','clown','clown-copper','clown-crossed','constructor','Coonskin3','Cowboy','cratehider','crown','cyborg1','cyborg2','cyclops','Dan','Dauber','DayAndNight','Disguise','dish_Ladle','dish_SauceBoatSilver','dish_Teacup','dish_Teapot','doctor','Dragon','dwarf','eastertop','Einstein','Elvis','Eva_00b','Eva_00y','Evil','flag_french','flag_germany','flag_italy','flag_usa','footballhelmet','fr_apple','fr_banana','fr_lemon','fr_orange','fr_pumpkin','fr_tomato','Gasmask','Glasses','hair_blue','hair_green','hair_grey','hair_orange','hair_pink','hair_purple','hair_red','hair_yellow','HogInTheHat','hogpharoah','IndianChief','InfernalHorns','Jason','jester','Joker','judo','kiss_criss','kiss_frehley','kiss_simmons','kiss_stanley','knight','lambda','lambdahat','Laminaria','lamp','laurel','leprechaun','mechanicaltoy','MegaHogX','metalband','Meteorhelmet','mexicansunbrero','mickey_ears','Moustache','Moustache_glasses','mp3','Mummy','mv_Spidey','mv_Venom','naruto','NinjaFull','NinjaStraight','NinjaTriangle','noface','ntd_Falcon','ntd_Kirby','ntd_Link','ntd_Samus','nurse','nursehat','OldMan','Pantsu','pinksunhat','pirate_bandana','pirate_eyepatch','pirate_hat','pirate_jack','pirate_jack_bandana','Plunger',
    77 else
    84 else
    78 {
    85 {
    79 masks = [];
    86 masks = [];
    80 }
    87 }
    81 
    88 
    82 var themes = {
    89 let themes = {
    83 // Last updated: 1.0.0
    90 // Last updated: 1.0.0
    84 "Art":1,
    91 "Art":1,
    85 "Beach":1,
    92 "Beach":1,
    86 "Bamboo":1,
    93 "Bamboo":1,
    87 "Bath":1,
    94 "Bath":1,
   112 "Planes":0,
   119 "Planes":0,
   113 "Sheep":1,
   120 "Sheep":1,
   114 "Snow":1,
   121 "Snow":1,
   115 "Stage":1,
   122 "Stage":1,
   116 "Underwater":1};
   123 "Underwater":1};
   117 var girder;
   124 let girder;
   118 var animationInterval;
   125 let animationInterval;
   119 
   126 
   120 var staticMasks = [];
   127 let staticMasks = [];
   121 
   128 
   122 on_xml_loaded = function(ex)
   129 on_xml_loaded = function(ex)
   123 {
   130 {
   124     var resp = this.responseText;
   131     let resp = this.responseText;
   125     var r = />([^<]*).png</g;
   132     let r = />([^<]*).png</g;
   126     var x;
   133     let x;
   127     while(x = r.exec(resp))
   134     while(x = r.exec(resp))
   128     {
   135     {
   129         masks.push(x[1]);
   136         masks.push(x[1]);
   130     }
   137     }
   131     on_hats_loaded();
   138     on_hats_loaded();
   132 }
   139 }
   133 
   140 
   134 on_xml_error = function()
   141 on_xml_error = function()
   135 {
   142 {
   136     var p = document.createElement("p");
   143     let p = document.createElement("p");
   137     p.appendChild(document.createTextNode("ERROR: List of hats could not be fetched from the server!"));
   144     p.appendChild(document.createTextNode("ERROR: List of hats could not be fetched from the server!"));
   138     document.body.appendChild(p);
   145     document.body.appendChild(p);
   139 }
   146 }
   140 
   147 
   141 window.onload = function()
   148 window.onload = function()
   142 {
   149 {
   143     // Load list of hats
   150     // Load list of hats
   144     if (!IS_LOCAL) {
   151     if (!IS_LOCAL) {
   145         // Request list of hats from repository URL
   152         // Request list of hats from repository URL
   146         var xml=new XMLHttpRequest();
   153         let xml=new XMLHttpRequest();
   147         xml.open("GET", "//hg.hedgewars.org/hedgewars/file/tip/share/hedgewars/Data/Graphics/Hats/");
   154         xml.open("GET", "//hg.hedgewars.org/hedgewars/file/tip/share/hedgewars/Data/Graphics/Hats/");
   148         xml.addEventListener("error", on_xml_error);
   155         xml.addEventListener("error", on_xml_error);
   149         xml.onload = on_xml_loaded;
   156         xml.onload = on_xml_loaded;
   150         xml.send();
   157         xml.send();
   151     }
   158     }
   157 
   164 
   158 on_hats_loaded = function()
   165 on_hats_loaded = function()
   159 {
   166 {
   160     // Exclude NoHat as uninteresting. Exclude team hats as we can't properly display them yet
   167     // Exclude NoHat as uninteresting. Exclude team hats as we can't properly display them yet
   161     // TODO: Add support for team hats
   168     // TODO: Add support for team hats
   162     var disallowedMasks = {
   169     let disallowedMasks = {
   163         "NoHat":true,
   170         "NoHat":true,
   164         "hair_team":true,
   171         "hair_team":true,
   165         "cap_team":true,
   172         "cap_team":true,
   166         "TeamTophat":true,
   173         "TeamTophat":true,
   167     };
   174     };
   168 
   175 
   169     // Render girders
   176     // Render girders
   170     var s = document.styleSheets[0].cssRules;
   177     let s = document.styleSheets[0].cssRules;
   171     for(var i=0;i<s.length;i++)
   178     for(let i=0;i<s.length;i++)
   172     {
   179     {
   173         if (s[i].selectorText.toLowerCase() === ".girder")
   180         if (s[i].selectorText.toLowerCase() === ".girder")
   174             girder = s[i];
   181             girder = s[i];
   175     }
   182     }
   176 
   183 
   177     var a = document.createElement("a");
   184     let a = document.createElement("a");
   178     var g = document.createElement("div");
   185     let g = document.createElement("div");
   179     g.className="girder";
   186     g.className="girder";
   180     a.className="hat";
   187     if (IS_LOCAL) {
       
   188         a.className="hatLocal";
       
   189     } else {
       
   190         a.className="hat";
       
   191     }
   181     a.appendChild(document.createElement("div"));
   192     a.appendChild(document.createElement("div"));
   182     a.lastChild.appendChild(document.createTextNode(""));
   193     a.lastChild.appendChild(document.createTextNode(""));
   183 
   194 
   184     // Render hats
   195     // Render hats
   185     var missingMasks = [];
   196     let missingMasks = [];
   186     var img;
   197     let img;
   187     var j = 0;
   198     let j = 0;
   188     var toDelete = [];
   199     let toDelete = [];
   189     for (var i=0;i<masks.length;i++)
   200     for (let i=0;i<masks.length;i++)
   190     {
   201     {
   191         if (disallowedMasks[masks[i]] === true) {
   202         if (disallowedMasks[masks[i]] === true) {
   192             missingMasks.push(masks[i]);
   203             missingMasks.push(masks[i]);
   193             toDelete.push(i);
   204             toDelete.push(i);
   194             continue;
   205             continue;
   195         }
   206         }
   196         var h = document.body.appendChild(a.cloneNode(true));
   207         let h = document.body.appendChild(a.cloneNode(true));
   197         if (IS_LOCAL)
   208         if (IS_LOCAL)
   198             h.href = "../share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png";
   209             h.href = "../share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png";
   199         else
   210         else
   200             h.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png";
   211             h.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png";
   201 
   212 
   202         img = new Image();
   213         img = new Image();
   203         img.onload = function() {
   214         img.onload = function() {
   204             var name = this.id.substr(7);
   215             let name = this.id.substr(7);
   205             if (this.height === 32) {
   216             if (this.height === 32) {
   206                 staticMasks[name] = true;
   217                 staticMasks[name] = true;
   207             }
   218             }
   208             this.remove();
   219             this.remove();
   209         }
   220         }
   210         img.src = h.href;
   221         img.src = h.href;
   211         img.id = "__mask_"+masks[i];
   222         img.id = "__mask_"+masks[i];
   212 
   223 
   213         h.lastChild.style.backgroundImage = 'url("'+h.href+'")';
   224         h.lastChild.style.backgroundImage = 'url("'+h.href+'")';
   214         h.lastChild.lastChild.data = masks[i];
       
   215         h.title = masks[i];
   225         h.title = masks[i];
   216         h.idle = Math.floor(Math.random()*19);
   226         h.idle = Math.floor(Math.random()*19);
   217         if (j%17 === 16 || i === masks.length-1)
   227         if (j%17 === 16 || i === masks.length-1)
   218             document.body.appendChild(g.cloneNode(false));
   228             document.body.appendChild(g.cloneNode(false));
   219         j++;
   229         j++;
   220     }
   230     }
   221     // Cleanup masks array
   231     // Cleanup masks array
   222     for (var i=0; i<toDelete.length; i++)
   232     for (let i=0; i<toDelete.length; i++)
   223         masks.splice(toDelete[i], 1);
   233         masks.splice(toDelete[i], 1);
   224 
   234 
   225     // List missing hats
   235     // List missing hats
   226     if (missingMasks.length > 0)
   236     if (missingMasks.length > 0)
   227     {
   237     {
   228         var pm = document.createElement("p");
   238         let pm = document.createElement("p");
   229         pm.appendChild(document.createTextNode("Other hats: "));
   239         pm.appendChild(document.createTextNode("Other hats: "));
   230         for (var i=0; i<missingMasks.length; i++)
   240         for (let i=0; i<missingMasks.length; i++)
   231         {
   241         {
   232             if (missingMasks[i] === "NoHat")
   242             if (missingMasks[i] === "NoHat")
   233                 continue;
   243                 continue;
   234             var link = document.createElement("a");
   244             let link = document.createElement("a");
   235             if (IS_LOCAL)
   245             if (IS_LOCAL)
   236                 link.href = "../share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png";
   246                 link.href = "../share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png";
   237             else
   247             else
   238                 link.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png";
   248                 link.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png";
   239             link.appendChild(document.createTextNode(missingMasks[i]));
   249             link.appendChild(document.createTextNode(missingMasks[i]));
   240             pm.appendChild(link);
   250             pm.appendChild(link);
   241             if (i < missingMasks.length -1)
   251             if (i < missingMasks.length -1)
   242                 pm.appendChild(document.createTextNode(", "));
   252                 pm.appendChild(document.createTextNode(", "));
   243         }
   253         }
       
   254         document.body.appendChild(document.createElement("br"));
   244         document.body.appendChild(pm);
   255         document.body.appendChild(pm);
   245     }
   256     }
   246 
   257 
   247     // Quick and dirty animation
   258     // Quick and dirty animation
   248     animationInterval = setInterval(animateHogs, 128);
   259     animationInterval = setInterval(animateHogs, 128);
   249 
   260 
   250     // Theme selection drop-down list
   261     // Theme selection drop-down list
   251     var form = document.body.appendChild(document.createElement("form"));
   262     let form = document.body.appendChild(document.createElement("form"));
   252 
   263 
   253     var opt = document.createElement("option");
   264     let opt = document.createElement("option");
   254     opt.appendChild(document.createTextNode(""));
   265     opt.appendChild(document.createTextNode(""));
   255 
   266 
   256     var label = document.createElement("label");
   267     let label = document.createElement("label");
   257     label.htmlFor = "theme_select";
   268     label.htmlFor = "theme_select";
   258     label.appendChild(document.createTextNode("Theme: "));
   269     label.appendChild(document.createTextNode("Theme: "));
   259     form.appendChild(label);
   270     form.appendChild(label);
   260 
   271 
   261     var sel = form.appendChild(document.createElement("select"));
   272     let sel = form.appendChild(document.createElement("select"));
   262     sel.id = "theme_select";
   273     sel.id = "theme_select";
   263     sel.onchange = switchTheme;
   274     sel.onchange = switchTheme;
   264     for(var theme in themes)
   275     for(let theme in themes)
   265     {
   276     {
   266         sel.appendChild(opt.cloneNode(true));
   277         sel.appendChild(opt.cloneNode(true));
   267         sel.lastChild.value = theme;
   278         sel.lastChild.value = theme;
   268         sel.lastChild.lastChild.data = theme;
   279         sel.lastChild.lastChild.data = theme;
   269         if(theme === "Nature")
   280         if(theme === "Nature")
   270             sel.lastChild.selected = true;
   281             sel.lastChild.selected = true;
   271     }
   282     }
   272     form.appendChild(document.createElement("br"));
   283     form.appendChild(document.createElement("br"));
   273 
   284 
   274     // Checkbox: Switch animation
   285     // Checkbox: Switch animation
   275     var chk = document.createElement("input");
   286     let chk = document.createElement("input");
   276     chk.id = "anim";
   287     chk.id = "anim";
   277     chk.type = "checkbox";
   288     chk.type = "checkbox";
   278     chk.onclick = switchAnim;
   289     chk.onclick = switchAnim;
   279     chk.checked = true;
   290     chk.checked = true;
   280     form.appendChild(chk);
   291     form.appendChild(chk);
   281     label = document.createElement("label");
   292     label = document.createElement("label");
   282     label.htmlFor = "anim";
   293     label.htmlFor = "anim";
   283     label.appendChild(document.createTextNode("Animate hats"));
   294     label.appendChild(document.createTextNode(" Animate hats"));
   284     form.appendChild(label);
   295     form.appendChild(label);
   285 
   296 
   286     form.appendChild(document.createElement("br"));
   297     form.appendChild(document.createElement("br"));
   287 
   298 
   288     // Checkbox: Hide girders
   299     // Checkbox: Hide girders
   292     chk.onclick = hideGirders;
   303     chk.onclick = hideGirders;
   293     chk.checked = true;
   304     chk.checked = true;
   294     form.appendChild(chk);
   305     form.appendChild(chk);
   295     label = document.createElement("label");
   306     label = document.createElement("label");
   296     label.htmlFor = "hide_girders";
   307     label.htmlFor = "hide_girders";
   297     label.appendChild(document.createTextNode("Show girders"));
   308     label.appendChild(document.createTextNode(" Show girders"));
   298     form.appendChild(label);
   309     form.appendChild(label);
   299 
   310 
   300     document.body.appendChild(form);
   311     document.body.appendChild(form);
   301 
   312 
   302 
   313     switchTheme();
   303 }
   314 }
   304 
   315 
   305 function animateHogs()
   316 function animateHogs()
   306 {
   317 {
   307     var a = document.getElementsByTagName("a");
   318     let a = document.getElementsByTagName("a");
   308     for (var i=0;i<a.length;i++)
   319     for (let i=0;i<a.length;i++)
   309     {
   320     {
   310         if (a[i].className !== "hat")
   321         if (a[i].className !== "hat" && a[i].className !== "hatLocal")
   311             continue;
   322             continue;
   312         // Cycle through hedgehog and hat animation frames
   323         // Cycle through hedgehog and hat animation frames
   313 
   324 
   314         // Hedgehog
   325         // Hedgehog
   315         a[i].style.backgroundPosition=Math.floor(a[i].idle/16)*-32+"px "+(a[i].idle%16)*-32+"px";
   326         a[i].style.backgroundPosition=Math.floor(a[i].idle/16)*-32+"px "+(a[i].idle%16)*-32+"px";
   316 
   327 
   317         var maskName = a[i].title;
   328         let maskName = a[i].title;
   318         // Hat
   329         // Hat
   319         if (staticMasks[maskName] === true) {
   330         if (staticMasks[maskName] === true) {
   320             // Hat offset for static hats
   331             // Hat offset for static hats
   321             if (a[i].idle === 2 || a[i].idle === 7 || a[i].idle === 12)
   332             if (a[i].idle === 2 || a[i].idle === 7 || a[i].idle === 12)
   322                 a[i].firstChild.style.marginTop="-4px";
   333                 a[i].firstChild.style.marginTop="-4px";
   352 }
   363 }
   353 
   364 
   354 // Turn on or off girders
   365 // Turn on or off girders
   355 function hideGirders()
   366 function hideGirders()
   356 {
   367 {
   357     var g = document.getElementsByClassName("girder");
   368     let g = document.getElementsByClassName("girder");
   358     for(var i=0;i<g.length;i++)
   369     for(let i=0;i<g.length;i++)
   359         if (this.checked)
   370         if (this.checked)
   360             g[i].className = "girder";
   371             g[i].className = "girder";
   361         else
   372         else
   362             g[i].className = "girder hide";
   373             g[i].className = "girder hide";
   363 
   374 
   364 }
   375 }
   365 
   376 
   366 // Select theme according to drop-down list value
   377 // Select theme according to drop-down list value
   367 function switchTheme()
   378 function switchTheme()
   368 {
   379 {
   369     var prefix;
   380     let prefix;
   370     if (!IS_LOCAL)
   381     if (!IS_LOCAL)
   371         prefix = "//hg.hedgewars.org/hedgewars/raw-file/tip";
   382         prefix = "//hg.hedgewars.org/hedgewars/raw-file/tip";
   372     else
   383     else
   373         prefix = "..";
   384         prefix = "..";
   374     document.body.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Sky.png")';
   385     let theme = this.value || "Nature";
   375     if (themes[this.value])
   386     document.body.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+theme+'/Sky.png")';
   376         girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Girder.png")';
   387     if (themes[theme])
       
   388         girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+theme+'/Girder.png")';
   377     else
   389     else
   378         girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Graphics/Girder.png")';
   390         girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Graphics/Girder.png")';
   379 }
   391 }
   380 //]]>
   392 //]]>
   381     </script>
   393     </script>