Selainohjelmointi 2D-animointi verkkosivuilla (JavaScript) (HTML5 Canvas) T-111.1100 Digitaalisen median työvälineet (3 op) ME-C2300 Verkkojulkaisemisen perusteet (5 op) Juuso Lappalainen Mediatekniikan laitos laitos 22. maaliskuuta 2016
Demo: HTML5 Pacman http://arandomurl.com/2010/07/25/html5-pacman.html
Luennon jälkeen osaan toteuttaa yksinkertaisia 2Danimaatioita verkkosivuille HTML5 Canvas:n avulla.
Luennon sisältö Kertausta Animointiteknologiat verkossa HTML5 Canvas HTML Canvas 2D Context Animointi Yhteenveto ja tehtävänanto Luennon ajan rakennetaan livekoodauksena pientä peliä: http://jsbin.com/kekatecese/5/edit?js,output
Kertausta
Javascriptin liittäminen HTML-sivuille 1) Sisäinen <script> elementti 2) Ulkoinen *.js tiedosto
Tapahtumat Yleisimmät tapahtumatyypit Käyttöliittymätapahtumat, esim. load Kohdistustapahtumat, esim. focus Hiiritapahtumat, esim. click, mouseover ja mousemove Näppäimistötapahtumat, esim. keyup ja keydown
jquery jquery on JavaScript-kirjasto, joka helpottaa ja nopeuttaa yleisimpien JavaScript-toimintojen toteutusta asiakaspäässä Yksinkertainen ja tiivis syntaksi Tukee yleisimmin käytettäviä toimintoja Ottaa huomioon selainten väliset eroavaisuudet Laajennettavissa liitännäiskoodin avulla
Debuggaus Selaimen kehitystyökalut Sisäänrakennettu kaikkiin suosituimpiin verkkoselaimiin Työkaluja DOM-puun tarkastelemiseen ja muokkaamiseen JavaScript-debuggeri console.log(... ) metodi Tulostaa viestit konsolille Huomattavasti parempi vaihtoehto kuin vanha alert(... ) metodin käyttäminen à avaa ponnahdusikkunan
Hyvin lyhyesti olio-ohjelmoinnista
Olio-ohjelmointi JavaScriptillä JavaScript on oliopohjainen kieli Ei kuitenkaan tarjoa Javan kaltaista tukea olioohjelmoinnille Ei suoranaisesti tue luokkia, perintää, jne. Voidaan simuloida funktioiden ja prototyyppien avulla Luokkien määrittelyyn useita eri tapoja http://www.phpied.com/3-ways-to-define-a-javascriptclass/ Tarjolla myös erillisiä kirjastoja
Köyhän miehen luokka (joka riittää kurssin tarpeisiin mainiosti J )
Animointiteknologiat verkossa
Animointiteknologioiden vertailu Teknologia Standardi Käyttötarkoitus Grafiikka Ohjelmointi Selain- ja työkalutuki CSS Animations W3C:n työluonnos yksinkertaiset animaatiot, esim. efektit 2D & 3D, pikseli CSS, deklaratiivinen ++ Flash Adoben liitännäinen selaimeen monimutkaiset animaatiot, esim. pelit 2D (& 3D), vektori ActionScript, imperatiivinen ++ HTML Canvas 2D Context + <canvas> W3C:n suositusehdotus monimutkaiset animaatiot, esim. pelit 2D, pikseli JavaScript, imperatiivinen ++ JavaScript-kirjastot useita toteutuksia yksinkertaiset animaatiot, esim. efektit 2D, pikseli JavaScript, imperatiivinen +++ SVG W3C:n suositus yksinkertaiset animaatiot, esim. efektit 2D, vektori XML, deklaratiivinen ++ WebGL + <canvas> Khronos Group:n spesifikaatio monimutkaiset animaatiot, esim. pelit 3D, pikseli JavaScript (OpenGL ES 2.0), imperatiivinen ++
HTML5 Canvas
Yleiskuvaus Käyttötarkoitus Tarjoaa piirtoalueen, johon voi lennossa piirtää 2D- ja 3D-pikseligrafiikkaa sekä kuvia JavaScript API:n avulla. Selaintuki Toimii kaikissa moderneissa työpöytä- ja mobiiliselaimissa Merkintä
Koordinaatisto (0, 0) x y (6, 2)
Koko näyttöalan käyttöönotto 1) HTML määrittelyt 2) CSS määrittelyt 3) JavaScript määrittelyt
www.codecademy.com/courses/web-beginner-en-swm11/0/1 Googleen codecademy canvas
HTML Canvas 2D Context
Yleiskuvaus Käyttötarkoitus Tarjoaa JavaScript-rajapinnan, joka mahdollistaa 2Dpikseligrafiikan ja -kuvien lennossa piirtämisen ja animoinnin piirtoalueelle. Toiminnot Muotojen (esim. suorakulmiot ja ympyrät) piirtäminen Tekstien piirtäminen Kuvien piirtäminen ja pikselimanipulaatioiden tekeminen Sekä paljon muuta!
Muotojen piirtäminen
Muotojen piirtäminen
Trigonometriaa: Ympyröiden kulmat http://net.tutsplus.com/tutorials/javascript-ajax/canvas-from-scratch-advanced-drawing/
Tekstien piirtäminen
Tekstien piirtäminen
Gradienttien, kuosien ja varjojen piirtäminen
Gradienttien piirtäminen
Kuosien piirtäminen
Varjojen piirtäminen
Kuvien piirtäminen ja pikselimanipulaatioiden tekeminen
Kuvan piirtäminen, rajaus ja skaalaus
Pikselimanipulaatioiden tekeminen
Piirtoaluemuunnosten tekeminen
Toiminnot Metodit Erilaisten piirtoaluemuunnosten tekeminen Esim. kiertäminen ja siirtäminen Muunnokset koskevat koko koordinaatistoa
Muunnettu koordinaatisto (0, 0) context.translate( 2, 1); (0, 0) y x (6, 2) (6, 2)
Rajapinta piirtoaluemuunnosten tekemiseen scale(... ) rotate(... ) translate(... ) Metodit transform(... ), suhteellinen muunnos edellisiin nähden settransform(... ), absoluuttinen muunnos edellisiin nähden http://www.w3.org/tr/2dcontext/#canvasrenderingcontext2d
Skaalauksien tekeminen
Kiertojen tekeminen
Siirtojen tekeminen
Absoluuttisten (tai suhteellisten) muunnosten tekeminen
Piirtoalueen tilojen tallentaminen ja palauttaminen
Rajapinta piirtoalueen tilojen tallentamiseen ja palauttamiseen save() restore() Metodit http://www.w3.org/tr/2dcontext/#canvasrenderingcontext2d
Animointi
Timing control for script-based animations (requestanimationframe) Käyttötarkoitus Tarjoaa JavaScript API:n animointiin, jonka ansiosta optimaalisen animointinopeuden määritys voidaan siirtää ohjelmoijalta selaimelle. Selaintuki Chrome 10.0+, Firefox 4.0+, IE 10.0+, Opera 15.0+, Safari 6.0+
Huono tapa animoida setinterval function animate(){ } // update objects // animate at 30 fps setinterval(animate, 1000 / 30);
Rajapinta animointiin Oikea tapa requestanimationframe( ) cancelanimationframe( ) Metodit Selain valitsee parhaan ajan animoinnille Animointi pysähtyy kun ikkuna ei ole aktiivisena Ei mahdollisuutta asettaa aikaa itse http://www.w3.org/tr/animation-timing/
requestanimationframe() function animate(time){ //update objects } framehandle = requestanimationframe(animate); var framehandle = requestanimationframe(animate); FrameHandle on tarpeellinen, jos jossain tilanteessa haluaa pysäyttää animaation. RequestAnimationFrame komennon voi tällöin peruuttaa komennolla: cancelrequestanimationframe(framehandle);
Animaatioiden tekeminen Perusvaiheet 1. Määrittele yleiset muuttujat (esim. velocityx ja velocityy) 2. Määrittele objektit (JavaScript-luokat) 3. Alusta objektit 4. Tyhjennä piirtoalue (koko tai muuttunut osa) 5. Piirrä objektit 6. Muuta objektien tiloja 7. Tarkista törmäykset, vuorovaikutus, yms. ehdot à Toista vaiheita 4-7, kunnes animaatio/peli loppuu (tutoriaali: http://billmill.org/static/canvastutorial/) Animaatiosilmukka
Animaatioesimerkki
Frames per second (FPS) Kuinka monta kuvaa piirretään sekunnissa (kuvia sekuntia kohden) Vaihtelee tietokoneen suorituskyvystä ja kuormituksesta riippuen
Frame-based motion Nopeus muodossa pixels/frame Voidaan ajatella animoinnissa, että jokin objekti liikkuu tietyn matkan jokaisella uudella kuvalla Ohjelmoijan helpompi ymmärtää Mutta: Vaihteleva FPS aiheuttaa sen, että välillä objektit liikkuvat nopeammin ja välillä hitaammin, jos objektin nopeus on määritelty esim. 150 pikseliä x-suunnassa / frame 120 pikseliä y-suunnassa / frame
Frame-based motion pixels / frame = (pixels / second) / fps tai pixels / frame = (pixels / second) * (second / frame) Jos objektin on määrä liikkua 200 pikseliä sekunnissa, ja FPS on 50, silloin sen pitää liikkua tässä framessa 4 pikseliä. (delta on 4) 200/50 = 4
Time-based motion Nopeus muodossa pixels/second Time-based motion = pixels/second on vakio Tällöin nopeus pysyy ajansuhteen vakiona riippumatta kuinka monta kuvaa tietokone pystyy piirtämään sekunnissa (eli riippumatta fps:stä)
Time-based motion var velocityx = 50; // 50 pixels per second var velocityy = 100; // 100 pixels per second animate(time){ // epoch time var elapsedtime = time - lasttime; deltax = velocityx * (elapsedtime / 1000); deltay = velocityy * (elapsedtime / 1000); obj.x = obj.x + deltax; obj.y = obj.y + deltay; } lasttime = time;
Time-based motion vs. Frame-based motion var velocityx = 50; // 50 pixels per second var velocityy = 100; // 100 pixels per second var velocityx = 50; // 1 pixel per second var velocityy = 100; // 2 pixels per second animate(time){ var elapsedtime = time - lasttime; animate(time){ deltax = velocityx * (elapsedtime / 1000); deltay = velocityy * (elapsedtime / 1000); obj.x = obj.x + deltax; obj.y = obj.y + deltay; deltax = velocityx; deltay = velocityy; obj.x = obj.x + deltax; obj.y = obj.y + deltay; } lasttime = time; }
Spritet Pikseligrafiikkana toteutettuja pelihahmoja Usein osittain läpinäkyviä (kuvassa musta) Yleisiä jo hyvin vanhoissa, esim. Commodore 64 ja Amiga:n peleissä Aiemmin toteutettu laitteistotasolla, PC:ssä ohjelmoitavia
Ilmaisia spritejä esim. http://content.gpwiki.org/index.php/game_content_resources#sprites
Sprite kuvien lataaminen // Load Sprite Sheet var marioimage = new Image(); marioimage.src = "img/smb_sprites.png"; // Document ready -> Load sprite sheet image (jquery syntax) $( document ).ready(imageloader); // Image loaded -> start animation function imageloader(){ marioimage.onload = function() { animationframe = requestanimationframe(animate); }; }
Spriten piirto ja päivitys function sprite (options) { var that = {}; that.context = options.context; that.width = options.width; that.height = options.height; that.image = options.image; // Draw current sprite image that.render = function () { // Draw sprite }; that.context.drawimage( ); // Load Sprite Sheet var playerimage = new Image(); playerimage.src = player_sprite_sheet.png"; // Create sprite var player = sprite({ context: cnv.getcontext("2d"), width: 26, height: 35, image: playerimage }); } // Update sprite frame index that.update = function () { }; return that; frameindex based image crop (x) frameindex 0 1 2 3 4 5 6 7 8 9 10 11
Näppäinkomennot ja liikutus event.preventdefault() estää komentoja valumasta eteenpäin (estää esim. sen, että nuolinäppäimet liikuttavat sivua ylös tai alas) Lisätietoa:http://www.markupjavascript.com/2013/10/event-bubbling-how-to-prevent-it.html var KEYCODE_LEFT = 37; var KEYCODE_UP = 38; var KEYCODE_RIGHT = 39; var KEYCODE_DOWN = 40; $(document).keydown(function(e) { }); if (e.keycode == KEYCODE_ESC) { cancelanimationframe(aniframe); } if (e.keycode == KEYCODE_LEFT) { e.preventdefault(); } // do something if (e.keycode == KEYCODE_RIGHT) { e.preventdefault(); // do something } if (e.keycode == KEYCODE_UP) { e.preventdefault(); } // do something if (e.keycode == KEYCODE_DOWN) { e.preventdefault(); // do something }
Hiirikoordinaattien muuntaminen canvas-koordinaatistoon Perustapaus - canvas.getboundingclientrect() function getmousepos(canvas, evt) { var rect = canvas.getboundingclientrect(); return { x: evt.clientx - rect.left, y: evt.clienty - rect.top }; }
Hiirikoordinaattien muuntaminen canvas-koordinaatistoon Jos canvaksen kokoa skaalattu CSS:llä function getmousepos(canvas, evt) { var rect = canvas.getboundingclientrect(); } return { }; x: evt.clientx - rect.left * (canvas.width / rect.width), y: evt.clienty - rect.top * (canvas.height / rect.height)
Törmäystarkistus Useita eri tapoja toteuttaa Yksinkertaisin on käyttää tarkistukseen neliskulmaisia objektien reunoja rajaavia laatikoita (bounding box) * *Image from Starling Framework the Open Source Game Engine for Flash http://wiki.starling-framework.org/tutorials/basic_collision_detection
Törmäystarkistus seinistä kimpoaminen update: function(){ this.left += this.velocityx; // Update X position this.top += this.velocityy; // Update Y position if((this.left+this.width)>canvasw this.left<0){ // X-axis collision } this.velocityx = -this.velocityx; // Invert velocity direction if((this.left+this.width)>canvasw){ // Relocate based on bounce this.left -= (this.left+this.width)-canvasw; } if(this.left<0){ } this.left = -this.left; // Relocate based on bounce } if((this.top+this.height)>canvash this.top<0){ // Y-axis collision this.velocityy = -this.velocityy; // Invert velocity direction } if((this.top+this.height)>canvash){ // Relocate based on bounce this.top -= (this.top+this.height)-canvash; } if(this.top<0){ // Relocate based on bounce } this.top = -this.top;
Törmäystarkistus Pyöreä rajaus
Eräs grafiikkakirjasto: Pixi.js
Eräs grafiikkakirjasto: Pixi.js Tarjoaa kehittyneen rajapinnan Canvasille Kuvien, äänien ym. esilataus on sisäänrakennettuna Monissa tilanteissa helpompi käyttää kuin pelkkää Canvasta Huonona puolena, että kirjaston opetteluun ei ole kattavia oppimateriaaleja
Yhteenveto ja tehtävänanto
Yhteenveto Animointiin verkossa on useita eri teknologioita Sopivan teknologian valinta riippuu usein vaatimuksista 2D vs. 3D Pikseligrafiikka vs. vektorigrafiikka Efekti vs. peli Saavutettavuus vs. teknologiademo HTML5 <canvas> tarjoaa standardoidun piirtoalueen 2D- ja 3D-pikseligrafiikan piirtämiseen HTML Canvas 2D Context tarjoaa standardoidun JavaScript-rajapinnan monimutkaisten 2Dpikseligrafiikka-animaatioiden piirtämiseen piirtoalueelle
Tehtävänanto Jatkakaa aiemmissa harjoituksissa tekemiänne kotisivuja Upottakaa haluamallenne sivulle <canvas> ja toteuttakaa siihen 2D-animaatio HTML Canvas 2D Context JavaScript API:n avulla Tehtävät on rakennettava annetun teeman ympärille Harjoitus tehdään itsenäisesti Harjoituksen vaatimukset sekä tarkempi tehtävänanto löytyvät kurssin MyCourses-sivuilta Harjoitustyöt-osiosta Palauttakaa harjoitus kurssin DIME-palvelimelle viimeistään maanantaina 4.4.2016 klo 18.00 mennessä Työ tarjoaa erittäin hyvän pohjan projektityölle!
Tästä on varmasti paljon iloa! http://cheatsheetworld.com/programming/html5-canvas-cheat-sheet/ http://www.nihilogic.dk/labs/canvas_sheet/html5_canvas_cheat_sheet.pdf
O Reilly Media 2013 (2nd Ed.) # of pages 750 ISBN 978-1449334987 http://corehtml5canvas.com/
Linkkejä http://www.html5canvastutorials.com/ http://net.tutsplus.com/sessions/canvas-from-scratch/ http://corehtml5canvas.com/ http://diveintohtml5.info/canvas.html http://billmill.org/static/canvastutorial/ http://www.canvasdemos.com/ http://www.w3schools.com/tags/ref_canvas.asp