Onko kenellään ideaa siitä, millä tavalla voisi tehdä sulavaliikkeisiä animaatioita Javascriptillä vai oliko se niin, että se on mahdotonta vaikka kuinka optimoisi?
Tässä yksi esimerkki, miten animaatiot pätkii ajoittain ainakin omalla koneellani:
http://paulus.net16.net/
Ei se mulla nykinyt. Varmaan kiinni selaimesta ja koneesta.
Varsinaisesti JS ei voi taata, ettei animaatio nyi, aivan kuten ei mikään muukaan tietokoneella toimiva esitysväline.
Nykivästäkin animaatiosta saa kuitenkin tasaisemman, jos liikkeen suhteuttaa aikaan. Nykyinen koodisi perustuu oletukseen, että koodin suoritus tapahtuu äärettömän nopeasti ja että funktiokutsut tapahtuvat tasan 16 millisekunnin välein. Todellisuudessa näin ei ole: monilla koneilla ajastimen tarkkuus on 10 millisekuntia, ja lisäksi järjestelmän muu kuorma aiheuttaa viivästystä vielä senkin jälkeen, kun ajastimen olisi pitänyt jo laueta.
Tasaisemmin toimiva ratkaisu olisi siis tällainen:
function siirra() { // Varsinainen liikutus, kuten ennenkin; // ei kuitenkaan ajastusta. } function aika() { return (new Data()).getTime(); } var nyt, loppu; function aja() { // Huolehditaan, että animaatio loppuu kiltisti. if (loppu) return; // Hoidetaan rästiin jääneet liikutukset. while (nyt < aika()) { nyt += 16; siirra(); } // 0 = mahdollisimman pian; muukin arvo toki käy. // Huomaa: parametrina funktio, ei turhaan tekstiä! setTimeout(aja, 0); } window.onload = function() { nyt = aika(); loppu = false; aja(); }; window.onunload = function() { loppu = true; };
Tein vielä esimerkin, jossa pomppii kaksi div-elementtiä, joista sininen on toteutettu näin ja punainen sinun tavallasi. Ero ei ole suuri, mutta punainen div jää auttamatta vähitellen jälkeen, varsinkin, jos koneen laittaa tekemään raskasta taustalla muuta.
(Linkki poistettu, laitankin koko koodin tähän.)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Tasaisesti pomppivia asioita – vai ovatko molemmat?</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.js"></script> <style type="text/css"> html, body { margin: 0; padding: 0; border: 0; height: 100%; } html { overflow: hidden; } body { margin: 1px 34px 34px 1px; position: relative; } p { margin: 1em; } .liikkuja { width: 32px; height: 32px; border-radius: 16px; position: absolute; } #oikea { background-color: blue; border: 1px solid green; } #vaara { background-color: red; border: 1px solid orange; } </style> <script type="text/javascript"> /* <![CDATA[ <!-- */ var loppu = false; var nyt; function Liikkuja(obj) { this.dx = 0.5; this.dy = 6; this.x = 0; this.y = 0; this.elementti = obj; this.dy_max = this.dy; } Liikkuja.prototype.siirra = function() { this.x += this.dx; this.y += this.dy; this.dy -= 0.2; if (this.x < 0) { this.x = -this.x; this.dx = -this.dx; } if (this.x > 100) { this.x = 100 - (this.x % 100); this.dx = -this.dx; } if (this.y < 0) { this.y = 0; this.dy = this.dy_max; } this.elementti.css({"left": this.x + "%", "top": this.y + "%"}); } function aika() { return Date.now(); } var loppu = false; var nyt; var oikea, vaara; function aja_vaarin() { if (loppu) return; vaara.siirra(); setTimeout(aja_vaarin, 20); } function aja_oikein() { if (loppu) return; while (nyt <= Date.now()) { nyt += 20; oikea.siirra(); } setTimeout(aja_oikein, 1); } $(function() { oikea = new Liikkuja($("#oikea")); vaara = new Liikkuja($("#vaara")); nyt = Date.now(); loppu = false; aja_vaarin(); aja_oikein(); }); $(window).unload(function() { loppu = true; }); /* --> ]]> */ </script> </head> <body> <p>Tässä on kaksi pomppivaa asiaa. Niitä liikutetaan eri tavalla: sininen liikkuu kellon mukaan, punainen toimii vain setTimeoutin tarkkuudella. Punainen jää selvästi jälkeen.</p> <div id="oikea" class="liikkuja"></div> <div id="vaara" class="liikkuja"></div> </body> </html>
Hassua, Chromessa näkyy pomppivia palloja/ympyröitä
Joka ei toisaalta ole ihme, koska tyyleissä:
border-radius: 16px;
Kuitenkin otsikoitu että neliöitä vaikka on yritetty tehdä palloja. Mistä lie kopioitu tyylit :D
Grez: Itse sanoisin ennemminkin, että hassua, Firefox ei vieläkään tue border-radiusta ilman -moz-etuliitettä. Ehkä seuraava versio tukee?
Edit. Korjasin osoitteen ja otsikon. Niin ne suunnitelmat muuttuvat, kun innostuu koodaamaan. ;)
Jaa no nyt sitten mun kommentti on ihan hassu, kun otsikko ei olekaan enää neliöitä. :D
Mulla ei muuten Chromessa tai Firefoxissa toi punainen esine juurikaan jää jälkeen. IE:ssä sen sijaan sitäkin enemmän.
Jo puolessa minuutissa punainen oli jäljessä jo pari kierrosta. Selaimena Internet Explorer.
Kiitti Metabolix vastauksesta ja panostuksesta, mielenkiintoinen testi!
Onkohan kuitenkin niin, että jos haluaa varmemmin tasaisia ja ns. "smootteja" animaatioita, niin pitäisi tehdä flashillä?
Olen kyllä nykiviä flash-animaatioitakin nähnyt.
Tosin on totta, että esim. iPhonessa flashilla tehdyt animaatiot ei taatusti nyi.
Grez kirjoitti:
Tosin on totta, että esim. iPhonessa flashilla tehdyt animaatiot ei taatusti nyi.
":D"
Pauluksen sivut kirjoitti:
PHP Error Message
Warning: include(header.php) [function.include]: failed to open stream: No such file or directory in /home/a7411843/public_html/index.php on line 19
Free Web Hosting
PHP Error Message
Warning: include() [function.include]: Failed opening 'header.php' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/a7411843/public_html/index.php on line 19
Free Web Hosting
Virhettä pukkaa.
Robotti-imuritkaan eivät oikein enää näytä samaiselta entiseltä pomppimisanimaatiolta.
Metabolix kirjoitti:
Grez: Itse sanoisin ennemminkin, että hassua, Firefox ei vieläkään tue border-radiusta ilman -moz-etuliitettä. Ehkä seuraava versio tukee?
Tämä johtuu yksinkertaisesti siitä, että 3.6-version Gecko ei tue vielä kaikkia border-radiuksen ominaisuuksia. Esimerkiksi dotted-tyylillä pyöristetyt reunat eivät näy pisteinä, vaan ihan vaan tavanomaisena yhtenäisenä reunana. Firefox 4:n Gecko tukenee border-radiusta täysin, mutta en ole tarkastanut asiaa. Pääpaino on tainnut olla nopeuttamisessa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.