Intro til Flash Camo: Part 1

Intro til Flash Camo: Del 1
Del
Del
Del
Del
Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Velkommen til en introduksjon av Flash Camouflage Work. Flash Camo (for kort) er en grafikk rammeverk som er delt opp i 3 kjerneområder: "dekor", den "CSS parser", og "CamoDisplay". Disse systemene kan brukes enkeltvis eller kombineres for å passe dine behov. Når den brukes sammen danner de et kraftig sett med verktøy for å hjelpe huden og style alle Flash program. Med Camo modulære tilnærming, kan du bruke så lite eller så mye av rammen som du vil.

I denne todelte opplæringen vi skal bygge en enkel nettside for å vise hvor enkelt det er å innlemme Flash Camo inn i neste prosjekt



Forhåndsvisning

Vi kommer til å gjenskape "Bobble Person nettstedet Launcher" fra http:. //jessefreeman.com

Trinn 1:. kassen Flash Camo 2.2

I denne opplæringen vi skal bruke Flex Builder. Hvis du ikke har jobbet i Flex Builder eller trenger hjelp til å få en Flex Library prosjekt oppsett, ta en titt på min "Flash Development Sandbox Tutorial" (del 1 og del 2). Denne opplæringen vil også lede deg gjennom å laste ned og sette opp Flash Camo fra SVN. For dette prosjektet skal vi bruke versjon 2.2 av rammeverket, kan du sjekke det ut her:

http://flash-camouflage.googlecode.com/svn/tags/FlashCamo_2.2.0_beta

Trinn 2: Sette opp Våre prosjekt

Opprett et nytt prosjekt kalt BobbleHeadApp og sørg for at du kobler den til Flash Camo SWC vi sjekket ut i trinn 1.

Du vil trenger også følgende arkivet å komme i gang. Laste dem ned fra her og plassere dem i html-malen mappen. Jeg har tatt med en oppdatert html-malfil knyttet til SWFObject sammen med oppsettet av våre eksterne ressurs mapper

Trinn 3:. Opprette en Flash Camo Doc Class

Nå som vi har vårt prosjekt og ressurser satt opp, la oss starte med vår Doc Class (BobbleHeadApp.as). Du bør bytte ut doc klasse med følgende kode:
pakke {import flash.display.Loader; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.net.URLRequest; [SWF (width = "600", height = "400", bakgrunnsfarge = "# 3A3E4A", framerate = "31")] public class BobbleHeadApp strekker Sprite {private Var fontSWF: Loader; offentlig funksjon BobbleHeadApp () {configureStage (); loadFonts (); } Private funksjon configureStage (): void {stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; } Private funksjon loadFonts (): void {fontSWF = new Loader (); fontSWF.contentLoaderInfo.addEventListener (Event.COMPLETE, onFontsLoaded); fontSWF.load (ny URLRequest ("SWF /skrifter /FontLibrary.swf")); } Private funksjon onFontsLoaded (hendelse: Hendelse): void {fontSWF.contentLoaderInfo.removeEventListener (Event.COMPLETE, onFontsLoaded); i det( ); } Beskyttet funksjonen init (): void {trace ("Hello World"); }}}

Noen ganger når jeg tester lokale filer du kan få følgende feilmelding:


Feil # 2044: Ubehandlet SecurityErrorEvent :. text = Feil # 2140: Sikkerhets sandkasse brudd: ... Lokale-med-filsystem og lokal-med-nettverk SWF-filer kan ikke laste hverandre

Hvis dette skjer med deg, legge til følgende ". -Bruk-nettverk = false "i prosjektene kompilatoren argumenter. Dette vil omgå sikkerhets Sandbox problemer du kan få mens lokalt testing.

Nå bør du være klar til å kompilere swf og ta en titt på utgangen vinduet. Du vil se "Hello World":

Hvis du sjekker dine forbindelser skriften swf skal ha blitt lastet:

Trinn 4: Opprette et globalt PropertySheet leder

