08.08.2013, 18:57
|
|
Аспирант
|
|
Регистрация: 23.05.2012
Сообщений: 44
|
|
Дёрганье при смене анимации
Всем привет!
у меня есть код:
<html>
<head>
<script src="/animate.js" type="text/javascript"></script>
<script>
window.onload = function() {
var div = document.getElementById("boxer"); //получаю блок по id
div.onmouseover = function(){ // при наведении....
animate({ //анимировать ширину
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
div.style.width = delta*(150-100)+100+"px";
}
})
};
div.onmouseout = function(){ // при отводе мыши....
animate({ //анимированно вернуть ширину
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
div.style.width = delta*(100-150)+150+"px";
}
})
};
}
</script>
</head>
<body>
<div style="background: grey; width:100px; height:100px;" id="boxer"></div>
</body>
</html>
что в animate.js? (взял от сюда: http://learn.javascript.ru/js-animation)
function animate(opts) {
var start = new Date;
var delta = opts.delta || linear;
var timer = setInterval(function() {
var progress = (new Date - start) / opts.duration;
if (progress > 1) progress = 1;
opts.step( delta(progress) );
if (progress == 1) {
clearInterval(timer);
opts.complete && opts.complete();
}
}, opts.delay || 20);
return timer;
}
// ------------------ Delta ------------------
function linear(progress) {
return progress
}
function quad(progress) {
return Math.pow(progress, 2)
}
function makeEaseOut(delta) {
return function(progress) {
return 1 - delta(1 - progress)
}
}
проблема такова... когда навожу мышкой на блок, и сразу отвожу... начинается дёрганье блока.
я понимаю что это изза того что блок анимированно увеличивается... а уже запущена функция плавного уменьшения.
но я никак не могу додуматься как мне остановить прошлую анимацию перед запуском новой...
или что нужно сделать, чтобы дёрганья небыло, и сразу анимированно возвращались пропорции
что подскажете? (желательно с примером)
|
|
08.08.2013, 21:51
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
max0n, var timer сделайте вне функции и
строку 14 в animate продублируйте на 2 строку
|
|
09.08.2013, 12:24
|
|
Аспирант
|
|
Регистрация: 23.05.2012
Сообщений: 44
|
|
привет снова... решил проблему таким способом:
<html>
<head>
<script>
window.onload = function() {
globalTimer = 0;
var div = document.getElementById("boxer");
div.onmouseover = function(){
clearInterval(globalTimer),
animate({
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
div.style.width = delta*(150-100)+100+"px";
}
})
};
div.onmouseout = function(){
clearInterval(globalTimer),
animate({
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
div.style.width = delta*(100-150)+150+"px";
}
})
};
var diva = document.getElementById("boxe");
diva.onmouseover = function(){
clearInterval(globalTimer),
animate({
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
diva.style.width = delta*(170-120)+120+"px";
}
})
};
diva.onmouseout = function(){
clearInterval(globalTimer),
animate({
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta) {
diva.style.width = delta*(120-170)+170+"px";
}
})
};
}
function animate(opts) {
var start = new Date;
var delta = opts.delta || linear;
globalTimer = timer = setInterval(function() {
var progress = (new Date - start) / opts.duration;
if (progress > 1) progress = 1;
opts.step( delta(progress) );
if (progress == 1) {
clearInterval(timer);
opts.complete && opts.complete();
}
}, opts.delay || 20);
return timer;
}
// ------------------ Delta ------------------
function elastic(progress) {
return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)
}
function linear(progress) {
return progress
}
function quad(progress) {
return Math.pow(progress, 2)
}
function quint(progress) {
return Math.pow(progress, 5)
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
function makeEaseOut(delta) {
return function(progress) {
return 1 - delta(1 - progress)
}
}
</script>
</head>
<body>
<div style="background: grey; width:100px; height:100px;" id="boxer"></div><br>
<div style="background: green; width:120px; height:120px;" id="boxe"></div>
</body>
</html>
но столкнулся с новой проблемой...
теперь когда сразу навожу на соседний блок, прошлый не возвращается к старым размерам.
что делать?
Последний раз редактировалось max0n, 09.08.2013 в 12:46.
Причина: не могу решить
|
|
09.08.2013, 13:01
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
max0n,
строка 31 --> var timer; и для полного счастья вычислять текущую ширину в строке 37 и корректировать step на эту величину
|
|
09.08.2013, 13:19
|
|
Аспирант
|
|
Регистрация: 23.05.2012
Сообщений: 44
|
|
Сообщение от рони
|
строка 31 --> var timer;
|
вырубает анимацию на корню...
что не так?
|
|
09.08.2013, 14:09
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
max0n,
так создавать массив таймеров для каждого элемента или индивидуальный таймер хранить в самом элементе или анимате раздвоить и каждой свой таймер для работы.
а лучше одна функция -- на входе id элемента + ширина конечная при mouseout и ширина при mouseover и duration чтобы не плодить копи паст.
|
|
09.08.2013, 15:12
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
max0n,
<html>
<head>
<script>
window.onload = function() {
var div = document.getElementById("boxer");
div.onmouseover = function(){
animate({
el : div,
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta,width) {
div.style.width = delta*(150-width)+width+"px";
}
})
};
div.onmouseout = function(){
animate({
el : div,
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta,width) {
div.style.width = delta*(100-width)+width+"px";
}
})
};
var diva = document.getElementById("boxe");
diva.onmouseover = function(){
animate({
el : diva,
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta,width) {
diva.style.width = delta*(170-width)+width+"px";
}
})
};
diva.onmouseout = function(){
animate({
el : diva,
duration: 1000,
delta: makeEaseOut(quad),
step: function(delta,width) {
diva.style.width = delta*(120-width)+width+"px";
}
})
};
}
function animate(opts) {
clearInterval(opts.el.timer);
var start = new Date;
var delta = opts.delta || linear;
var width = parseFloat(opts.el.style.width);
opts.el.timer = setInterval(function() {
var progress = (new Date - start) / opts.duration;
if (progress > 1) progress = 1;
opts.step( delta(progress),width );
if (progress == 1) {
clearInterval(opts.el.timer);
opts.complete && opts.complete();
}
}, opts.delay || 20);
}
// ------------------ Delta ------------------
function elastic(progress) {
return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)
}
function linear(progress) {
return progress
}
function quad(progress) {
return Math.pow(progress, 2)
}
function quint(progress) {
return Math.pow(progress, 5)
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
function makeEaseOut(delta) {
return function(progress) {
return 1 - delta(1 - progress)
}
}
</script>
</head>
<body>
<div style="background: grey; width:100px; height:100px;" id="boxer"></div>
<div style="background: green; width:120px; height:120px;" id="boxe"></div>
</body>
</html>
|
|
09.08.2013, 15:17
|
|
Аспирант
|
|
Регистрация: 23.05.2012
Сообщений: 44
|
|
огромное тебе спасибо!!!!
жаль не могу ещё раз тебе спасибо отправить )))
респект вообщем )
Последний раз редактировалось max0n, 09.08.2013 в 15:37.
Причина: очепятка
|
|
|
|