Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   программная анимация (https://javascript.ru/forum/misc/23608-programmnaya-animaciya.html)

taha 29.11.2011 20:54

программная анимация
 
Сегодня утром наткнулся на данную статью Основы программной анимации на JavaScript

и вроде всё в порядке... даже реализовал анимацию, движение по спирали, пока в голову не начали лезть сомнения.. Всё-таки для человека долгое время развлекающегося асемблером и далекого от web-технологий всё это как то странно.. просто хочу уточнить пару моментов..

Допустим есть что-то похожее на:

function go(arg1,arg2){
  var radius = arg1;
  var obj = arg2; /* элемент который вращаем*/
  ...
  setTimeout(function() {
      /* Используем radius и obj*/
      /* Тут изменение параметров */
      if (/* условие срабатывания итерации */)
          setTimeout(arguments.callee, 0);
   }, 0);
}


Не могу до конца понять.. Смотрите..
мы запускаем go(MyElement1, Rad);
проинициализировались переменные
setTimeout запускает анонимную функцию и гоняет её по циклу, пользуясь переменными go(), пока не сделает все свои дела...

вопрос встал вот в чем: пока setTimeout гоняет свою функцию, она пользуется переменными go() и тут я могу понять замыкание и тд.. НО! А если я пользуюсь этой функцией не для одного элемента, а для нескольких??? Разве переменные radius и obj не должны перетераться???? и на этом месте у меня в голове заварилась каша :)

melky 29.11.2011 20:57

они каждый раз будут заново создаваться и каждый раз будет появляться замыкание. вроде бы :)

taha 29.11.2011 21:06

я пока для себя могу найти только одно разумное объяснение...
что когда идет обращение к go() второй/.../n-й раз интерпритатор будет видеть, что [[scope]] функции go, ныне принадлежащий анонимной функции, пока еще занят и будет создавать новый [[scope]], а старый остаётся за анонимной функцией до её смерти... Логично?? или я не прав...

taha 29.11.2011 21:25

Цитата:

Сообщение от Главная » Основные элементы языка » Замыкания
При запуске функции все происходит стандартно:

создается [[scope]]
туда записываются локальные переменные
внутренняя функция получает ссылку на [[scope]]

Но в самом конце - внутренняя функция присваивается sourceNode.onclick. Внешняя функция закончила свою работу, но внутренняя - может запуститься когда-нибудь потом.

Интерпретатор javascript не проводит анализ - понадобятся ли внутренней функции переменные из внешней, и какие переменные могут быть нужны.

Вместо этого он просто оставляет весь [[scope]] внешней функции в живых.

Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции и нашла бы ее там.

Когда внешняя функция будет вызываться повторно, но с другими аргументами, а [[scope]] будет еще занят внутреней функцией с предыдущего вызова, интерпритатор для этой внешней функции создаст [[scope]] ещё раз?????

trikadin 29.11.2011 21:51

Каждому вызову - по отдельному [скопу]) melky всё правильно сказал...

Кстати, на будущее: если нужно анимировать два разных объекта одновременно, то лучше пользоваться одним таймером, который будет менять св-ва обоих.

taha 29.11.2011 22:21

спасибо за ответы

trikadin, в моем случае согласен... а если я не знаю сколько их будет? допустим два от одного родителя и 6 от другого с разными радиусом и скоростью например... страшная же функция получится)))) я хотел найти наиболее простое решение для себя, чтоб использовать как $(...).animate({...});

trikadin 29.11.2011 22:25

А если 100500 и все с разной анимацией разных css-св-в?)

Анимацию на javascript надо оптимизировать для каждого отдельного случая, иначе тормозно будет.

melky 29.11.2011 23:28

лучше тогда использовать transitions ...

ёмаё, ну для кого их придумывали? в каждой теме про них говорю, толку никакого :)

trikadin 29.11.2011 23:34

melky, в каждой теме говорят, что использовать document.write и ставить обработчик на кнопку, а не на отправку формы - плохо. Никакого толку)

melky 29.11.2011 23:38

обработчик ещё через свойство и через атрибут ставить :) где-то тут было.

trikadin 29.11.2011 23:40

Цитата:

Сообщение от melky
обработчик ещё через свойство и через атрибут ставить где-то тут было.

Пруф.

Минус руки бы за такое...

А вообще, transitions придумывали для тех, у кого хватит ума их использовать.

melky 29.11.2011 23:46

:) сколько там его надо? по-моему, они в разы легче, чем та же анимация

если взять "ту же анимацию" из исходников jquery. очень хитрая.

а с переходами только уточнить, какие префиксы (браузер) использовать.

trikadin 30.11.2011 00:01

melky, мой уже ставший излюбленным пример: линукс на три порядка стабильнее, быстрее, удобнее, гибче (список дополнить по мере необходимости) винды. И моска для его использования в качестве десктопной системы (убунту, например) нужно немного.

Где же толпа пользователей линукса?)

taha 30.11.2011 07:49

Во-первых, melky, я не читал все Ваши посты на этом форуме...
Во-вторых, transitions и keyframes, я использую давольно часто, но без вмешательств с js, а только для анимации небольших красотулек, на которые срать если в каком либо браузере не поддерживается...

trikadin, что стабильнее, удобнее, гибче да, но не на много быстрее.. нынешние дистрибутивы ubuntu жрут столько же сколько и win7... Хотя на моем старом ноуте с оперативой в 512МБ работало быстрее винды, но не на много... и то что их можно ставить простому обывателю - не согласен..

trikadin 30.11.2011 08:07

Цитата:

Сообщение от taha
но не на много быстрее.. нынешние дистрибутивы ubuntu жрут столько же сколько и win7... Хотя на моем старом ноуте с оперативой в 512МБ работало быстрее винды, но не на много...

А я убунту (десятую) ставил на 256 мб оперативы, и она хоть и с тормозами, но работала, причём на несколько порядков быстрее той винды (хр), которая стояла там до этого. К тому же, цитата:
Цитата:

Ubuntu Lucid Lynx работает стабильно при минимальном объеме 384 Мб ОЗУ. (Программа установки требует, как минимум, 256 Мб ОЗУ, в то время как альтернативные установки можно запустить, используя лишь 192 Мб ОЗУ.)
Мне кажется, есть разница: минимум 256 (192) мб или минимум 1 гб.

Цитата:

Сообщение от taha
и то что их можно ставить простому обывателю - не согласен..

Аргументация? Знакомые, которым я поставил всю ту же убунту (нет, я её не рекламирую :D) через неделю использования привыкли и перестали замечать разницу. Хотя люди от компа далёкие.

Я же не говорю про генту) Конечно, её простым обывателем ставить не надо...

melky 30.11.2011 08:55

Цитата:

Сообщение от taha (Сообщение 139846)
Во-первых, melky, я не читал все Ваши посты на этом форуме...

при чём тут это?

Цитата:

Сообщение от taha (Сообщение 139846)
Во-вторых, transitions и keyframes, я использую давольно часто, но без вмешательств с js, а только для анимации небольших красотулек, на которые срать если в каком либо браузере не поддерживается...

эти красотульки можно использоварь ради чего угодно. плюс ваша анимация полностью на js, а не на transitions, будет безбожно тормозить на IOS-девайсах (таких,как айфоны).

на переходах она идёт плавно, соотв.

(jquery эту фичу уже использует)

Цитата:

Сообщение от taha (Сообщение 139846)
trikadin, что стабильнее, удобнее, гибче да, но не на много быстрее.. нынешние дистрибутивы ubuntu жрут столько же сколько и win7...

что такое убунта ? я забыл про неё пару-тройку дистрибутивов назад.

из известных дистров не пробовал только Mint и таких жесткачей, как Slackware, Gentoo. сейчас сижу на Arch x86-64 и радуюсь жизни.

Цитата:

Сообщение от taha (Сообщение 139846)
Хотя на моем старом ноуте с оперативой в 512МБ работало быстрее винды, но не на много... и то что их можно ставить простому обывателю - не согласен..

уверяю вас, уже можно. они с каждым днём улучшаются. в Open SUSE или Linux Mint установка проще, чем в винде. в первом есть предустановленный flashplayer, wine и libre office, помимо другого софта, таким образом, ничего не устанавливая, можно сразу начинать работу! сказка.

taha 30.11.2011 11:55

trikadin, melky ну ну... особенно когда идут проблемы с железом, либо когда необходимый софт нужно искать/качать и компилить сорцы - это как раз для далёких от компа людей... про извращения с вайн я вообще промолчу... конечно если вы оказываете им тех. поддержку, то не спорю, что для домашнего применения будет супер, но у меня нет таких знакомых, кто хотел заморочится, а ходить к ним и решать тупые вопросы мне лень.

