Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: CSS, HTML, JavaScript: Animaatio kuvaa vaihtamalla

Metabolix [15.09.2009 21:04:12]

#

Aina toisinaan herää keskustelua animaation tekemisestä JavaScriptin voimin. Tässä on pieni JS-luokka, joka osaa vaihtaa kuvia ajastetusti. Lisäksi tarvitaan hieman CSS:ää asetteluun ja HTML:ää itse sivua varten.

Luokan toiminta on yksinkertainen. Kuvat pitää sijoittaa jonkin elementin sisään, ja luokka osaa etsiä ne annetusta elementistä. Luokalle kerrotaan, miten kauan kutakin kuvaa näytetään ja montako kertaa animaatio toistuu. Kun animaatio alkaa, käynnistetään ajastin, joka vaihtaa aina seuraavaan kuvaan, kunnes animaatio pysäytetään tai loppuu. Animaatiossa voi liikkua myös kuva kerrallaan ilman ajastusta, ja lisäksi luokassa on funktio animaation nollaamiseen.

/* CSS */

/* Kuvat ovat absoluuttisesti aseteltuja ja
 * koko ympäröivän elementin kokoisia. */
.animaatio img {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	/* Oletuksena kuvat ovat piilossa. */
	visibility: hidden;
}
/* Näkyvälle kuvalle on oma CSS-luokka. */
.animaatio img.nakyva {
	visibility: visible;
}
/* Animaation pääelementin pitää olla suhteellisesti aseteltu,
 * jotta kuvien "position: absolute" toimisi. */
.animaatio {
	position: relative;
}

/* Edelliset säännöt koskevat kaikkia animaatioita.
 * Esimerkkianimaatiolla on tietty koko ja sijainti. */
#animaatio {
	width: 3em;
	height: 3em;
	float: right;
}
/* JS */
/* Animaatio-olioiden luontiin.
 * div - elementti, jossa kuvat ovat, tai elementin id.
 * vali - kuvien aikaväli sekunteina
 * kerrat - montako kertaa animaatio toistetaan; Infinity = loputon toisto.
 */
function jsAnimaatio(div, vali, kerrat) {
	// Jos annettiin id, haetaan sen perusteella elementti.
	if (typeof(div) != "object") {
		div = document.getElementById(div);
	}
	if (!div) throw "Ei annettu diviä!";

	// Muutetaan väli millisekunneiksi.
	this.vali = Math.round(vali * 1000);

	// Jos kertamäärä ei ole positiivinen luku, laitetaan siihen ääretön.
	if (typeof(kerrat) != "number" || kerrat <= 0) {
		kerrat = Infinity;
	}

	// Haetaan kuvat.
	this.kuvat = [];
	this.kohta = 0;
	for (var img = div.firstChild; img; img = img.nextSibling) {
		if (img.tagName && img.tagName.toLowerCase() == "img") {
			this.kuvat.push(img);
			this.piilota(img);
		}
	}

	// Lasketaan, monenko kuvan jälkeen animaatio loppuu.
	this.loppu = Math.round(kerrat * this.kuvat.length);

	// Nollataan laskuri.
	this.nollaa();
}

/* Kuvan indeksi. (Sisäinen funktio.) */
jsAnimaatio.prototype.kohta_mod = function () {
	// Otetaan modulo kuvataulun pituudella;
	// kikkaillaan vähän, jotta negatiivinenkin kohta toimii.
	var tmp = this.kuvat.length;
	return (this.kohta % tmp + tmp) % tmp;
}

/* Kuvan piilotus. (Sisäinen funktio.) */
jsAnimaatio.prototype.piilota = function (img) {
	// Otetaan luokka "nakyva" pois.
	img.className = img.className.replace(/\s*nakyva/, '', 'g');
}

/* Kuvan näyttö. (Sisäinen funktio.) */
jsAnimaatio.prototype.nayta = function (img) {
	// Lisätään luokka "nakyva".
	img.className = img.className.replace(/\s*nakyva/, '', 'g') + " nakyva";
}

/* Animaation nollaus. */
jsAnimaatio.prototype.nollaa = function (alkuun) {
	if (!this.kuvat.length) return this;
	if (alkuun == null) {
		alkuun = true;
	}
	// Piilotetaan näkyvä kuva.
	this.piilota(this.kuvat[this.kohta_mod()]);
	if (alkuun) {
		// Animaatio alkaa nollasta.
		this.kohta = 0;
	} else if (this.loppu == Infinity) {
		// Äärettömän animaation "loppu" on viimeinen kuva;
		// toistoilla ei ole merkitystä.
		this.kohta = this.kuvat.length - 1;
	} else {
		// Äärellisen animaation loppu on juuri ennen loppua.
		this.kohta = this.loppu - 1;
	}
	// Näytetään uusi kuva.
	this.nayta(this.kuvat[this.kohta_mod()]);
	return this;
}

/* Animaation käynnistys: laitetaan ajastin käyntiin. */
jsAnimaatio.prototype.kaynnista = function (eteenpain) {
	// Pysäytetään ja aloitetaan uudestaan.
	this.pysayta();
	if (eteenpain == null) {
		eteenpain = true;
	}
	var _this = this;
	this.interval_id = setInterval(
		function() {
			// Ajastin vaihtaa kuvaa haluttuun suuntaan.
			eteenpain ? _this.seuraava() : _this.edellinen();
		},
		this.vali
	);
	return this;
}

/* Animaation pysäytys: suljetaan ajastin. */
jsAnimaatio.prototype.pysayta = function () {
	if (!this.interval_id) return this;
	// Poistetaan ajastin.
	clearInterval(this.interval_id);
	this.interval_id = null;
	return this;
}

/* Seuraava kuva. */
jsAnimaatio.prototype.seuraava = function () {
	// Jos animaatio loppuu, lopetetaan.
	if (!this.kuvat.length || this.kohta + 1 >= this.loppu) {
		return this.pysayta();
	}
	// Piilotetaan kuva, nostetaan indeksiä ja näytetään uusi.
	this.piilota(this.kuvat[this.kohta_mod()]);
	this.kohta += 1;
	this.nayta(this.kuvat[this.kohta_mod()]);
	return this;
}

/* Edellinen kuva. */
jsAnimaatio.prototype.edellinen = function () {
	// Jos animaatio loppuu, lopetetaan.
	if (!this.kuvat.length || (this.loppu != Infinity && this.kohta - 1 < 0)) {
		return this.pysayta();
	}
	// Piilotetaan kuva, lasketaan indeksiä ja näytetään uusi.
	this.piilota(this.kuvat[this.kohta_mod()]);
	this.kohta -= 1;
	this.nayta(this.kuvat[this.kohta_mod()]);
	return this;
}

/* Kun sivu latautuu, luodaan yksi animaatio.
 * Elementin id on "animaatio". Joka kuva näkyy
 * 0,5 sekuntia, ja sarja toistetaan kolmesti. */
window.onload = function () {
	window.animaatio = new jsAnimaatio("animaatio", 0.5, 3);
}
<!-- (X)HTML; lisättävä osaksi valmista sivua -->

<!-- Animaatioelementti kuvineen: -->
<div class="animaatio" id="animaatio">
	<img src="kuva_1.png" alt="Animaatio (1)" />
	<img src="kuva_2.png" alt="Animaatio (2)" />
	<img src="kuva_3.png" alt="Animaatio (3)" />
</div>

<!-- Animaation hallinta: -->
<ul>
	<li><button onclick="window.animaatio.nollaa()">Alkuun</button></li>
	<li><button onclick="window.animaatio.nollaa(false)">Loppuun</button></li>
	<li><button onclick="window.animaatio.kaynnista()">Eteenpäin</button></li>
	<li><button onclick="window.animaatio.kaynnista(false)">Taaksepäin</button></li>
	<li><button onclick="window.animaatio.pysayta()">Pysäytä</button></li>
	<li><button onclick="window.animaatio.seuraava()">Seuraava</button></li>
	<li><button onclick="window.animaatio.edellinen()">Edellinen</button></li>
</ul>

ankzilla [20.09.2009 20:01:12]

#

Oot kyllä poika nähny ison vaivan tällaisen asian eteen.

Metabolix [28.09.2009 22:29:47]

#

ankzilla kirjoitti:

Oot kyllä poika nähny ison vaivan tällaisen asian eteen.

Ajattelepa tarkemmin. Koodia tarvitsee muokata vain ihan vähän, niin tästä saa tehtyä vaikka slide show'n tyylikkäillä kuvanvaihtoefekteillä.

Horny The Horrible [10.12.2009 23:42:14]

#

tämä on loistava. Onnittelut tekijälle. Bravo

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta