Miten saan javascriptillä tehtyä sellaisen systeemin, jossa aluksi on yksi kuva ruudulla. Sitten kun heität hiiren siihen päälle niin se arpoo kolmesta kuvasta jonkun esille. Kun poistat hiiren kuvan päältä palautuu alkuperäinen kuva ja jälleen kun laitat hiiren päälle se arpoo niistä 3 kuvasta yhden näkyviin.
Eli siis tehtävässä on yhteensä 4 kuvaa, se alkuperäinen joka näkyy aluksi ruudulla. Sekä 3 kappaletta semmoisia, jotka arpoutuvat kun laittaa hiiren kuvan päälle.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN"> <html> <head> <title></title> </head> <body> <script language="javascript"> function changePict() { vaihda = new Image(); vaihda.src = "kuva"+Math.round((Math.random()*2)+2)+".gif"; document.muutettava_kuva.src=vaihda.src; } function changeBack() { vaihda = new Image(); vaihda.src="kuva1.gif"; document.muutettava_kuva.src=vaihda.src; } </script> <img src="kuva1.gif" name="muutettava_kuva" onMouseOver="changePict()" onMouseOut="changeBack();"> </body> </html>
Jos kuvilla on eri nimiä, käytä switch-lausetta.
Joo kuvien nimet on kuva1, kuva2, kuva3, kuva4... Kokeilenpas tuota
Itsenäisesti nimettyjen kuvien tapaus:
function vaihda(img, kuvat) { img.src_bak = img.src; var i = Math.floor(Math.random() * kuvat.length); img.src = kuvat[i]; } function palauta(img) { img.src = img.src_bak; }
<img src="alkukuva.png" onmouseover="vaihda(this, ['vaihto_01.png', 'kuva2.png', 'muu.png'])" onmouseout="palauta(this)" />
Taulukot kannattaa ehdottomasti hyödyntää, switch-lause on tässä aivan turha.
Juhkon esimerkissä luodaan aivan turhaan ylimääräinen Image-objekti. Sen src-ominaisuus on kuitenkin string, joten on aivan sama sijoittaa arvo suoraan lopulliseen päämääräänsä. Vrt:
function helppo_10() { return 10; } function vaikea_10() { var a = 10; var b = a; return b; }
Myös round-funktion käyttö satunnaisluvun pyöristämiseen aiheuttaa epätasaisen jakauman, jossa ensimmäisen ja viimeisen kuvan todennäköisyys on vain 1/4 ja keskimmäisen 1/2. Oikeasti luku pitää arpoa halutun kokoiselta alueelta ja pyöristää aina alaspäin.
Lisäksi muuttujat on aina hyvä määritellä var
-sanalla, koska muuten ne viittaavat objektin (tässä tapauksessa window
) jäseniin eivätkä ole paikallisia:
function var_i() { var i = "var i"; } function member_i() { i = "member i"; } function alert_i() { var e; try { alert(i); } catch (e) { alert("Virhe!"); } } var_i(); alert_i(); // Virhe! member_i(); alert_i(); // member i
Tossa Juhkon random systeemissä tää viimenen kuva ei näy paljoa koskaan jos ollenkaan. Täytyy vähän säädellä.
EDIT Metabolixin versio toimii jo vähän paremmin, kiitos.
EDIT Jooh miten tota randomia kannattais muuttaa, jotta tulis enemmän sattumalla noita hommeleita. Tossa kun nyt 3 kuvaa vaihtelee, niin ensimmäinen näistä kolmesta tulee huomattavasti vähempiä kertoja.
Javakoodari kirjoitti:
EDIT Jooh miten tota randomia kannattais muuttaa, jotta tulis enemmän sattumalla noita hommeleita. Tossa kun nyt 3 kuvaa vaihtelee, niin ensimmäinen näistä kolmesta tulee huomattavasti vähempiä kertoja.
Oletko varma asiasta? Kokeilin tuota Metabolixin vaihda-funktiota 100000 kertaa, jolloin kuva 1 tuli 33246 kertaa, kuva 2 tuli 33347 kertaa ja kuva 3 tuli 33407 kertaa. Kokeilin vielä toiset 100000 kertaa, jolloin kuva 1 tuli 33538 kertaa, kuva 2 tuli 33392 kertaa ja kuva 3 tuli 33070 kertaa.
lainaus:
Oletko varma asiasta? Kokeilin tuota Metabolixin vaihda-funktiota 100000 kertaa, jolloin kuva 1 tuli 33246 kertaa, kuva 2 tuli 33347 kertaa ja kuva 3 tuli 33407 kertaa. Kokeilin vielä toiset 100000 kertaa, jolloin kuva 1 tuli 33538 kertaa, kuva 2 tuli 33392 kertaa ja kuva 3 tuli 33070 kertaa.
Joo perun sanani se johtuikin tuosta kuva 1 koosta, eli se vain vilahti välillä, koska se oli pienempi kuin muut. Hyvin toimii kiitoksia :)
Jos haluat varmistaa tasaisen jakauman lyhyelläkin aikavälillä, voit pitää yllä taulukkoa, johon lisäät aina saman määrän kutakin vaihtoehtoa. Arvotut arvot poistetaan aina taulukosta, ja kun sen koko alittaa asetetun rajan, lisätään taas yksi kutakin arvoa. Jos vähimmäiskooksi määrätään yksi, uusi täyttö tapahtuu vasta, kun kaikki arvot on arvottu. Tällöin mitään kuvaa ei näytetä uudestaan, ennen kuin kaikki muutkin on näytetty. Alla on tätä varten kirjoitettu apuluokka:
function laatikko(arvot, minimikoko) { this.arvot = arvot; this.minimikoko = minimikoko; this.sisalto = []; } laatikko.prototype.tayta = function () { while (this.sisalto.length < this.minimikoko) { for (var i in this.arvot) { this.sisalto.push(this.arvot[i]); } } } laatikko.prototype.arvo = function () { this.tayta(); var a = this.sisalto.splice(Math.floor(Math.random() * this.sisalto.length), 1); return a[0]; } function vaihda(img, kuvat) { img.src_bak = img.src; if (!img.laatikko) { img.laatikko = new laatikko(kuvat, kuvat.length + 1); // Laita jokin koko. } img.src = img.laatikko.arvo(); } function palauta(img) { img.src = img.src_bak; }
Javakoodari kirjoitti:
miten tota randomia kannattais muuttaa, jotta tulis enemmän sattumalla noita hommeleita.
Metabolix kirjoitti:
Jos haluat varmistaa tasaisen jakauman lyhyelläkin aikavälillä
Heh, sinänsä hauskaa, kun kysytään miten saisi enemmän satunnaiseksi, niin annetaan vastaus miten sen saisi vähemmän satunnaiseksi.
Tosin en itsekään pidä mahdottomana, että kysyjä oikeasti halusi vähemmän satunnaisen vaikka luulikin haluavansa enemmän satunnaisen. :D
Grez kirjoitti:
Heh, sinänsä hauskaa, kun kysytään miten saisi enemmän satunnaiseksi, niin annetaan vastaus miten sen saisi vähemmän satunnaiseksi.
Yritän usein puuttua ennemmin ongelmaan kuin siihen, mitä kysyjä luulee ongelmaksi. Neuvoni kohdistui siis itse asiassa seuraavaan virkkeeseen:
Javakoodari kirjoitti:
Tossa kun nyt 3 kuvaa vaihtelee, niin ensimmäinen näistä kolmesta tulee huomattavasti vähempiä kertoja.
Ok, no ehkä sanoin vähän väärin mikä oli huvittavaa, eli ehkä enemmänkin toi toivomus oli huvittavasti ristiriitainen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.