Novije i potpunije stranice pogledajte na adresi: http://www.dario-ljubesic.iz.hr/

Jednostavna animacija :: JavaScript :: Dario

Općenito

Na (X)HTML stranicama, prikaz sekvence slika koje se izmjenjuju, normalno se radi animiranim GIF-om. Pojedinačne slike u GIF formatu mogu se npr. programom Ulead GIF Animator poslagati u sekvencu, može se odrediti trajanje prikaza pojedine slike i način na koji se slike izmjenjuju. Tako napravljen animirani gif, osim za prastare preglednike, moguće je promatrati kao "običan" gif.

Animirani gif nije rješenje za sve slučajeve. Ako želim izmjenjivati slike, puno efikasnije ih je držati u jpg formatu (koji ima bolju kompresiju, pa slika zauzima manje prostora i brže dolazi do preglednika) i tako pojedinačne slike izmjenjivati. Dodatno, kod prikaza animacije, mogu prikazati prvu sliku, i dok se ona prikazuje, pripremiti slijedeću. Efektivno, korisniku se puno brže prikazuje stranica.

Kod izmjene slika mogu koristiti efekt pretapanja ili miješanja slika (engl. blending) u preglednicima koji ga podržavaju.

Princip postupnog unapređenja (engl. progressive enhancement)

Ako primjenimo princip postupnog unapređenja na izradu web stranica, prvo krećemo s izradom stranica za najlošije preglednike. Kasnije unapređujemo stranice, na način koji lošijim preglednicima ne predstavlja problem, a korisnicima s boljim preglednicima pruža potpuniju informaciju. Na početku (u jezgri), koristimo strukturalne semantičke oznake (engl. tag) koje nadograđujemo prezentacijskim unapređenjima definiranim u CSS pravilima. Struktura čini prvi sloj, CSS formira drugi. Na sve to, možemo definirati pravila ponašanja DHTML -om, što nam predstavlja treći sloj. DHTML ponašanja kodiraju se u JavaScript-u, a vrlo često taj JavaScript dinamički mijenja HTML i/ili CSS, pa sloj ponašanja zapravo nadograđuje strukturu i prezentaciju, po potrebi mijenjajući ih za svoje potrebe.

Tehnologije poput (X)HTML, CSS, JavaScript, DOM sadržane su u ovakvoj slojevitoj arhitekturi, koju nazivamo slojevito semantičko označavanje (engl. Layered Semantic Markup, LSM).

Ovaj pristup ima niz prednosti pred drugim tehnologijama, uključivši podršku zastarjelim preglednicima i uređajima. Budućnost ne donosi isključivo samo napredne tehnologije, što se može dobro vidjeti kod prenosnih uređaja.

Sadržaj mora biti dostupan svima (ne misli se samo na ljude s posebnim potrebama), pa čak i bez prezentacije. Prezentacija može postojati bez ponašanja. Slijedi kako slojevi moraju biti dobro izolirani i nezavisni. Ako preglednik ne podržava DHTML svojstva koja koristimo, taj nedostatak treba utjecati (na njegovo viđenje stranice) što je manje moguće. Stranica mora raditi i bez DHTML unapređenja, a eventualne greške korisniku ne treba pokazivati.

Nenametljiv (engl. unobtrusive) JavaScript

Tehnike koje odvajaju sloj ponašanja jednim imenom nazivamo nenametljiv (engl. unobtrusive) JavaScript. Nenametljivi JavaScript izdvojen je u zasebne datoteke, ne pojavljuje se unutar XHTML-a, vidimo jedino (unutar <head> dijela):

<script type="text/javascript" src="scripts.js"></script>

Naziv nenametljivi JavaScript zapravo promovira bolji način kodiranja, koji se koristi za unapređenje funkcionalnosti i/ili izgleda dokumenta koji je korisnik otvorio. Funkcionalnost i/ili izgled ne smiju ovisiti o JavaScript-u, između ostalog zato što:

Umjesto "starog" način kodiranja, koji provjerava koji preglednik se koristi (engl. browser sniffing), bolje je prije upotrebe objekta (funkcije ili svojstva) provjeriti da li on postoji (engl. feature sniffing). Zagovornici nenametljivog JavaScript-a, u pravilu, neće trošiti vrijeme na podršku preglednika koji nemaju "pristojnu" DOM podršku. Drugim riječima, vrijeme testiranja document.layers (NS4) ili document.all (<IE5) je prošlo. Moderni preglednici podržavaju document.getElementsById i to je ono što koristimo.

JavaScript kod može brzo biti prenapučen globalnim varijablama. Zato je najbolje svoje varijable "sakriti" u funkcije ili objekte, kako bi naše skripte mogle raditi zajedno sa skriptama drugih (izbjegavajući "tuču" za varijable, odnosno mijenjanje vrijednosti tuđim varijablama).

JavaScript specifičnosti

