Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Javascript ja pehmeet animaatiot?

Sivun loppuun

Paulus M [30.09.2010 18:26:00]

#

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/

Grez [30.09.2010 18:38:18]

#

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.

Metabolix [30.09.2010 20:21:31]

#

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>

Grez [30.09.2010 20:26:42]

#

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

Metabolix [30.09.2010 20:29:22]

#

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. ;)

Grez [30.09.2010 20:32:48]

#

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.

Macro [30.09.2010 21:00:41]

#

Jo puolessa minuutissa punainen oli jäljessä jo pari kierrosta. Selaimena Internet Explorer.

Paulus M [30.09.2010 22:44:43]

#

Kiitti Metabolix vastauksesta ja panostuksesta, mielenkiintoinen testi!

Onkohan kuitenkin niin, että jos haluaa varmemmin tasaisia ja ns. "smootteja" animaatioita, niin pitäisi tehdä flashillä?

Grez [30.09.2010 22:49:45]

#

Olen kyllä nykiviä flash-animaatioitakin nähnyt.

Tosin on totta, että esim. iPhonessa flashilla tehdyt animaatiot ei taatusti nyi.

punppis [08.10.2010 18:01:49]

#

Grez kirjoitti:

Tosin on totta, että esim. iPhonessa flashilla tehdyt animaatiot ei taatusti nyi.

":D"

Jokotai [09.10.2010 19:40:09]

#

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.

Lebe80 [09.10.2010 21:36:28]

#

Robotti-imuritkaan eivät oikein enää näytä samaiselta entiseltä pomppimisanimaatiolta.

Merri [09.10.2010 21:43:08]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta