Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > прокрутка изображения


Автор: solenko 20.6.2006, 08:24
Здравствуйте!
Пытаюсь сделать прокрутку изображения в диве. Вот что получилось:
Код

<HTML>
<HEAD>
<script language="javascript">
function Panoram(containerId, width, height, panoram_step){
    var obj = this;
    var div1 = null;
    var img1 = new Image();
    var step = panoram_step;
    var direct = 0;

    var container = document.getElementById(containerId);
    if (container == null){
         alert('Неверно указан контейнер!');
         return null;
    }

    var interval_id = 0;

    var panoram_width = width;
    var panoram_height = height;

    var speed = 0;

    doMove = function(){
       div1.style.left = parseInt(div1.style.left) + direct * step;
       interval_id = setTimeout("doMove()", 100 - speed);

    }
        
    setSpeed = function(){


        ob = container;
        var x=0, y=0;
        while(ob) {
          x+=ob.offsetLeft;
          y+=ob.offsetTop;
          ob=ob.offsetParent;
        }

        delta = panoram_width/2 - (event.screenX - x);
        if (delta > 0){direct = -1;}
        else {direct = 1;}

        speed = Math.round(Math.abs(200*(delta/panoram_width)));
    }

    killInterval = function(){ clearTimeout(interval_id); }

    setImage = function(imgName){
      img1.src = imgName;
    }

    init = function(){
      if (!img1.complete){
         setTimeout(init, 1000);
         return;
      }
      div1 = document.createElement('span');
      if (img1.height != panoram_height){
         k = panoram_height / img1.height;
         img1.height = img1.height * k;
         img1.width = img1.width * k;
    }
    
    container.style.width = panoram_width;
    container.style.height = panoram_height;
    container.style.overflow = 'hidden';
    
    div1.style.position = 'relative';
    div1.style.visibility = 'visible';
    div1.style.display = 'inline';

    div1.style.left = (parseInt(container.style.width) - img1.width) / 2;

    speed = 0;


    div1.appendChild(img1);

    container.appendChild(div1);

    container.onmousemove = setSpeed;
    container.onmouseenter = doMove;
    container.onmouseout = killInterval;
  }

}

function onBodyLoad(){
    var p = new Panoram('testId', 400, 197, 1);
    setImage('lyuteranskaya.jpg');
    init();
}
</SCRIPT>

</HEAD>
<BODY onload="onBodyLoad();">
<DIV style="border:solid black 1pt;" name="test" id="testId"></DIV>
</BODY>
</HTML>


Проблемма в том, что прокрутка почему-то останавливается при изменении положения мышки. Иногда полностью, а иногда просто замирает на время движения.
Подскажите, плиз, в чем проблемма.


То, как это не работает, можно увидеть http://kievexpress.com.ua/solenko/ (пока только в IE) 

Автор: Sardar 25.6.2006, 00:55
Вероятно браузер захлёбываеться высчитывать скорость и "пропускает" setTimeout в doMove. Замени на setInterval (есессно вызывать один раз). Также передавай функцию по имени, а не строкой "doMove()", т.к. создаёться лишняя анонимная функция. 

Автор: solenko 28.6.2006, 17:56
Sardar, дело не в этом. Почему-то возникает событие onmouseout при перемещении над дивом.
По поводу doMove -- спасиб. Исправил, и, кажется, даже понял smile
По поводу setInterval вметсто setTimeout  -- мне ж тогда прийдется каждый раз убивать и снова создавать этот интервал, ведь скорость-то меняется. 

Автор: Sardar 28.6.2006, 18:27
Цитата(solenko @  28.6.2006,  16:56 Найти цитируемый пост)
мне ж тогда прийдется каждый раз убивать и снова создавать этот интервал, ведь скорость-то меняется. 

На самом деле поставить новый таймату гораздо более ресурсоёмкая (особенно в том виде как оно сейчас) операция чем изменять шаг прокрутки. Другими словами запускаешь интервал со средней частотой и меняешь количество сдвигаемых пикселей. Вариация в пикселях должна быть не больше 0-5, иначе не красиво подрыгивать начнёт.

Цитата(solenko @  28.6.2006,  16:56 Найти цитируемый пост)
Почему-то возникает событие onmouseout при перемещении над дивом.

На самом деле ты ловишь события над картинкой, а они уже дальше "пузыряться" к документу, по пути встречая слой контейнер. Если мышь убегает с картинки на бордер дива, то получаем onmouseout на картинке, если обратно с бордера на картинку или вообще в сторону, то получаем onmouseout на слое. Т.е. слой получает два вызова onmouseout, но event.srcElement (на ком событие) разные. Получив onmouseout с картинки на бордер, а потом не выбегая из дива двинуть мышью назад, то onmouseenter возбуждено не будет, всё застопориться пока ты не вынесешь мышь за пределы дива и не вернёшься обратно. Совет: проверяй по event.srcElement == this в onmouseout. 

Автор: solenko 28.6.2006, 18:42
Огромное спасибо. Совету с event.srcElement внял -- все просто прекрастно. Сейчас буду пытаться внять и остальным smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)