И melky, я не говорю про всю анимацию.. я говорил про анимацию, которая жизнено необходима для отображения сайта (меню навигации и тп)...
То что transitions быстрее и желательно использовать его, я не спорю...

И вообще мы ушли от темы... JS - используется для анимации?? используется! И был вопрос не по анимации, а по статье с этого сайта, а точнее про вызов функций и [[scope]]... анимация css3 немного не то, что меня сейчас интересует, хотя в Ваших сообщениях на этом форуме я получил для себя некоторые новые знания о transitions

trikadin 30.11.2011 12:46

taha, так в чём проблема, собственно? Мы ответили на ваш вопрос. О достоинствах и недостатках линя можно спорить вечно. Не будем разводить холивар.

taha 30.11.2011 13:42

trikadin, да нет у меня больше вопросов... я про то и говорю, что ответ уже давно получен и желания спорить про css3 и linux у меня нет... тем более, что сам сижу на ubuntu 11.04, юзаю css3-анимацию и вообще не понимаю к чему было всё вышесказаное, если вопрос был не об этом

trikadin 30.11.2011 13:49

Просто тема об этом зашла) Вы же сами спор и начали. :)

taha 30.11.2011 14:00

trikadin, нет нет.... не я... начиная с 8-го поста пошли какие-то Ваши личные с
melky темы про css и линух и про то, о чем melky говорит в каждой теме

trikadin 30.11.2011 16:10

Цитата:

Сообщение от taha
trikadin, нет нет.... не я... начиная с 8-го поста пошли какие-то Ваши личные с
melky темы про css и линух и про то, о чем melky говорит в каждой теме

А, ну это да) Но там мы просто не могли не пообсуждать.

Но про линь-то вы начали спорить на тему убоства/неудобства его для обычного юзверя.

melky 30.11.2011 18:00

Цитата:

Сообщение от taha (Сообщение 139881)
И вообще мы ушли от темы...

очень далеко. ;)

вернёмся к анимации, совершаемой в бОльшей мере инструментами JavaScript.

taha 01.12.2011 11:44

trikadin, melky спасибо за советы, стало работать намного быстрее...

taha 04.12.2011 16:02

у меня еще один вопросик.. а если я буду использовать не

setTimeout(function() {
    /* Тут изменение параметров */
    if (/* условие срабатывания итерации */)
        setTimeout(arguments.callee, 0);
}, 0);


а следущее

function RunAnimate(obj, R, dlt,start){
if(progress < 1) setTimeout(function(){RunAnimate(obj, R, dlt, start);}, 10);
}

второй вариант будет работать быстрее?? ведь по идее кучи [[скопов]] создаваться не должно.. так?? так как для RunAnimate всё передается через аргументы

trikadin 04.12.2011 16:18

Используйте setInterval при создании анимации...

taha 04.12.2011 16:48

а потом
if(progress < 1) ClearInterval(handle);

тоже как-то не очень хорошо, нужно будет хранить handle, тоесть будет сохраняться скоп вызвавшей функции...
хотя это лучше чем куча скопов от сеттаймаут...
спасибо, ща попробую

trikadin 04.12.2011 17:16

Программная анимация на JS делается примерно так:

<div id="elem" style="width: 10px; height: 10px; background: red; position:absolute"></div>
<script>
div= document.getElementById("elem");
pos=0;
interv= setInterval(function(){
 if (++pos > 50){
  clearInterval(interv);
  return;
 };
 div.style.left= pos+"px";
}, 50);
</script>

nerv_ 04.12.2011 19:09

еще вариант
<html>
	<head>
		<meta charset="utf-8">
		<style type="text/css">
			div { background-color:green; height:100px; width:100px; }
		</style>
		<script type="text/javascript">
			var i = 0;
			function x() {
				if (i<400) {
					document.getElementsByTagName('div')[0].style.marginLeft=++i+'px';
					setTimeout(x,10);
				}
			}
		</script>
	</head>
	<body>
		<div onclick="x();"></div>
	</body>
</html>

taha 04.12.2011 19:49

nerv_, я им и пользовался... просто хочу попробовать разные способы и найти для себя наиболее оптимальный..

Думаю, что сопсоб trikadin, будет оптимальней.. ибо [[скоп]] RunAnimatin создастся один раз и будет юзаться функцией setInterval'а..
В случае setTimeout(RunAnimatin,10); я так понимаю, что RunAnimatin будет запускаться раньше завершения, предыдущего запуска, и для нё будет создаваться новый [[скоп]].. и следовательно грузится будет больше..

это я так понимаю, могу быть не прав....

trikadin 04.12.2011 20:37

nerv_, ваш способ медленнее и больше памяти жрёт.

taha 05.12.2011 02:20

trikadin, сделал как Вы сказали и всё прекрасно, не считая firefox, который тормозит скрипт на функции easeOut в этих строках, как и в прошлых вариантах

function d(progress) {
	        for(var a = 0, b = 1, result; 1; a += b, b /= 2) {
	           if (progress >= (7 - 4 * a) / 11)


правда в нем еще две группы с 10-15 вкладок в каждой.. и он всегда тормозит.. но остановить скрипт он всёже хочет в данном месте

trikadin 05.12.2011 02:29

А что после ифа?

И каково значение progress? lim(a)=2 при b=>0, следовательно, если progress > -1/11, то бесконечный цикл гарантирован.

taha 05.12.2011 03:34

код взят всё с тойже статьи

function easeOut(progress) {
     function d(progress) {
        for(var a = 0, b = 1, result; 1; a += b, b /= 2) {
           if (progress>=(7-4*a)/11)
               return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
        }
     }
     return 1 - d(1 - progress);
}


поемуто с простейшими функциями такого не случается

значение progress не знаю.. ибо firefox зависает.. это периодически случается только в нём кстати...

но теперь, благодаря Вам, в три раза реже))

оффтоп... когда перебираю все анимируемые элементы
var obj = document.getElementById("Mylist");
	for (var i in obj.childNodes){
			if ( obj.childNodes[i].nodeType == 1 ){
				...
       }}

firebug говорит
Цитата:

Предупреждение: reference to undefined property obj.childNodes[i].nodeType
Строка: 49
не могу понять почему... вроде всё правильно же

taha 05.12.2011 08:38

сделал одну из предложеных функций easeOut'вой

function easeOut(progress) { return 1-Math.pow((1-progress),2) * ((2.5 + 1) * (1-progress) - 2.5); }


firefox, ниразу не завис ещё, остальные еще быстрее залетали

но вопрос по
Цитата:

Предупреждение: reference to undefined property obj.childNodes[i].nodeType
Строка: 49
остался актуален

поискал в инете, в статьях про DOM примеры вот такие:
var object = document.getElementById('el');
    for (var childItem in object.childNodes) {
    if (object.childNodes[childItem].nodeType == 1)
    object.childNodes[childItem].style.color = '#FF0000';
    }

тоесть тоже самое... и в чём косяк?

PS: то что firefox притормаживал это впринципе норм.. его обычное состояние

trikadin 05.12.2011 11:59

Вообще, object.childNodes - это массив (грубо говоря) узлов. Поэтому можно попробовать перебирать вот так:
for (var i=0; i!= object.childNodes; ++i)


Потому что мало ли, что там может выплыть при переборе через key in obj.

taha 05.12.2011 12:17

эхххххх..... =\\\\\\\\\\\

var n = 0; /* Все прямые потомки являющиеся элементами */

	for (var i in objPiE.childNodes) n=(objPiE.childNodes[i].nodeType==1)?(++n):(n);
	/* Колличество элементов li в данном списке */


красивей смотрелось =(

melky 05.12.2011 12:30

Цитата:

Сообщение от taha (Сообщение 140806)
var obj = document.getElementById("Mylist");
	for (var i in obj.childNodes){
			if ( obj.childNodes[i].nodeType == 1 ){
				...
       }}

в IE сюда попадёт ещё и item и length.
перебирайте элементы через цикл, а не через перебор свойств.
var i = 0, curr;
while(curr = obj.childNodes[i++]){
        //....
}

devote 05.12.2011 12:34

for(var curr, i = 0; curr = obj.childNodes[i]; i++){ 
    if ( curr.nodeType == 1 ) {
        // ...
    }
}

taha 05.12.2011 12:46

trikadin,
спасибо огромное работает также, но firebug ругаться перестал на это...
он что-то вобще взбесился.. даже на jquery, который тупо только подключен, ругается


Часовой пояс GMT +3, время: 08:41.