Vi re kommer til å trenge et sentralt sted å lagre og få tilgang til våre CSS egenskaper. Før vi gjør dette la oss snakke om CamoPropertySheet. Du kan ha brukt CSS med Flash i det siste, men dette er noe helt nytt og unikt til Flash Camo. Camo tilpassede CSS parser, den "CamoPropertySheet" (finnes på innsiden av "camo.core.property" pakken), går langt utover den opprinnelige Stylesheet klassen ved å støtte stil arv, pseudo velgere og sammenslåing stiler på fly. Målet med CamoPropertySheet er å lage stiler noe du kan bruke på noen av dine klasser i stedet for bare textfields. CSS er en fin måte å definere klasse eiendommer i en ekstern fil og Camo hjelper konvertere disse CSS-stiler i eiendom /verdi-par du kan bruke til noe. Camo har også en CamoPropertySheetManager (finnes på innsiden av "camo.core.managers" -pakken) klasse for å håndtere flere CamoPropertySheets i ett program.

Siden vil vi trenger alle våre klasser for å ha tilgang til CamoPropertySheetManager Vi re kommer til å skape en Singleton. Dette Singleton vil håndheve én forekomst av vår CamoPropertySheetManager. Jeg er ikke en stor fan av enkeltfødte, men i situasjoner som dette de er et nødvendig onde. Vi trenger en enkelt klasse forekomst ansvarlig for å administrere og retur etterspør PropertySelectors. Jeg vil forklare senere hva en ProperySelector er og hvordan det vil fungere i søknaden vår.

La oss lage en ny klasse kalt "GlobalPropertySheetManager" og sette den i "com.jessefreeman.managers" pakken.
< p> Her er klassen kode:
pakke com.jessefreeman.managers {import camo.core.managers.CamoPropertySheetManager; public class GlobalPropertySheetManager {public static konst INIT: String = "init"; privat Static Var __instance: CamoPropertySheetManager; offentlig funksjon GlobalPropertySheetManager (håndhever: SingletonEnforcer) {if (håndhever == null) {kaste nytt Feil ("Feil: forekomst mislyktes: Bruk GlobalDecalSheetManager.instance i stedet."); }} Public static funksjon få forekomst (): CamoPropertySheetManager {if (GlobalPropertySheetManager .__ eksempel == null) {GlobalPropertySheetManager .__ eksempel = new CamoPropertySheetManager (); } Returnere GlobalPropertySheetManager .__ eksempel; }}} Intern klasse SingletonEnforcer {}

Det er mange måter å lage en Singleton og diskusjonen er litt ute av omfanget av denne opplæringen. La oss raskt snakke om hva som skjer her. Siden Actionscript 3 klasser er ikke i stand til å ha private konstruktører er det ingen måte å skjule konstruktøren av en klasse. I stedet for å la den klassen som skal opprettes gjennom den vanlige "nye" konstruksjon vil vi håndheve ringe GlobalPropertySheetManager.instance for å få en referanse til klassen. De eksempel getter sjekker for å se om klassen allerede er opprettet, hvis klassen ikke eksisterer det skaper en ny CamoPropertySheetManager. Hvis forekomsten finnes det vil returnere en referanse til den forekomsten. Dette sikrer at vi bare har en forekomst av CamoPropertySheetManager i hele vårt program. Nå er vi klare til å starte lasting i vår CSS

Trinn 5:. Loading PropertySheet CSS

CamoPropertySheetManager har ingen måte å laste CSS, i stedet vil vi levere lasten mekanisme og fortelle det å analysere de lastede data. Vi vil begynne med å skape vår belastning metoden ved å gjøre bruk av URLLoader. Legg til følgende metoder til vår Doc Class etter "onFontsLoaded" funksjon:
privat funksjon loadPropertySheet (): void {trace ("Legge CSS"); propSheet = GlobalPropertySheetManager.instance; Var loader: URLLoader = new URLLoader (); loader.addEventListener (Event.COMPLETE, onPropertySheetLoad); loader.load (ny URLRequest ("css /main.properties.css"));} private funksjon onPropertySheetLoad (hendelse: Hendelse): void {var target: URLLoader = event.target som URLLoader; target.removeEventListener (Event.COMPLETE, onPropertySheetLoad); propSheet.parseCSS ("global.properties", target.data); spor ("PropertySheetSelectors", propSheet.getPropertySheet ("global.properties") .selectorNames); init ();}

