Efekt “blur” w czystym JavaScript? Proszę bardzo.

luty 2nd, 2010. Brak komentarzy.
Kategorie: JavaScript, Zabawy z kodem, jQuery.

Witam po krótkiej przerwie. Dziś szybki post zainspirowany pewnym pytaniem na niedawno powstałym portalu devPytania. Pytanie było proste – efekt rozmycia obrazka przy użyciu czystego JS. Czyli bez użycia podmiany obrazka na wstępnie “zblurowany” :) Czemu nie, da się.

Zaznaczę na wstępie, że nie znam się na grafice, a tym bardziej na algorytmach graficznych. I odróżniam Gaussian Blur od Motion Blur “na oko”. Mój “blur” niech zostanie nazwany “rozmyciem rozmytym” – chodziło mi tylko o przedstawienie idei :)

Do celów przykładowych pozwoliłem sobie użyć logo devPytania. W razie, gdyby ktoś uznał to za łamanie praw autorskich, proszę o kontakt.

Idea: dynamicznie dodać przezroczyste duplikaty obrazka, poprzesuwane względem siebie. Tyle.

Plusem takiego rozwiązania jest konieczność załadowania tylko jednego obrazka – kopie ładują się z cache’u przeglądarki.

Zaznaczam, że używam jQuery tylko aby nie produkować większych ilości kodu – przedstawiam ideę, która bez problemu można przełożyć na czysty JS.

OK, nie chciało mi się…

Rozwiązanie jest proste. Najpierw tworzymy DIVa, wrzucamy do niego nasz obrazek:

    <div id="dv">
      <img src="a.png" id="base">
    </div>

Odrobinę stylów:

    #dv 
    { 
      position: relative; 
    }
 
    #base 
    {
      position: absolute; 
      top: 0px; 
      left: 0px; 
    }
 
    .blur 
    {
      opacity: 0.04; 
      position: absolute; 
      display: none;
    }

Później, po załadowaniu strony, szybkie oskryptowanie:

    var move = 3  // maksymalny ofset przesuniecia obrazków
    var pic = "a.png"; // nazwa pliku
 
    $().ready(function()
    {
      for(x = -move; x <= move; x++)
      {
        for(y = -move; y <= move; y++)
        {
          // najpierw dodajemy wszystkie obrazki
          $("#dv").prepend('<img src="' + pic + '" id="pic_' + x + '_' + y + '" class="blur">');
 
          // nadajemy im pozycje
          $("#pic_" + x + "_" + y).css('left', x);
          $("#pic_" + x + "_" + y).css('top', y);
 
          // powyzsze mozna zrobic od razu, np.
          // ... .prepend(' ... class="blur" style="left: ' + x + '; right:' + y + ';">');
        }
      }
 
      // obsługujemy mysz, jeśli trzeba
      $("#base").mouseover(function()
      {
        $(".blur").show();
        $(this).hide();
      });
      $(".blur").mouseout(function()
      {
        $(this).hide();
        $("#base").show();
      });
    });

Warto zauważyć, że można kombinować z #base:hover, podając visibility: hidden;, ewentualnie zmieniając z-index, ale ta metoda, po kilku próbach, wydała mi się najwygodniejsza, czy też raczej najmniej niewygodna :)

Jak na razie nie zanotowałem spowolnienia przy odtwarzaniu tego “ogromnego” kodu…

Przykład TUTAJ.

I… to by było na tyle. Pozdrawiam ekipę z devPytania :)

Skomentuj: