Flash MX: Reakce na změnu velikosti scény - Grafika.cz - vše o počítačové grafice

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Poptávka práce


Webdesign

Flash MX: Reakce na změnu velikosti scény

flash velikost resize

1. listopadu 2002, 00.00 | Flash MX přišel se zajímavou novinkou: Při změně velikosti plochy vyhrazené pro objekt SWF už nemusí nutně dojít k prostému zvětšení nebo zmenšení zobrazovaného obsahu. Designér může sám definovat, co se má při změně velikosti provést.

Flash se čím dál víc používá jako prostředek pro tvorbu běžného uživatelského rozhraní aplikací. Některé panely, které jsou součástí uživatelského rozhraní samotného Flashe MX (panel "Answers" nebo panely přiinstalované spolu s produkty Flash Remoting a Flash Communication Server) jsou řešené jako aplikace SWF. Možná jste si lámali hlavu, jak je možné, že při změně jejich velikosti se tak šikovně přeskupuje jejich obsah. Po prostudování tohoto článku už budete vědět, jak na to.

Až do verze 5 se objekt ve formátu SWF choval podobně jako běžný obrázek: Pokud jsme jej zvětšili nebo zmenšili, celý obsah se překreslil tak, aby využil vymezenou plochu. V kombinaci s vektorovým charakterem flashové grafiky se to jevilo jako velmi výhodné a nabízelo se vkládat do stránek objekty SWF s variabilními rozměry (nastavenými např. na 100 %). Ovšem jakmile začneme kombinovat vektory s bitmapami nebo se pustíme do speciální "pixelově" orientované grafiky, je uživatelská manipulace s rozměrem vymezené plochy nežádoucí – v jiné než původně zamýšlené velikosti není výsledek tak hezký. Designéři tedy seškrtali ze svých HTML kódů procenta a zůstali u fixních rozměrů. S příchodem Flashe MX ale procenta můžeme zase oprášit a ve vhodných případech povolit uživatelům měnit velikost scény. Nyní totiž můžeme sami skriptem reagovat na tyto změny. Místo zvětšování a zmenšování můžeme nechat objekty přeskupovat, při nezměněné velikosti. A nebo obě možnosti zkombinovat v rámci jedné aplikace (jak si ukážeme v následujícím příkladu), či reagovat na změnu velikosti úplně jinak.

Objekt Stage

Nástroje, které slouží k tomuto účelu, jsou soustředěny v nově zavedeném objektu Stage. Jedná se o třídu, k jejímž vlastnostem a metodám přistupujeme přímo, bez vytváření instancí konstruktorem (tedy obdobně jako např. u objektů Math či Key). Se všemi vlastnostmi a metodami objektu Stage (je jich jen několik) se setkáme v následujích příkladech (s výjimkou vlastnosti showMenu, která však není příliš přínosná, protože umožňuje to, co bylo možné už dříve, ovšem pouze pomocí parametrů v HTML: nastavit, zda má být uživateli dostupné systémové menu Flash Playeru).

Přistupme tedy rovnou k tomu nejdůležitějšímu. Kam umístit skript, který bude řešit reakci na změnu velikosti scény? ActionScript je objektový jazyk orientovaný na zpracování událostí, proto nás nepřekvapí, že i pro změnu velikosti scény je zavedena speciální událost. Tato událost vyvolá ovladač události (event handler), což je metoda, která se v tomto případě musí jmenovat onResize. Ale pozor, je zde jeden podstatný rozdíl oproti dosud známým ovladačům událostí jako jsou onRollOver nebo onLoad. Událost onResize musíme zpracovat pomocí tzv. listenerů. To je další novinka Flashe MX, proto se u ní na chvíli zastavme.

Odbočka: Co to jsou listenery?

Listener ("posluchač") řeší problém, jak na jednu událost reagovat více různými skripty na více různých místech aplikace. Tím se liší od mechanismu obyčejných ovladačů událostí, kdy přiřazením funkce příslušnému ovladači "obsadíme" danou událost výlučně naší funkcí a případný předchozí ovladač této události je přepsán. Pomocí listenerů můžeme připojit ovladač události bez obav, že tím zrušíme ovladače připojené stejné události na jiných místech aplikace.

Ukažme si to právě na příkladu události onResize. Pokud by onResize byl obyčejný ovladač události, přiřadili bychom mu nějakou funkci (Stage.onResize = mojeFunkce;) a při inkriminované události (změně velikosti scény) by se vyvolala právě a pouze tato funkce. Jelikož je však událost onResize řešena mechanismem listenerů, řešení musí vypadat takto:

mujListener = new Object();
mujListener.onResize = function () {
	trace ("Scena zmenila svou velikost.");
}
Stage.addListener(mujListener);

Vyzkoušejte si tento příklad – kód zapište do prvního snímku nově vytvořené aplikace a tu pak spusťte uvnitř vývojového prostředí Flash MX. Vždy, když změníte velikost okna s běžící aplikací (případně celého Flashe MX), do okna "Output" se vypíše text "Scena zmenila svou velikost.".

Jak vidíte, onResize vlastně vůbec není metodou objektu Stage. Jedná se o tzv. callback metodu, patřící nějakému jinému objektu. Tento objekt pomocí metody addListener zaregistrujeme u objektu Stage jako nový listener, tedy objekt, který bude informován, dojde-li k dané události. A to právě vyvoláním jeho callback metody onResize. Tímto způsobem můžeme na různých místech aplikace zaregistrovat různé listenery a reagovat tak na danou událost různými způsoby, které se vzájemně neovlivňují. Pokud budeme chtít listener odregistrovat, použijeme metodu removeListener:

Stage.removeListener(mujListener);

Objektem, který registrujeme jako listener, může být obecně jakýkoliv objekt, nikoliv pouze instance třídy Object, tak jako v uvedeném příkladu. Jedinou podmínkou je, aby listener definoval metodu příslušného názvu odpovídající události, na kterou chceme reagovat. V praxi může být listenerem například movie clip, který v příslušné callback metodě definuje takovou reakci na danou událost, která se týká právě jeho. Toto řešení se mi jeví jako nejpřehlednější, proto jsem ho zvolil i v následující komplexní ukázce.

Ukázková aplikace

Nejprve se podívejte na výslednou aplikaci. Skládá se z několika komponent, z nichž každá reaguje na změnu velikosti scény jiným způsobem. Modrá hlavička má pevnou výšku a šířka se roztahuje přes celou scénu. Po stranách jsou šipky, které chceme mít umístěné vždy na okraji, nápis mezi nimi chceme mít vycentrovaný. Zbytek plochy pod hlavičkou je vyplněn oranžovým boxem. Ten může měnit svou velikost, aby co nejlépe využil plochu, která je k dispozici, ale nesmí se zdeformovat, poměr stran boxu musí zůstat zachován.

Nyní si můžete stáhnout zdrojový kód ukázky a pustit se do jeho zkoumání.

Na prvním snímku hlavní časové osy jsou uvedeny tyto dva příkazy:

Stage.scaleMode = "noScale";
Stage.align = "TL";

Tyto příkazy jsou nutností, chceme-li dále reagovat na změnu velikosti scény vlastními skripty. Pokud bychom je vynechali, aplikace by se nechovala tak, jak chceme. scaleMode je základní vlastnost, která určuje, jak bude Flash reagovat na změnu velikosti scény. Z dostupných hodnot (exactFit, showAll, noBorder a noScale) nás bude zajímat noScale, která zaručí, že nebude docházet ke změně velikosti zobrazovaného obsahu (význam ostatních hodnot si místo složitého popisování v případě zájmu raději vyzkoušejte sami). Druhá vlastnost – align – určuje, kam bude vykreslovaný obsah zarovnán. Dostupné hodnoty jsou tvořené kombinací písmen vyjadřujících vertikální a horizontální zarovnání. Příkladem je TL (top left), což je hodnota, která nás bude zajímat – obsah bude zarovnán do levého horního rohu, což je nastavení, které dává smysl, chceme-li mít reakci na změnu velikosti scény plně pod kontrolou.

Hlavní časová osa naší ukázky (kořenový klip) obsahuje dva klipy: mcHlavicka a mcBlok – kód zajišťující reakci na změnu velikosti scény najdete u obou z nich na jejich prvním snímku:

Klip mcHlavicka definuje tento skript:

onResize = function () {
	mcPodklad._width = Stage.width;
	mcSipkaPrava._x = Stage.width;
	tfTitulek._width = Stage.width;
	tfTitulek.text = 
		"Aktuální rozměry scény: " 
		+ Stage.width + "px X " 
		+ Stage.height + "px";
}
Stage.addListener(this);
onResize();

