Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 08.11.2010, 15:25
Интересующийся
Отправить личное сообщение для vandy3 Посмотреть профиль Найти все сообщения от vandy3
 
Регистрация: 28.10.2010
Сообщений: 14

Алгоритм плавной смены фона или изображения
Здравствуйте.
Пытаюсь придумать алгоритм плавной смены фона 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 и устанавливая таймауты, но по-другому не представляю, как сделать постепенное изменение) или в принципе нужно использовать другой алгоритм?
Ответить с цитированием
  #2 (permalink)  
Старый 08.11.2010, 17:30
Интересующийся
Отправить личное сообщение для vandy3 Посмотреть профиль Найти все сообщения от vandy3
 
Регистрация: 28.10.2010
Сообщений: 14

Правильно ли в каждой функции иметь аргумент callback, чтобы вызывать после завершения кода текущей функции?
Что-нибудь вроде:
function fade ( el, maxVal, minVal, frames, callback ) {
...
setTimeout ( function () { setOpacity ( el, opacityValue ); if ( i == frames && callback ) { callback ( el ); } }, timeInterval );
...
}

Как тогда передавать аргументы в функцию callback, если я не знаю, какие аргументы ей понадобятся (в данном случае, я передал "el", но ведь мог послать функцию, которая не знает, что с этим el делать)? Вплане, как сделать вызов функции после выполнения текущей функции более универсальным?

Последний раз редактировалось vandy3, 08.11.2010 в 17:34.
Ответить с цитированием
  #3 (permalink)  
Старый 08.11.2010, 20:39
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Сообщение от vandy3
То что придумал я не работает должным образом
Как вариант...

<!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>


Осталось доделать фильтры для ИЕ... Ну и добавить див с картинкой...
Ответить с цитированием
  #4 (permalink)  
Старый 09.11.2010, 03:27
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Вариант на заданную тему )))
<!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>
Ответить с цитированием
  #5 (permalink)  
Старый 09.11.2010, 14:54
Интересующийся
Отправить личное сообщение для vandy3 Посмотреть профиль Найти все сообщения от vandy3
 
Регистрация: 28.10.2010
Сообщений: 14

Спасибо за ответы. А по сути, как правильно сделать так, чтобы эффекты, выполнялись последовательно один за другим, даже если откладываешь эффекты с помощью setTimeout?
Ответить с цитированием
  #6 (permalink)  
Старый 09.11.2010, 16:36
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

vandy3,
попробуйте заменить конструкцию for для запуска таймаутов
на
setTimeout(function() {
    /* Тут изменение параметров */
    if (/* условие срабатывания итерации */)
        setTimeout(arguments.callee, 0);
else callback()
}, 0);
подробнее тут
Ответить с цитированием
  #7 (permalink)  
Старый 11.11.2010, 00:56
Аватар для vladlen
Кандидат Javascript-наук
Отправить личное сообщение для vladlen Посмотреть профиль Найти все сообщения от vladlen
 
Регистрация: 19.10.2010
Сообщений: 143

kerio.com - тут был такой эффект, не смотрел даже, т.к. такой задачи не было, если не на фреймвоках, то можешь разобрать
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите, пжлста, найти (или написать) скрипт для смены картинок. Artweb Работа 9 25.02.2011 11:28