Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: animate bez biblioteki
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
acidm
Witam!!
Próbuje napisać funkcje do animacji bez użycia bibliotek.
Elementy animowane poruszaja sie tylko linearnie (narazie) a wsparciem dla opacity i kolorkow zajme si pozniej.
Problem jest w tym że nie działają 2 funkcje jednocześnie(a dokładniej jedna funkcja dla 2 wlaściwości css w firefox i safari).
Na dodatek gdy przekazuje this jako argument do funkcji zwrotnej to nie dziala.
A zapomniałbym funkcja ma miec swój odpowiednik stop() z jquery,zamiast ustawiac czas wykonania ustawiam predkosc.
Domyślam sie że problemem jest to że dodaje timer jako jedna metode do obiektu animowanego,tylko nie wiem jak to obejsc....
Wszystkie pozostałe sugestie mile widziane:)

http://jsfiddle.net/q2n34/1/



  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4.  
  5. <style type="text/css">
  6. #przyklad {
  7. background-color: #00C;
  8. height: 100px;
  9. width: 100px;
  10. border: 3px solid #000;
  11. position: absolute;
  12. left: 4px;
  13. top: 22px;
  14. right: 0px;
  15. bottom: 0px;
  16. margin: 0px;
  17. padding: 0px;
  18.  
  19. }
  20. #przyklad2 {
  21. height: 50px;
  22. width: 100px;
  23. position: absolute;
  24. top: 185px;
  25.  
  26. }
  27.  
  28. <script type="text/javascript">
  29. window.onload=function(){
  30. function getCss(obiekt,wlasnosc){
  31. if (obiekt.currentStyle){
  32. return obiekt.currentStyle[wlasnosc];
  33. }else if(window.getComputedStyle){
  34. return document.defaultView.getComputedStyle(obiekt, null)[wlasnosc];}
  35. };
  36. //koniec get css
  37.  
  38. function animate(obiekt,wlasnosc,koncowa,speed,callback){
  39.  
  40.  
  41. if(!speed){var speed=1;}
  42. var startowa=parseFloat(getCss(obiekt,wlasnosc));
  43. if(koncowa.indexOf('px')!==-1){var jednostka='px'}
  44. else if(koncowa.indexOf('%')!==-1){var jednostka='%'}
  45. else {var jednostka='';}
  46. var koncowa=parseFloat(koncowa);
  47. obiekt.style[wlasnosc]=startowa+jednostka;
  48.  
  49. var step=((Math.max(startowa,koncowa)-Math.min(startowa,koncowa))/100)*speed;
  50.  
  51.  
  52. (function(){
  53.  
  54. var biezaca=parseFloat(obiekt.style[wlasnosc]);
  55.  
  56. if (koncowa<biezaca){
  57. obiekt.style[wlasnosc]=biezaca-step+jednostka;
  58. }
  59. else if(biezaca<koncowa){
  60. obiekt.style[wlasnosc]=biezaca+step+jednostka;
  61. }
  62. obiekt.timer=setTimeout(arguments.callee,10);
  63. if(biezaca>(koncowa-step)&&biezaca<(koncowa+step))
  64. {
  65. obiekt.style[wlasnosc]=koncowa+jednostka;
  66. clearTimeout(obiekt.timer);
  67. if(callback){
  68. return (callback )();
  69. }
  70.  
  71. }
  72.  
  73. })();
  74. }
  75.  
  76. var element=document.getElementById('przyklad');
  77. var element2=document.getElementById('przyklad2');
  78.  
  79. element.onclick=function(){
  80. var elem=this;
  81. animate(elem,'left','200px',2,function(){animate(elem,'height','300px',3)});
  82. animate(elem,'padding','50px',2);
  83. }
  84. function stop(obiekt){
  85.  
  86. clearTimeout(obiekt.timer);
  87. }
  88. element2.onclick=function(){
  89.  
  90. stop(element);
  91. }
  92. }
  93.  
  94. </head>
  95.  
  96.  
  97. <div id="przyklad">klik</div>
  98.  
  99. <input name="guzik" type="button" value="stop" id="przyklad2"/>
  100. </body>
  101. </html>
wdev
1. W jsFiddle masz opcję JSLint - sprawdza Twój kod pod względem poprawności formalnej. Zapuść sobie to i sprawdź. Jak dla mnie, to możesz mieć problem ze zmiennymi - poczytaj sobie o zmiennych w javascripcie i słowie kluczowym var. Dla przykładu tylko :
Kod
if(koncowa.indexOf('px')!==-1){var jednostka='px'}
  else if(koncowa.indexOf('%')!==-1){var jednostka='%'}
  else {var jednostka='';}

sprawia, że Twoja jednostka zawsze jest równa '', bo var ma zasięg funkcyjny a nie blokowy. Jak masz takie konflikty w zmiennych, to szukanie błędów przypomina trochę wróżenie z fusów...
2. Konsola wywala od razu błąd: Uncaught TypeError: Object #<Text> has no method 'getElementsByTagName'. Biorąc pod uwagę, że jest to w jakimś zupełnie innym skrypcie - prawdopodobnie masz coś źle pozamykane.
3. Jak już uprzątniesz kod i dalej będziesz miał problemy, to daj znać wink.gif (btw, TidyUp z jsFiddle też by nie zaszkodziło).

PS. Dla ustawienia wartości domyślnej:
Kod
if (!speed) {
  var speed = 1;
}

mniej pisania masz używając:
Kod
speed = speed || 1;
acidm
Kod
if(koncowa.indexOf('px')!==-1){var jednostka='px'}
else if(koncowa.indexOf('%')!==-1){var jednostka='%'}
else {var jednostka='';}

sprawia, że Twoja jednostka zawsze jest równa '', bo var ma zasięg funkcyjny a nie blokowy. Jak masz takie konflikty w zmiennych, to szukanie błędów przypomina trochę wróżenie z fusów..."

Zgadza sie zmienne maja zasieg funkcyjny wiec sa widoszczne poza if i petlami i dlatego jednostka jest rowna "" lub % lub px a to dlatego ze zmienna jest przypisywana(nadpisywana ) jesli warunek jest spełniony smile.gif
wiec zmienna jednostka nie jest zawsze równa ""

''2. Konsola wywala od razu błąd: Uncaught TypeError: Object #<Text> has no method 'getElementsByTagName'. Biorąc pod uwagę, że jest to w jakimś zupełnie innym skrypcie - prawdopodobnie masz coś źle pozamykane.''
zgadza sie w jsfiddle zapomnialem zmienic z frameworka nz czysty js

speed = speed || 1;
przydatne:) jak równiesz jslint w jsfiddle smile.gif

mam juz nowa wersje:)

czekam na sugestie jak cos

http://jsfiddle.net/zDeF7/
wdev
Cytat(acidm @ 25.07.2011, 11:05:19 ) *
Zgadza sie zmienne maja zasieg funkcyjny wiec sa widoszczne poza if i petlami i dlatego jednostka jest rowna "" lub % lub px a to dlatego ze zmienna jest przypisywana(nadpisywana ) jesli warunek jest spełniony smile.gif
wiec zmienna jednostka nie jest zawsze równa ""


A to w sumie ciekawe, na co mi zwracasz uwagę. Widzę, że pod najnowszym Chromem i Firefoksem to przechodzi rzeczywiście bez problemów (innych chwilowo nie mam pod ręka, żeby potestować). Ale wiem, że jeszcze do niedawna miałem z tym sporo kłopotu. Kiedyś to się nazywało redeklaracja zmiennej i wyrzucało parę błędów, nie mówiąc już o dziwnym przypisywaniu zmiennej. Nevermind.
acidm
Pod innymi też przechodzi (ie5>8 .opera,safari,) ale zwracam honor ,z js przygode zaczolem od niedawna ...
Pomijajc, jak zmienic ten zapis aby byl prawidlowy?

Pojawil sie kolejny problem ..
Gdy wywoluje stop() poprzez klikniecie wszystko jest ok,ale gdy stop() jest wywolywane przy starcie drugiej animacji nie dziala...


http://jsfiddle.net/cXeRD/
wdev
Cytat(acidm @ 27.07.2011, 09:22:33 ) *
Pod innymi też przechodzi (ie5>8 .opera,safari,) ale zwracam honor ,z js przygode zaczolem od niedawna ...
Pomijajc, jak zmienic ten zapis aby byl prawidlowy?

Pojawil sie kolejny problem ..
Gdy wywoluje stop() poprzez klikniecie wszystko jest ok,ale gdy stop() jest wywolywane przy starcie drugiej animacji nie dziala...

http://jsfiddle.net/cXeRD/


Generalnie dobra praktyka jest taka, że zmienne, których będziesz używać definiujesz na początku funkcji, to jest też to, na co JSLint zwraca uwagę.

Jeśli chodzi o Twój błąd - nie bardzo widzę problem... Dorzuciłem sobie drugi div i działa dobrze...
Kod
document.getElementById('przyklad1').onmouseover = function(){
      stop(element)
      animate(this, 'width', '400px');
};
acidm
Po najechaniu kursorem i szybkim zjechaniu , podczas 1 animacji powinno nastapic zablokowanie biezacej i odpalenie nastepnej..
tymczasem dzieje sie inaczej..

Tal lepiej?
http://jsfiddle.net/cXeRD/7/

ps.dlaczego należy unikac arguments.callee?



chyba to dlatego ze pole przerwij jest zmieniane na false(wlaczenie nastepnego animate) nim funckja prywatna zdazy zorientowac sie o zmianie pola(wynika z opoznienia do nastepnego uruchomienia ) ..
jak temu zaradzic questionmark.gif(przy zachowaniu mozliwosci ponownego odpalenia animate() po wywolaniu stop())
misi3k
Przerywanie animacji powinieneś robić za pomocą clearTimeout(). Miałeś już wcześniej dobre rozwiązanie, zapisując ID timera we właściwości obiektu, na którym odpalasz animację: obiekt.timer.
Poprawki zaznaczyłem komentarzami z wykrzyknikiem.
http://jsfiddle.net/cXeRD/15/
acidm
dziekuje slicznie:)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.