Pull to refresh

Смена изображений

Reading time4 min
Views5.8K
Как то раз на просторах интернета наткнулся на одну замечательную галерею — адрес забыл, но идея ее осталась в памяти. И вот на один из сайтов понадобилась какая то нестандартная смена картинок (затухание и сьезжание уже приелись) И вот я вспомнил про нее.



Суть в чем? Чтобы изображение открывалось по частям (квадратам, полосам итп.) при чем не просто появлялось а чтоб все это было напичкано эффектами.

Ну чтож, приступим.


Для начала сделаем небольшой конфиг
change_img={
  x:7,
  y:10,
  sort:4,
  delay:{
    st:5000,
    animate:1000,
    cadr:50
  },
  div_id:'slider_photo'
}


* This source code was highlighted with Source Code Highlighter.

тут думаю все просто и понятно. Количество строк\столбцов, тип сортировки (о нем позже), задержка при смене, и id дива с фотографиями.

Суть такова — наш див с картинками заполняется маленькими дивами с позиционнированным background и их уже вертим как хотим.

вначале расчитаем ширину и высоту наших квадратов
r=$('#'+change_img.div_id+' img');
change_img_x=(r[0].height/change_img.x+'').replace(/(.*)\.(.*)/,"$1")-1+1;
change_img_y=(r[0].width/change_img.y+'').replace(/(.*)\.(.*)/,"$1")-1+1;

* This source code was highlighted with Source Code Highlighter.


Теперь заполняем наш див этими самыми квадратами
  function create_div_img(){
    x=0;
    for(i=0;i<change_img.x;i++)
      for(k=0;k<change_img.y;k++){
        
        d=document.createElement('DIV');
        $(d).css({
          position:'absolute',
          top:change_img_x*i+'px',
          left:change_img_y*k+'px',
          opacity:0,
          'z-index':10,                    
          background:'url("'+src_i[x]+'")',
          'backgroun-position':'-'+(change_img_y*k)+'px-'+(change_img_x*i)+'px'                                                                                
        });
        d.className='img_change_s_0';d.style.backgroundPosition='-'+(change_img_y*k)+'px -'+(change_img_x*i)+'px';
        
        document.getElementById('img_change_'+x).appendChild(d);
      }
  }


* This source code was highlighted with Source Code Highlighter.

Ну тут все просто — 2 цикла для создания квадратиков с абсолютным позиционированием

и теперь сама функция которая создает плавное выдвижение этих частей
  function div_animate(){
    s=0;
    setTimeout(ferter,change_img.delay.cadr);
    function ferter(){
      if(s>=change_img.x*change_img.y)return;
      $(referrer[arr_chagr[s++]]).animate({opacity:1,width:change_img_y,height:change_img_x},change_img.delay.animate);
      setTimeout(ferter,change_img.delay.cadr);
    }
  }


* This source code was highlighted with Source Code Highlighter.

Тут тоже все ясно — по таймингу вызываем анимацию новго квадратика. От setInterval я отказался, потомучто при сворачивании браузера и разворачивании (любого) идет сбой и квадратики начинают появляться почти одновременно.

Теперь если вы внимательно просмотрели код то вы увидели массив arr_chagr, который нигде (пока) не объявлен, и ничего не делает.
Этот массив отвечает за последовательность появления квадратиков. Вначале в конфиге мы задавали тип сортировки (0-5).

Теперь рассмотрим эту функцию.
  function get_array_change(x){
    reff=new Array();
    for(i=0;i<x;i++)reff[i]=i;
    switch(change_img.sort){
      default:
      case 0: return reff;break;
      case 1: return reff.reverse();break;
      case 2: return array_x();break;
      case 3: return array_x().reverse();break;
      case 4: return array_casc();break;
      case 5: return array_casc().reverse();break;
    }
    function array_x(){
      arr=new Array();es=0;            
      for(i=0;i<change_img.y;i++)
        for(k=0;k<change_img.x;k++){
          arr[es++]=reff[i+k*change_img.y];
        }
      return arr;  
    } 
    function array_casc(){
      arr=new Array();sr=change_img.y-change_img.x;
      es=0;rem_x=-1;fer_y=0;rif=-1;
      for(i=0;i<change_img.x;i++){
        rif++;gren=0;
        rem_x+=rif+1;fer_y=rif;
        keyt=rem_x;miss=0;
        for(k=0;k<change_img.y;k++){
          if(k)keyt+=fer_y;
          if(fer_y<change_img.x&&!gren)fer_y++;
          else{miss++}if(miss>=sr&&k){fer_y--;gren=1;}
          arr[keyt]=reff[es++];
        }
      }
      return arr;  
    }
  }


* This source code was highlighted with Source Code Highlighter.

Она получает x-количество элементов в массиве (arr_chagr=get_array_change(change_img.x*change_img.y);)
Ну первые 2 case все ясно — простой и развернутый массив.



Дальше идут 2 case — Тоже самое но только сортировка по вертикали (функция array_x()).



И последние — сортировка каскадом. Мне сложно очень описать ее словами — скажу только то что данная сортировка работает только если количество столбцов > количества строк. (change_img.y>change_img.x).



еще кое что по поводу сортировки каскадом — Проблема также заключалась в том, что вначале картинка открывается достаточно быстро, но когда подходит к середине начинает медленнее и медленнее. Ну в принципе правильно — для того чтобы отобразить первую диагональ требуется 1 квадрат, 2 — 2. На диагональ в центре уходит максимальное количество квадратов — 7, что соответственно в 7 раз дольше чем 1 диагональ, в 3.5 раз дольше 2, и.т.д.
Пришлось стандартную функцию div_animate() заменить на
  function div_animate(){
    s=0;
    if(change_img.sort==4||change_img.sort==5){
      change_img.delay.cadr=regular;
      del_rem=change_img.x*change_img.y/2;
    }
    setTimeout(ferter,change_img.delay.cadr);
    function ferter(){
      if(s>=change_img.x*change_img.y)return;
      $(referrer[arr_chagr[s++]]).animate({opacity:1,width:change_img_y,height:change_img_x},change_img.delay.animate);
      if(change_img.sort==4||change_img.sort==5){
        if(s<del_rem)setTimeout(ferter,change_img.delay.cadr-=change_img.delay.cadr/25);
        else setTimeout(ferter,change_img.delay.cadr+=change_img.delay.cadr/25);
      }
      else setTimeout(ferter,change_img.delay.cadr);
    }
  }


* This source code was highlighted with Source Code Highlighter.

Суть такова — до до тех пор пока скрипт не прошел половину квадратиков интервал между открытием их увеличивается на стандартный интервал / 25 (change_img.delay.cadr/25) а после увеличивается на такоеже количество мс. В следствии чего почти не заметна разница в скорости между началом и серединой показа изображения

Ну вот и все.

html код для всего этого
"slider_photo">
"/template/img/1.jpg"
/>
"/template/img/2.jpg"
/>
"/template/img/3.jpg"
/>


* This source code was highlighted with Source Code Highlighter.

Красивая смена картинок, которую легко встроить в любой сайт а также легко настроить под себя готова.
работает даже в IE.

К сожалению пример выложить не могу так как по причине малой необходимости нет своего сайта.
Весь код можно посмотреть и скачать здесь.

upd Демо можно посмотреть тут

upd2 Изменил код. Теперь реализован функциями на почти чистом js (jquery используется только для анимации) Спасибо Seldon
Tags:
Hubs:
Total votes 16: ↑9 and ↓7+2
Comments17

Articles