JavaScript omogućava rad s objektima na svoj specifičan način. Objekt se definira kao funkcija (ne postoji razlika u sintaksi), a njegovi članovi (engl. members) i metode navode se s prefiksom this.. Objektima možemo dodavati metode naknadno, ne u samoj funkciji kojom definiramo objekt, definirajući "prototype" anonimne funkcije. Objekt instanciramo (tj. napravimo novi) ključnom riječi new, koja poziva funkciju kojom smo definirali objekt (efektivno djeluje kao konstruktor objekta). Primjer:


function set_slide_show() {
  var s = new slide_show('picture', 3000,
    ['images/slide1.jpg', 'images/slide2.jpg', 'images/slide3.jpg', 'images/slide4.jpg']);
  if (s.ready()) {
    s.rotate();
  }
}

function slide_show(div_id, pause, slides, opacity_start, opacity_step,
  opacity_interval, dnload_check) {
  this._div_id = div_id;  // container id
  this._slides = slides;  // array of images
  // postavljanje drugih varijabli
  var o = document.getElementById(this._div_id);
  if (o) {
    // ako element postoji
      this._slide_ready = true;
  }
}

slide_show.prototype.ready = function () {
  return this._slide_ready;
}

U ovom odsječku, objekt je definiran u funkciji slide_show, a instanciran u funkciji set_slide_show. Metoda (funkcija) ready() objekta slide_show dodana je u zadnjim redovima primjera anonimnom funkcijom. Kao što se vidi u primjeru, kad se pristupa drugim dijelovima objekta (dakle iz konstruktora ili neke od metoda objekta), koristi se prefiks this.

JavaScript ne razlikuje privatne (engl. private) i javne (engl. public) članove i metode. U primjeru, logično privatnim članovima naziv počinje podvlakom (engl. underline).

U funkciji set_slide_show, kod instanciranja objekta, konstruktoru prosljeđujemo parametre (treći parametar je anonimno polje s imenima slika, preciznije relativnim path-om do slika). Ako je objekt uspješno instanciran (provjerom statusa preko s.ready() metode), poziva se metoda koja rotira slike (s.rotate()).

U funkciji slide_show treba primijetiti provjeru egzistencije objekta. Pozivom var o = document.getElementById(this._div_id); dobiva se objekt ili nedefinirana (engl. undefined) vrijednost. Kako nedefinirana vrijednost u logici JavaScript-a odgovara neistini (engl. false), redom if (o) { počinje kodni blok koji se izvršava samo u slučaju da je vrijednost varijable "o" objekt.

Pretapanje slika

Microsoft IE verzija 4.0 uvodi filtere, kojima je moguće postići razne prelazne, tranzitivne efekte. Filteri nisu standardizirani te ih drugi preglednici ne podržavaju. Filter je moguće primijeniti kod učitavanja stranice ili preklapanja elemenata (slojeva). Mene zanima alpha filter kojem mogu specificirati razinu (ne)prozirnosti.

Gecko bazirani preglednici (Firefox, Mozilla, ...) počinju od proljeća 2005-te godine podržavati neprozirnost (engl. opacity). Prema W3C specifikaciji, u CSS pravilima moguće je navesti razinu neprozirnosti.

Slično rade starije verzije Gecko baziranih preglednika, samo koriste naziv MozOpacity (umjesto jednostavno opacity) za CSS svojstvo. Starije verzije Safari i Konqueror preglednika koriste naziv KHTMLOpacity.

Za svaku vrstu pretapanja (filter, W3C ili jednostavna zamjena slika), pripremljena je metoda unutar objekta. Konstruktor objekta testira koju verziju pretapanja je moguće primijeniti i spremi izabranu funkciju u _updateOpacity. Kasnije, poziva se funkcija spremljena kao _updateOpacity.

Postupak se svodi na definiranje dvije pozadine, platna (engl. canvas) na koje se postavljaju slike. U normalnom stanju, na jednoj pozadini prikazujemo "aktivnu" sliku. Kod zamjene slike, postupak je:

Učitavanje slika

Izmjenjuju se dvije pozadine, tako da se na "neaktivnoj" pozadini priprema slijedeća slika. Broj slika nije ograničen, ali se one učitavaju samo jednom (nakon toga su u cache memoriji). U startu, prikazana je "aktivna" slika na njenoj podlozi. Konstruktor slide_show objekta napravi drugu pozadinu i na njoj mjesto (img element) za drugu sliku, te pokrene postupak učitavanja druge slike. Vrijeme prikazivanja "aktivne" slike treba biti duže od vremena potrebnog za učitavanje slijedeće slike sa servera pa kad dođe vrijeme za zamjenu slike, imamo slijedeću sliku spremnu.

U slijedećoj iteraciji, funkcija rotate() pokrene postupak učitavanja treće slike. Funkcija pripremi drugu sliku (koja je učitana) i pokrene postupak zamjene slika. Postupak zamjene svodi se na povećanje neprozirnosti nove slike, pauzu te ponovo povećanje neprozirnosti. Taj postupak ponavlja se dok neprozirnost ne dostigne vrijednost 100 (potpuna neprozirnost).

Pogledajte

Naslovna stranica