Du må også legge til følgende egenskaper til Doc Klasse:
private Var propSheet: CamoPropertySheetManager;

Så importere følgende klasser:
import flash.net.URLLoader; import camo.core.managers.CamoPropertySheetManager, import com.jessefreeman.managers.GlobalPropertySheetManager;

Til slutt vil vi bare endre vår onFontsLoaded metode for å ringe loadPropertySheet ved å erstatte:
init ();

med:
loadPropertySheet ();

Siden URLLoader kan lastes inn i hvilken som helst tekstfil, vi bare legger i våre egne CSS deretter gi det ut til CamoPropertySheetManager eksempel at vi har fått fra GlobalPropertySheetManager. Legg merke til hvordan vi kalt "parseCSS" og bestått i et navn på vår PropertySheet sammen med strengen data vi bare lastet. Det er alt du trenger å gjøre for å få Camo analysere din css. Senere vil vi snakke om hvordan vi får våre stiler, men her er litt mer info på PropertySheet system i camo.

Når CSS analyseres, kan du hente en rekke velger navn ved å kalle "selectedNames" getter. En velger representerer navnet på den spesielle CSS stil og sin samling av verdier. Den "getSelector" metoden vil returnere velgeren og dens egenskaper som en "PropertySelector". Nye velgere kan legges til CamoPropertySheet ved å kalle "newSelector" og passerer et navn velger og en PropertySelector eksempel. Til slutt kan du duplisere en CamoPropertySheet ved å ringe "klone". Vi vil dekke dette mer som vi begynner å bygge ut våre komponenter

Trinn 6:. Testing CSS parser

Nå er en god tid for å teste at vår CSS parser fungerer. La oss åpne opp css filen i "html-tempalte /css /main.properties.css" og legg til følgende type:
.TestStyle {x: 100px; y: 100px; width: 100px; høyde: 100px; background-color: # ff0000; border: 1px solid # 000000;}

Hvis du arbeider i Flex Builder og endre filer i html-malen mappen du vil trenge ren prosjektet. Du kan gjøre dette ved å gå til Prosjekt > Ren ... og velge de prosjektene du ønsker å rengjøre. Når du rengjør et prosjekt, gjør det en ny kopi av html-malen mappen over til bin mappen. La oss si at du endrer noe i html-mal deretter legge til en ny linje med kode. Flex Builder pre-former automatisk en ren. Denne situasjonen skjer bare når du redigerer en fil i html-malen og ikke gjøre en ren. Stol på meg, vil dette trinnet spare deg utallige timer med frustrasjon prøver å finne ut hvorfor endringene ikke er å dukke opp i nettleseren. Jeg pleier å kartlegge ren prosjektet handling for å Tilvalg + Kommando + c siden jeg bruker det så mye.

Nå hvis du rekompilere swf og se på resultatet bør du se navnet ".TestStyle" velgernavnet ved siden av den "PropertySheetSelectors" spor.

La oss prøve å hente vår stil og spore den ut. Erstatt:
trace ("PropertySheetSelectors", propSheet.getPropertySheet ("global.properties") .selectorNames);

innsiden av onCSSLoad fra vår Doc Class med dette:
trace ("Test Selector", propSheet. getSelector ("TestStyle."));

Nå når du kompilere bør du se følgende:
Test Selector .TestStyle {x: 100; høyde: 100background-color: # ff0000; border: en solid # 000000; selectorName: .TestStyle; y: 100; width: 100;}

Dette er den strengverdien av vår PropertySelector. Ser ut som et objekt rett? Vel det er fordi det er! Camo sin css parser konverterer css velgere inn innfødte stedene. Det er viktig å merke seg at hver verdi er fremdeles en streng. Senere vil vi snakke om hvordan å konvertere disse strengene til opprinnelig skrevet verdier, slik at du kan bruke dem til noe objekt eller klasse i programmet. La oss begynne å bygge grunnlaget for vårt prosjekt

Trinn 7:. Opprette en AbstractComponent

Nå er vi klare til å begynne å bygge våre komponenter. Vi ønsker alle våre komponenter for å arve evnen til å finne sin egen CSS stil automatisk. Hvis du ikke er kjent med hva en abstrakt klasse er, kan du bli overrasket over å høre at du kan allerede være å bruke dem.

En enkel forklaring på en abstrakt klasse er noen klasse du oppretter som har noen kjernefunksjoner, men skal utvides til å legges spesifikk funksjonalitet.

abstrakte klasser, mye som vår Singleton, bør ikke være direkte instansiert. Tenk på Abstrakt klasse som grensesnitt, men med kode i dem. Vi er ganske enkelt å sette opp et par funksjoner alle komponenter vil trenge, og hver komponent vil legge til ekstra logikk de trenger. Vi kommer til å ringe vår Abstract Class "AbstractComponent" og sette den i "com.jessefreeman.components" pakken.

La oss ta en titt på koden:
pakke com.jessefreeman.components {import camo.core.display.CamoDisplay; import camo.core.property.PropertySelector; import com.jessefreeman.managers.GlobalPropertySheetManager; import flash.errors.IllegalOperationError; public class AbstractComponent strekker CamoDisplay {beskyttet statisk konst ID_DELIMITER: String = ""; beskyttede Var defaultSelectorNames: Array; offentlig funksjon AbstractComponent (selv: AbstractComponent, id: String) {if (! selv = dette) {//bare en underklasse kan passere en gyldig referanse til selv kaste nytt IllegalOperationError ("Abstract klassen ikke fikk henvisning til selv.» + classname + "ikke kan startes direkte."); } Else {parseStyleNames (id); i det( ); }} Beskyttet funksjons parseStyleNames (id: String): void {defaultSelectorNames = id.split (ID_DELIMITER); this.id = defaultSelectorNames.pop (); //Rydde opp velgere defaultSelectorNames.unshift (+ classname "."); defaultSelectorNames.push ("#" + this.id); } Beskyttet funksjonen init (): void {var prop: PropertySelector = GlobalPropertySheetManager.instance.getSelector.apply (null, defaultSelectorNames); applyProperties (prop); }}}

Selv om dette er en liten klasse er det mye å gå på. La oss starte med det faktum at det er forlenge CamoDisplay. Normalt ville vi utvide Sprite eller MovieClip for våre visnings klasser, men fordi vi ønsker å dra nytte av Flash Camo sin BoxModel må vi bygge ut av CamoDisplay. Vi skal snakke om BoxModel og CamoDisplay litt senere.

Hvis du sjekker ut konstruktøren du vil legge merke til er vi ber om to elementer, selv og id. Som vi gå gjennom konstruktøren gjør vi en bekreftelse på at klassen bare kan startes ved å sende en henvisning av seg selv tilbake i konstruktøren. Du vil se hvordan dette fungerer med våre "konkrete" komponenter (en konkret klasse er enhver fullt funksjonell klasse som utvider en abstrakt klasse). Den andre egenskapen id er viktig fordi vi skal bruke den til å slå opp komponentens id fra css. Når Abstract validering har gått, vi kaller den parseStyleName metoden.

parseStyleNames metoden er å gjøre noe spesielt for oss. Hvis du har jobbet i HTML og CSS kan du vite at du kan overbelaste en ID eller klasse tag ved å levere flere CSS velger navn adskilt av et mellomrom. I denne metoden lar vi deg legge til flere IDer atskilt med et mellomrom, og vi analysere dem ut i individuelle IDer. Den siste ID blir den viktigste ID for klassen og vi legge til en "#" til den automatisk. Vi legger også klassens navn, fra en getter av CamoDisplay kalt "classname", til vår liste over velger navn. La oss se på init-funksjonen ved å se hvordan vi bruker denne

I init funksjon vi gjør to ting.; får våre velgere fra GlobalPropertySheetManager og deretter bruke CSS egenskapene til komponenten i seg selv gjennom applyProperties metoden. Ta en titt på hvordan vi kaller den getSelector metoden på GlobalPropertySheetManager. Denne delen kan gjøre hodet eksplodere, men ikke fortvil, garanterer jeg at på slutten av de neste trinnene koden vil kompilere og kjøre fint om du fullt ut forstår hva som skjer.

Først og fremst, vi ønsker å få en forekomst av CamoPropertySheetManager så vi kaller GlobalPropertySheetManager forekomsten eiendom. Husk dette er en Singleton og vi har bare én forekomst av CamoPropertySheetManager. Neste vi kaller sin funksjon "getSelector", men i stedet for å føre inn navn på hver velger vi kaller en funksjon av "getSelector" -funksjonen. Jeg vet dette er gal, men det er noe innebygd i språket. Se "getSelector" er en pause funksjon i Flash. Dette er en funksjon som ikke har et sett antall parametre slik at du kan passere i så mange elementer som du vil. Her er hva funksjonen faktisk ser ut i kildekoden:
offentlig funksjon getSelector (... selectorNames): PropertySelector

Se "... selectorNames"? Det forteller den funksjonen du vil få et beløp av velger navn, så vær forberedt. Siden vi ikke kan bare passere en rekke inn i "getSelector" -metoden (fordi det ville bare se det som en matrise variabel) må vi kalle en spesiell funksjon som heter "apply" for å passere i en rekke argumenter. Moralen i historien er at du kan passere i så mange valg navn som du ønsker inn i "getSelector" -funksjonen og CSS parser vil fusjonere dem alle i én PropertySelector. Hvis du ønsker å forstå mer om resten uttalelser i Flash sjekke dette ut

Nå som er ute av veien, la oss se på et eksempel for å illustrere hva denne klassen vil gjøre

Trinn 8..: Testing AbstractComponent

Vi kommer til å utføre en rask test for å vise hvordan AbstractComponent og BoxModel innsiden av CamoDisplay arbeid. Lag en klasse som heter "SimpleDisplay" i "com.jessefreeman.components" pakken

Her er klassen kode.
Pakke com.jessefreeman.components {public class SimpleDisplay strekker AbstractComponent {offentlig funksjon SimpleDisplay ( id: String = "BoxModelDisplay") {super (dette, id); }}}

Dette er en veldig enkel klasse, det bare utvider AbstractComponent og passerer en referanse til seg selv opp til super (for å passere AbstractComponent validering) og også går opp sin id. La oss teste det ut ved å gå tilbake til vår Doc klasse og legge følgende etter vår Hello World spor innsiden av "init" -funksjon:
Var komponent: SimpleDisplay = new SimpleDisplay ("BoxModelDisplay"); addChild (komponent); < p> og import:
importere com.jessefreeman.components.SimpleDisplay

Nå hvis du kompilere swf, du vil ikke se noe, men SimpleDisplay eksempel er der. Gå inn i CSS-filen og endre navnet på ".TestStyle" til ".SimpleDisplay". Nå rekompilere og du skal kunne se ditt SimpleDisplay.

Utrolig, ikke sant? Den SimpleDisplay funnet automatisk sitt CSS klasse navn og anvendt sine verdier. Forekomster av SimpleDisplay automatisk bruke den ".SimpleDisplay" CSS stil til seg selv nå. La oss legge til følgende stil til vår CSS sheet:
#BoxModelDisplay {background-color: # 00FF00; border-top: 10px;}

Nå når du kompilere vil du se at ID-en til Component overstyrer base klassen stil

Dette er en veldig effektiv måte å tilpasse utseendet og følelsen av. søknaden din. Nå kan du bruke CSS til å style noen klasse som utvider AbstractComponent. Dette er gjort mulig ved Camo sin BoxModelDisplay. Den "BoxModelDisplay" tillater oss å søke Margin, Padding, Border og en bakgrunns (Farge /bilde). Camo sin BoxModel fungerer akkurat som CSS-tallet. Her er et diagram:

Som du kanskje husker, utvidet vårt AbstractComponent den CamoDisplay som igjen forlenger BoxModel. Vel, det CamoDisplay ikke bare arver alle BoxModel layout, men det legger også noen ekstra funksjoner. Du kan lese om alle de BoxModel og CamoDisplay eiendommer i mappen docs din Flash Camo kassa

Trinn 9:. LabelComponent

Vi kommer til å lage en enkel komponent som vil håndtere alle en av tekstene vi trenger i vår søknad. Dette er også en god del for å bidra til å illustrere hvordan ProperySelector virker. For å komme i gang, lage en ny klasse kalt "Label" i "com.jessefreeman.components" pakken

Her er koden:.
Pakke com.jessefreeman.components {import camo.core.enum. CSSProperties; import flash.text.StyleSheet; import flash.text.TextField; import flash.text.TextFormat; public class Etikett strekker AbstractComponent {beskyttet Var _styleSheet: Stylesheet; beskyttet Var Textfield: Textfield = new Textfield (); beskyttet Var proxyTextFormat: tekstformat = new tekstformat (); beskyttet Var _textAlign: String = CSSProperties.LEFT; offentlig funksjon satt autoSize (verdi: String): void {textField.autoSize = validateAutoSize (verdi); ugyldig (); } Offentlig funksjon satt antiAliasType (verdi: String): void {textField.antiAliasType = validateAntiAliasType (verdi); ugyldig (); } Offentlig funksjon sett embedFonts (verdi: Boolean): void {textField.embedFonts = verdi; ugyldig (); } Offentlig funksjon sett skarphet (verdi: Number): void {textField.sharpness = verdi; ugyldig (); } Offentlig funksjon få tekst (): String {return textField.text; } Offentlig funksjon sett tekst (verdi: String): void {textField.text = verdi; ugyldig (); } Offentlig funksjon satt Tekstjustering (verdi: String): void {_textAlign = verdi; ugyldig (); } Offentlig funksjon satt textFieldWidth (verdi: Number): void {textField.width = verdi; ugyldig (); } Offentlig funksjon satt textFieldHeight (verdi: Number): void {textField.height = verdi; ugyldig (); } Offentlig funksjon satt textFieldAlign (verdi: String): void {proxyTextFormat.align = verdi; ugyldig (); } Offentlig funksjon satt fontFace (verdi: String): void {font = verdi; ugyldig (); } Offentlig funksjon sette fontstørrelse (verdi: Number): void {size = verdi; ugyldig (); } Offentlig funksjon sett skriften (verdi: String): void {proxyTextFormat.font = verdi; ugyldig (); } Offentlig funksjon sett farge (verdi: uint): void {proxyTextFormat.color = verdi; ugyldig (); } Offentlig funksjon sett størrelse (verdi: Number): void {proxyTextFormat.size = verdi; ugyldig (); } Offentlig funksjon sett bokstav (verdi: Number): void {proxyTextFormat.letterSpacing = verdi; ugyldig (); } Offentlig funksjon merke (id: String = "label") {super (dette, id); } Ride beskyttet funksjonen init (): void {textField.selectable = false; textField.autoSize = "left"; addChild (tekstfeltet); super.init (); } Ride beskyttet funksjon draw (): void {proxyTextFormat.align = _textAlign; textField.defaultTextFormat = proxyTextFormat; textField.setTextFormat (proxyTextFormat); super.draw (); } Offentlig funksjon setTextFormat (format: tekstformat, beginIndex: int = - 1, endIndex: int = - 1): void {textField.setTextFormat (format, beginIndex, endIndex); } Public static funksjon validateAntiAliasType (verdi: String): String {switch (verdi) {case CSSProperties.ADVANCED: returverdi; gå i stykker; standard: returnere CSSProperties.NORMAL; gå i stykker; }} Public static funksjon validateAutoSize (verdi: String): String {switch (verdi) {case CSSProperties.LEFT: case CSSProperties.RIGHT: case CSSProperties.CENTER: returverdi; gå i stykker; standard: retur CSSProperties.NONE; gå i stykker; }}}}

Som du ser, denne etiketten komponent fungerer som en Textfield gjennom komposisjon. Jeg gjør dette ved å opprette en forekomst av en Textfield og bruker settere til å oppdatere sine verdier. Dette kan virke som over-kill, men ved å gjøre ting på denne måten jeg dra nytte av to funksjoner fra Flash Camo. Først av jeg forlenge AbstractDisplay > CamoDisplay > BoxModelDisplay sett av klasser slik at jeg får CSS styling og BoxModel for "gratis". Også, jeg trenger ikke lenger å opprette en egen tekstformat å style Textfield og bruke den hver gang det er en endring. Denne komponenten tillater meg å bare bruke tekstformat egenskaper og den automatisk oppdaterer tekstfeltet forekomster egenskaper. Dette er viktig når vi ser på hvordan PropertySelectors brukes.

Jeg har allerede vist deg hvordan vår AbstractComponent gjelder automatisk CSS-stiler til våre komponenter, men la oss se på hva som foregår bak kulissene i CamoDisplay når vi kaller " applyProperties ". Her er hva koden ser slik ut:
offentlig funksjon applyProperties (stil: PropertySelector): void {clearProperties (); PropertyApplierUtil.applyProperties (dette, stil); ugyldig ();}

Noen ting skjer her. Først blir alle eiendommer fjernet fra CamoDisplay. Deretter bruker vi et verktøy klasse kalt PropertyApplierUtil å bruke en PropertySelector til CamoDisplay eksempel. Jeg nevnte tidligere at PropertySelectors er objekter som er opprettet fra CSS velgere. Vel verdiene av objektet er strenger, men vi trenger en måte å konvertere en font størrelse til et nummer. Dette verktøyet automatiserer prosessen ved å analysere verdi typer av et klasse offentlige variabler og getters, deretter konverterer den matchende PropertySelector verdier til riktig type. Her er et eksempel.

La oss si at du ønsker å stille skriftstørrelsen på vår etikett komponent. Du kan ha en stil som ser slik ut:
.Label {size: 30;}

Når du bruker ".Label" PropertySelector til etikett forekomst (husk dette gjøres automatisk for oss) PropertyApplierUtil ser for en egenskap kalt "størrelse" på etiketten eksempel. Når den finner det, sjekker den egenskapsverdien. Siden vi har en getter heter størrelse som godtar en tallverdi, vil verktøyet automatisk konvertere PropertySelector størrelse verdi i et antall og sett den på vår komponent. Du trenger ikke å gjøre noe spesielt, håndterer verktøyet opprinnelig Strings, nummer, Arrays, objekter, farger (enheter) og et par andre typer. Så lenge den offentlige variabel har en type verktøyet kan konvertere, vil eventuelle samsvarende egenskaper automatisk settes. Vi vil se dette i aksjon i neste trinn

Trinn 10:. Bruke Label Component

La oss gå inn i vårt Doc klasse og erstatte vår SimpleDisplay demo ved å erstatte init-funksjon med følgende:
beskyttet funksjonen init (): void {trace ("Hello World"); createLabel ();}

Deretter oppretter du en ny funksjon i henhold til vår init funksjon:
privat funksjon createLabel (): void {label = ny etikett ("siteLabel"); addChild (label);}

Ikke glem å legge til følgende parameter:
private Var label: Etikett;

I tillegg til vår import:
import com.jessefreeman.components.Label; < p> Til slutt, vi må legge til følgende stiler til vår css filen:
.Label {font: Arial svart; size: 20px; embedFonts: true; color: #ffffff; anti-alias-type: avanserte;} # siteLabel {text: Anatomy of JESSE FREEMAN; x: 155; y: 60; size: 18px; rotasjon: 24px; brev-Avstand: -2; tekst-høyde: 30px; alpha: 0,5;}

Nå hvis du kompilere swf du bør se din etikett med teksten "Anatomy of JESSE FREEMAN"

Etiketten automatisk brukt ".Label" sammen med "#siteLabel". og stylet seg selv. Se hvor enkelt det var? Noen få linjer med kode, noen CSS og vi er oppe og går i løpet av kort tid.

Nå har du en gjenbrukbar etikett komponent som kan ved stylet med css. Denne klassen er på ingen måte ferdig. Du kan fortsette å legge til så mange getters eller settere som du trenger for å gjøre dette Etikett tilpasses. Jeg bare ga deg et utgangspunkt for å komme i gang med. Når du begynner å forlenge utenfor rammen er det viktig å forstå noen av de underliggende uavgjort logikken

Trinn 11:. CamoDisplay ugyldig

Du har kanskje lagt merke til fra vår etikett komponent som de "oppheve () "Metoden kalles etter at vi endrer en verdi i noen av settere. Redrawing den BoxModel og skjermen er veldig dyrt, så for å lindre byrden av stadig forfriskende displayet, venter CamoDisplay til neste ramme for å tegne seg selv. Denne teknikken brukes i Adobes egne komponenter og er svært effektiv i å kutte ned på innsnevrede cpu prosesser. Det er noe du bør huske på når du utvider CamoDisplay og bruke ugyldig på dine egne settere.

Den andre viktig metode du bør vite om er "draw ()". Etter at displayet har blitt ugyldiggjort og en ny ramme blir gjengitt av Flash Player, blir uavgjort kalt automatisk av CamoDisplay. Hvis du har tilpasset visning logikk dette er det beste stedet for å si det. Når "tegne" kalles, er den ugyldig flagget reset og CamoDisplay vil ikke tegne seg selv før det er ugyldig igjen.

Hvis du gjør komplekse animasjoner som å endre bredde og høyde eller krever stadige oppdateringer, kan du overstyre omstøtelse ved å kalle "refresh ()" til enhver tid. Dette vil umiddelbart tvinge CamoDisplay å tegne. Bruk denne når du trenger å ha konstant vise oppdateringer siden det kan bli svært intensivt for å gjengi

Trinn 12:. Lag en Bobble Container

Vi kommer til å lage en klasse som heter "BobbleContainer" i "com.jessefreeman.components" pakken

Her er koden:
pakke com.jessefreeman.components {import com.jessefreeman.components.AbstractComponent; import flash.events.IEventDispatcher; import flash.events.MouseEvent; public class BobbleContainer strekker AbstractComponent {beskyttet Var _active: Boolean; offentlig Var rollOverForce: Number = 1; offentlig Var noddingForce: Antall = 0; offentlig Var noddingAngle: Antall = 0; offentlig Var noddingRange: Number = 30; offentlig Var noddingHit: Number = 0,7; offentlig Var noddingDamp: Number = 0,985; offentlig funksjon BobbleContainer (id: String = "bobbleContainer") {super (dette, id); } Offentlig funksjon som er aktiv (verdi: Boolean): void {_active = verdi; if (_active) addEventListeners (denne); else removeEventListeners (denne); } Offentlig funksjon får aktiv (): Boolean {return _active; } Ride beskyttet funksjonen init (): void {super.init (); } Beskyttet funksjons addEventListeners (mål: IEventDispatcher): void {target.addEventListener (MouseEvent.ROLL_OVER, onRollOver); target.addEventListener (MouseEvent.ROLL_OUT, onRollOut); } Beskyttet funksjons removeEventListeners (mål: IEventDispatcher): void {target.removeEventListener (MouseEvent.ROLL_OVER, onRollOver); target.removeEventListener (MouseEvent.ROLL_OUT, onRollOut); } Offentlig funksjon calculateBobble (): void {if (noddingForce) {if (noddingForce < 0,05) noddingForce = 0; rotasjon = tak i Math.sin (noddingAngle) * noddingForce * (noddingRange * 0,5); noddingAngle + = noddingHit * noddingForce; noddingForce * = noddingDamp; }} Beskyttet funksjon onRollOver (event: MouseEvent): void {if (noddingForce < (rollOverForce * 0,5)) {noddingAngle = 0; noddingForce = rollOverForce; }} Beskyttet funksjon onRollOut (event: MouseEvent): void {}}}

I vår Doc klasse, la oss lage en BobbleContainer eksempel å teste vår kode med. La oss legge til følgende funksjon under createLabel:
beskyttet funksjon createPerson (): void {bobbleTest = new BobbleContainer ("TestContainer"); addChild (bobbleTest);}

Du vil trenge følgende egenskap:
private Var bobbleTest: BobbleContainer;

deretter import:
import com.jessefreeman.components.BobbleContainer;

For å få dette skal fungere trenger vi å legge til noen flere ting. I vår init funksjon legge til følgende:
createPerson (); addEventListener (Event.ENTER_FRAME, onEnterFrame);

Under init funksjonen add:
privat funksjon onEnterFrame (hendelse: Hendelse): void {bobbleTest.calculateBobble ();}

Vi er nesten ferdig. Legg til følgende i CSS-fil og traff kompilere:
.BobbleContainer {aktiv: true; rollOverForce: 1; roll-over-force: 1; nikker-force: 0; nikker-vinkel: 0; nikker-range: 10; nikker rammede: 0,7; text-align: center;