Metoda onResize upraví šířku podkladu hlavičky, pozici pravé šipky (levou šipku netřeba posunovat, je vždy v levém horním rohu) a šířku textového pole pro titulek (toto pole má nastaveno centrování textu, proto není třeba měnit pozici pole, ale jen jeho šířku, která musí být vždy nastavena na 100 % šířky celé scény). Navíc je text pole dynamicky nastaven tak, aby zobrazoval aktuální rozměry scény. Povšimněte si vhodného umístění středových bodů (center point) všech objektů, které bylo navrženo s ohledem na jednoduchost skriptu pro překreslení objektů v závislosti na velikosti scény.

Příkazem Stage.addListener(this); zaregistrujeme klip mcHlavicka jako listener objektu Stage. Tím zajistíme, že metoda onResize bude v vždy v pravou chvíli zavolána. Nakonec ještě metodu onResize zavoláme hned při inicializaci klipu, aby došlo ke správnému překreslení hned při prvotním spuštění aplikace. Událost onResize se totiž nevyvolá hned při spuštění aplikace, ale teprve poté, co poprvé změníme velikost scény.

Klip mcBlok definuje o něco složitější skript:

vychoziSirka = _width;
vychoziVyska = _height;
onResize = function () {
	var sirka = Stage.width;
	var vyska = Stage.height - _parent.mcHlavicka._height;
	var zmenaSirky = sirka / vychoziSirka * 100;
	var zmenaVysky = vyska / vychoziVyska * 100;
	if (zmenaSirky < zmenaVysky) {
		_xscale = zmenaSirky; _yscale = zmenaSirky;
	}
	else {
		_xscale = zmenaVysky; _yscale = zmenaVysky;
	}
	_x = sirka / 2;
	_y = vyska / 2 + _parent.mcHlavicka._height;
}
Stage.addListener(this);
onResize();

Než začneme definovat metodu onResize, zapamatujeme si pomocí proměnných vychoziSirka a vychoziVyska původní rozměry bloku (tj. celého klipu). Metoda onResize nejprve do proměnných sirka a vyska dosadí aktuální dostupnou výšku a šířku plochy vymezené pro náš blok. Dostupná šířka je rovna šířce celé scény, dostupnou výšku je ale třeba zmenšit o výšku hlavičky. Dále je vypočítán koeficient zmenšení/zvětšení výšky a šířky vzhledem k výchozím rozměrům bloku. Je pochopitelné, že chceme-li zachovat proporce bloku (nezdeformovat jej), tak tento koeficient musí být stejný pro výšku i šířku a musí to být menší z těch dvou zjištěných. To řeší následující podmiňovací příkaz. Nakonec ještě vypočítáme nové souřadnice bloku. Středový bod je tentokrát vhodně umístěný ve středu bloku, takže stačí zjistit polovinu dostupné výšky a šířky (a u výšky opět nezapomenout na posunutí o výšku hlavičky). A hotovo! Zbývající dvě řádky skriptu jsou stejné jako u klipu mcHlavicka, kde také byl vysvětlen jejich smysl.

Jednoduché, že? Řekl bych, že dokonce jednodušší než podobná řešení při návrhu layoutu HTML stránek, kde jsou takové úkoly každodenní starostí webdesignéra a řeší se obvykle pomocí CSS nebo kombinací CSS a JavaScriptu.

Na závěr ještě poznámku o vkládání objektů SWF do HTML stránek. Jak můžete vidět v této ukázce, k roztažení plochy dokumentu na celou dostupnou plochu okna prohlížeče a vynulování okrajů je použita definice kaskádovými styly (CSS), v souladu s dnešním trendem veškeré formátování svěřit tomuto modernímu standardu. Aby ale všechno fungovalo tak, jak má, i ve starších prohlížečích (dnes už můžeme říct opravdu starožitných), bylo by nutné uchýlit se k tradičnímu způsobu založenému na tabulce (s výškou a šířkou nastavenou na 100%) a zastaralých atributech elementu BODY pro vynulování okrajů dokumentu.

Tématické zařazení:

 » Rubriky  » Go verze  

 » Rubriky  » Webdesign  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: