Алгоритм плавной смены фона или изображения
Здравствуйте.
Пытаюсь придумать алгоритм плавной смены фона div-элемента. Есть div-элемент, которому назначается фоновая картинка. По прошествии определенного времени надо сменить фон другой картинкой. Смена фона внешне должна происходить следующим образом: затухание блока (блок становится постепенно черным), далее проявление фона с уже измененным фоном. То есть не просто плавное "опрозрачивание" одного дива, и проявление другого. То что придумал я не работает должным образом: <div id="wrapper"><div id="content"></div></div> Wrapper назначен черный фон, content присваивается конкретная картинка для фона. Соответственно изменяю непрозрачность (opacity) блока content до нуля, изменяю фон content и повышаю непрозрачность до 100. (от 0 до 1 в w3c-совместимых браузерах). За затухание отвечает функция fade, которая в зависимости от флага показано изображение или скрыто повышает или понижает прозрачность блока: function fade ( el, maxVal, minVal, frames ) { var vpf = Math.ceil( ( maxVal - minVal ) / frames ); // valuePerFrame var tpf = Math.ceil( 1000 / el.fps ); // timePerFrame if ( el._fadeIn ) { // Если объект показан на экране, то надо сделать fadeOut (скрыть) for ( var i = 1; i <= frames; i++ ) { (function() { var opacityValue = maxVal - i * vpf; var timeInterval = i * tpf; setTimeout ( function () { setOpacity ( el, opacityValue ); }, timeInterval ); })();} el._fadeIn = false; } else { // Иначе делаем fadeIn, показываем объект for ( var i = 1; i <= frames; i++ ) { (function() { var opacityValue = minVal + i * vpf; var timeInterval = i * tpf; setTimeout ( function () { setOpacity ( el, opacityValue ); }, timeInterval ); })();} el._fadeIn = true; } } Функция, в которой собран механизм содержит в себе нечто вроде: ... fade ( el, 100, 0, halfFrames ); changeBg(); // изменение фона блока setTimeout ( function () { fade ( el, 100, 0, halfFrames ); }, el.duration / 2 ); el.currentPos += 1; ... Если не использовать setTimeout для вывода из черного состояния, то функция fadeIn (2-ая по порядку) перебивает, как я понимаю, первую - fadeOut (1-ая по порядку). Если использовать setTimeout ..., то картинка фона меняется раньше, чем фон затухает. Вопросов несколько: как заставить выполняться нужные мне строки кода по цепочке - до тех пор пока не выполнится предыдущий метод, не запускается следующий? Может стоит как-то изменить способ изменения прозрачности (изменять не циклом for и устанавливая таймауты, но по-другому не представляю, как сделать постепенное изменение) или в принципе нужно использовать другой алгоритм? |
Правильно ли в каждой функции иметь аргумент callback, чтобы вызывать после завершения кода текущей функции?
Что-нибудь вроде: function fade ( el, maxVal, minVal, frames, callback ) { ... setTimeout ( function () { setOpacity ( el, opacityValue ); if ( i == frames && callback ) { callback ( el ); } }, timeInterval ); ... } Как тогда передавать аргументы в функцию callback, если я не знаю, какие аргументы ей понадобятся (в данном случае, я передал "el", но ведь мог послать функцию, которая не знает, что с этим el делать)? Вплане, как сделать вызов функции после выполнения текущей функции более универсальным? |
Цитата:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>12345</title> <style type="text/css"> #box { width: 200px; height: 100px; opacity: 0; background-color: #000000; } </style> <script> inc=0.01 function Go() { var o=document.getElementById('box') var val=o.style.opacity var stop=false val=+val+inc switch (val) { case 0: stop=true break case 1: inc*=-1 break default: } o.style.opacity=val if (stop) { return } window.setTimeout(Go,30) } </script> </head> <body> <div id='box'></div> <input type='button' onclick='Go()' value='Go' /> </body> </html> Осталось доделать фильтры для ИЕ... Ну и добавить див с картинкой... |
Вариант на заданную тему )))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <style type="text/css"> #wrapper { width: 180px; height: 180px; background-color: #000000; } #content { width: 180px; height: 180px; background-image: url(http://www.buket.co.ua/planet/srez_cvety/____182.jpg); } </style> </head> <body> <div id="wrapper"><div id="content"></div></div> <script language="JavaScript" type="text/javascript"> function slide(e, b, j, z) { e = e||document.getElementById(e); if(e.timer) window.clearTimeout(e.timer) var a = e.style.cssText; for (var d in b) { var g = RegExp("(" + d + ".*?)(\\d+\\.?\\d*)", "i"); g.test(a) ? a = a.replace(g, "$1" + b[d][0]) : d != "opacity" ? a = d + ": " + b[d][0] + "px;" + a : window.ActiveXObject ? a = "filter:progid:DXImageTransform.Microsoft.Alpha(opacity=" + b.opacity[0] + ");" + a : a = "opacity:" + b.opacity[0] / 100 + ";" + a } e.style.cssText = a; var k = (new Date).getTime(); setTimeout(function () { var h = ((new Date).getTime() - k) / j; h = h < 0.5 ? Math.pow(2 * h, 3) / 2 : (2 - Math.pow(2 * (1 - h), 3)) / 2; for (var c in b) { var i = Math.ceil((b[c][1] - b[c][0]) * h + b[c][0]); if (c == "opacity" && !window.ActiveXObject) i /= 100; var f = RegExp("(" + c + ".*?)(\\d+\\.?\\d*)", "i"); a = a.replace(f, "$1" + i) } e.style.cssText = a; if (h < 1) e.timer = setTimeout(arguments.callee, 30); else { for (c in b) { if (c == "opacity" && !window.ActiveXObject) b[c][1] /= 100; f = RegExp("(" + c + ".*?)(\\d+\\.?\\d*)", "i"); a = a.replace(f, "$1" + b[c][1]) } e.style.cssText = a; z&&z() } }, 10) }; var p = {"opacity":[100,0]}, p2 = {"opacity":[0,100]}, content=document.getElementById("content"), img = ["url(http://img.files.7ja.ru/pics-big/99.jpg)","url(http://www.dostavka-buketov.ru/imag/df156.jpg)","url(http://www.buket.co.ua/planet/srez_cvety/____182.jpg)"] go=function(){slide(content, p, 4000,function(){content.style.backgroundImage=img[0];img.push(img.shift());slide(content, p2, 3000)})} </script> <input type='button' onclick='go()' value='Go' /> </body> </html> |
Спасибо за ответы. А по сути, как правильно сделать так, чтобы эффекты, выполнялись последовательно один за другим, даже если откладываешь эффекты с помощью setTimeout?
|
vandy3,
попробуйте заменить конструкцию for для запуска таймаутов на setTimeout(function() { /* Тут изменение параметров */ if (/* условие срабатывания итерации */) setTimeout(arguments.callee, 0); else callback() }, 0);подробнее тут |
kerio.com - тут был такой эффект, не смотрел даже, т.к. такой задачи не было, если не на фреймвоках, то можешь разобрать
|
Часовой пояс GMT +3, время: 00:33. |