主にWEB関連の覚え書き。たまに実験もしてみる。

2010年3月10日水曜日

画像検索スライドショー


Googleで画像検索→結果をスライドショーでランダム表示。 ここからマウスホイールで画像切り替えとか入れてみようかと思ったが、生javascriptで記述するのがつらくなってきて挫折。これ以上凝ったことをするなら何かライブラリを使うようにした方がいいような気がする。

ソース (このまま貼り付けるとねこのスライドショー)
<script src="http://www.google.com/jsapi"></script>

<script type="text/javascript">
<!--
google.load('search', '1');
-->
</script>

<script type="text/javascript">
<!--
    function ss_setIndicator(id, str) {
      var i = document.getElementById('ss-indicator');
      if (!i) return;

      var span = document.getElementById(id);
      if (!span) {
        span = document.createElement('span');
        span.id = id;
        span.style.margin = '1px';
        span.style.padding = '1px';
        i.appendChild(span);
      }

      span.innerHTML = '';
      span.appendChild(document.createTextNode(str));
    }

    function ss_walkAllPage(s) {
      var cursor = s.cursor;
      var next = cursor.currentPageIndex + 1;
      if (next >= cursor.pages.length) return;
      s.gotoPage(next);
    }
    
    function ss_addSlide(imgUrl, pageUrl, title) {
        var slide = new Object();

        slide.imgUrl = imgUrl;
        slide.pageUrl = pageUrl;
        slide.title = title;
        slide.valid = true;
        slide.img = null;

        var contentDiv = document.getElementById('SS_PreviewPane');
        contentDiv.ss.slides[contentDiv.ss.slides.length] = slide;
    }

    function ss_imageSearchComplete(is) {
      if (!is.results) return;
      if (is.results.length <= 0) return;

      var results = is.results;

      for (var i = 0; i < results.length; ++i) {
        ss_addSlide(results[i].url,
                    results[i].originalContextUrl,
                    results[i].contentNoFormatting);
      }

      ss_walkAllPage(is);

      ss_setIndicator('SS_IS_INDICATOR', 'Url#' + document.getElementById('SS_PreviewPane').ss.slides.length);
      ss_startShow();
    }
    
    function ss_searchImage() {
        var imageSearch = new google.search.ImageSearch();
            
        /*
        imageSearch.setRestriction(google.search.ImageSearch.RESTRICT_IMAGESIZE,
                                   google.search.ImageSearch.IMAGESIZE_MEDIUM);
        imageSearch.setRestriction(google.search.ImageSearch.RESTRICT_IMAGESIZE,
                                   google.search.ImageSearch.IMAGESIZE_EXTRA_LARGE);
        imageSearch.setRestriction(google.search.ImageSearch.RESTRICT_IMAGESIZE,
                                   google.search.ImageSearch.IMAGESIZE_EXTRA_LARGE);
        */

        imageSearch.setRestriction(
          google.search.ImageSearch.RESTRICT_IMAGETYPE,
          google.search.ImageSearch.IMAGETYPE_PHOTO
        );

        imageSearch.setResultSetSize(google.search.Search.LARGE_RESULTSET);
            
        imageSearch.setSearchCompleteCallback(
          this,
          ss_imageSearchComplete,
          [imageSearch]
        );

        imageSearch.setNoHtmlGeneration();

        imageSearch.execute(
          document.getElementById('SS_PreviewPane').ss.keyword
        );

    }

    function ss_feedLoadComplete(result) {

      if (result.error) return;
      
      var contentDiv = document.getElementById('SS_PreviewPane');
      var num = 0;

      for (var i = 0; i < result.feed.entries.length; i++) {
        var entry = result.feed.entries[i];
        var srcImg = entry.content.match('<img[^>]*>');

        if (srcImg == null) continue;

          var src = srcImg[0].match("src=\"[^\"]*\"");
                
          if (src == null) continue;


          var srcUrl = src[0].substring(
                          src[0].indexOf('"') + 1,
                          src[0].lastIndexOf('"')
                        );
          ++num;
          ss_addSlide(srcUrl, entry.link, entry.title);
      }

      ss_setIndicator(
        'SS_MINE_FEED_INDICATOR',
        'feed_recieve=' + result.feed.entries.length + '/' + num
      );

      ss_startShow();

    }

    function ss_fetchFeed() {
      var contentDiv = document.getElementById('SS_PreviewPane');
      var feed = new google.feeds.Feed(contentDiv.ss.feed);
      feed.setNumEntries(20);
      feed.load(ss_feedLoadComplete);

    }

    function ss_mining() {

      var pv = document.getElementById('SS_PreviewPane');

      if (!pv) return;

      pv.ss.slides = new Array();
      pv.ss.prefetch = new Array();

      if (pv.ss.keyword != null && pv.ss.keyword != '') {
        ss_searchImage();
      }

      if (pv.ss.feed != null && pv.ss.feed != '') {
        ss_fetchFeed();
      }
    }

    function ss_adjustImg(img, pv) {
      var w = img.width;
      var h = img.height;

      if (w > pv.ss.width) {
        w = pv.ss.width;
        h = img.height * w / img.width;
      }
      
      if (h > pv.ss.height) {
        h = pv.ss.height;
        w = img.width * h / img.height;
      }

      img.width = w;
      img.height = h;
    }

    function ss_setOpacity(e, op){  
      e.style.filter = 'alpha(opacity=' + (op * 100) + ')';  // IE6.0, IE7.0  
      e.style.MozOpacity = op;  // Firefox, Netscape  
      e.style.opacity = op;  // Chrome, Safari, Opera  
    }  

    function ss_startShow() {
      var pv = document.getElementById('SS_PreviewPane');
      if (pv.ss.timerId != 0) return;

      if (pv.firstChild != null && pv.firstChild.firstChild != null) {
        var img = pv.firstChild.firstChild;
        if (img != null) {
          img.style.border = 'none';
        }
      }
      ss_post(pv, pv.ss.fetchInterval);
    }

    function ss_pauseShow() {
      var pv = document.getElementById('SS_PreviewPane');
      if (pv.ss.timerId == 0) return;

      clearTimeout(pv.ss.timerId);

      var img = pv.firstChild.firstChild;
      img.style.border = '1px solid #000';
      ss_setOpacity(img, 1);
      pv.ss.timerId = 0;
      pv.ss.fadeOut = 1;
      pv.ss.fadeIn = 1;
    }

    function ss_forward(pv) {
      var pickup = Math.floor(Math.random() * pv.ss.slides.length);

      var c = pv.ss.ring.current;
      if (pv.ss.ring.array[c].img != null) {
        pv.ss.ring.array[c].img.id = '';
      }

      if (pv.ss.slides[pickup].img == null) {
        pv.ss.slides[pickup].img = document.createElement('img');
        pv.ss.slides[pickup].img.src = pv.ss.slides[pickup].imgUrl;
      }

      pv.ss.ring.prevSlide = pv.ss.ring.array[c].slide;
      pv.ss.ring.array[c].img = pv.ss.slides[pickup].img;
      pv.ss.ring.array[c].slide = pickup;


      pv.ss.ring.current = ((pv.ss.ring.current + 1) % pv.ss.ring.array.length);
    }

    function ss_isFit(img) {
      return img.complete && (img.width >= 80) && (img.height >= 80);
    }

    function ss_dispFadeIn(pv) {
      var c = pv.ss.ring.current;
      var img = pv.ss.ring.array[c].img;
      var slide = pv.ss.ring.array[c].slide;

      if (pv.ss.fadeIn > 0) {
        pv.ss.fadeIn -= pv.ss.fadeStep;
        if (pv.ss.fadeIn < 0) pv.ss.fadeIn = 0;

        ss_setOpacity(img, 1.0 - pv.ss.fadeIn);

        return 16;
      }

      pv.ss.numShow++;
      ss_setIndicator('SS_SHOW_INDICATOR', 'Show#' + pv.ss.numShow);

      pv.ss.fadeOut = 1;
      pv.ss.fadeIn = 1;

      ss_forward(pv);

      pv.ss.daemonFunc = ss_dispCheckSlides;

      return pv.ss.interval;
    }

    function ss_dispFadeOut(pv) {
      if (pv.ss.fadeOut > 0) {
        pv.ss.fadeOut -= pv.ss.fadeStep;
        if (pv.ss.fadeOut < 0) pv.ss.fadeOut = 0;

 if (pv.ss.ring.prevSlide >= pv.ss.slides.length) {
          return 16;
        }

        var img = pv.ss.slides[pv.ss.ring.prevSlide].img;
        if (img != null) {
            ss_setOpacity(img, pv.ss.fadeOut);
        }

        return 16;
      }

      var c = pv.ss.ring.current;
      var img = pv.ss.ring.array[c].img;
      var slide = pv.ss.ring.array[c].slide;

      ss_adjustImg(img, pv);

      img.alt = pv.ss.slides[slide].title;
      img.style.border = 'none';
      img.style.margin = '1px';
      img.style.padding = '1px';

      ss_setOpacity(img, 0);

      var a = document.createElement('a');
      a.href = pv.ss.slides[slide].pageUrl;
      a.title = pv.ss.slides[slide].title;
      //a.target = '_blank';
      a.onmouseover = ss_pauseShow;
      a.onmouseout = ss_startShow;

      a.appendChild(img);

      pv.innerHTML = '';
      pv.appendChild(a);

      pv.ss.daemonFunc = ss_dispFadeIn;

      return 16;
    }

    function ss_dispWaitForImage(pv) {
      var c = pv.ss.ring.current;
      var img = pv.ss.ring.array[c].img;

      if ((img.width < 80) || (img.height < 80)) {
        ss_forward(pv);
        pv.ss.numSkip++;
        ss_setIndicator('SS_SKIP_INDICATOR', 'Skip#' + pv.ss.numSkip);
        return pv.ss.fetchInterval;
      }

      if (!img.complete) {
        return pv.ss.fetchInterval;
      }
     
      pv.ss.daemonFunc = ss_dispFadeOut;
      return pv.ss.fetchInterval;
    }

    function ss_dispCheckSlides(pv) {
      if (pv.ss.slides.length != 0) {
        pv.ss.daemonFunc = ss_dispWaitForImage;
      }
      return pv.ss.fetchInterval;

    }

    function ss_initRing(pv) {
      for (var i = 0; i < pv.ss.ring.array.length; ++i) {
        ss_forward(pv);
      }
      pv.ss.daemonFunc = ss_dispCheckSlides;
      return pv.ss.fetchInterval;
    }

    function ss_post(pv, delay) {
      pv.ss.timerId = setTimeout('ss_daemon();', delay);
    }

    function ss_daemon() {
      var pv = document.getElementById('SS_PreviewPane');

      if (pv.ss.timerId != 0) {
          clearTimeout(pv.ss.timerId);
          pv.ss.timerId = 0;
      }

      ss_post(pv, pv.ss.daemonFunc(pv));
    }

    function ss_begin(place, width, height, keyword, feed) {
      var placeDiv = document.getElementById(place);

      var table = document.createElement('table');
      var tbody = document.createElement('tbody');
      var tr = document.createElement('tr');
      var td = document.createElement('td');

      placeDiv.appendChild(table);
      table.style.border = '1px solid #888';
      table.style.margin = '0px';
      table.style.padding = '0px';
      table.appendChild(tbody);
      tbody.appendChild(tr);
      tr.appendChild(td);

      td.style.textAlign = 'center';
      td.style.verticalAlign = 'middle';

      var pv = document.createElement('div');
      pv.id = 'SS_PreviewPane';
      pv.style.width = width + 'px';
      pv.style.height = height + 'px';
      pv.ss = new Object();
      pv.ss.keyword = keyword;
      pv.ss.feed = feed;
      pv.ss.width = width - 6;
      pv.ss.height = height - 6;
      pv.ss.fadeOut = 1;
      pv.ss.fadeIn = 1;
      pv.ss.fadeStep = 0.1;
      pv.ss.timerId = 0;
      pv.ss.numSkip = 0;
      pv.ss.numShow = 0;
      pv.ss.daemonFunc = ss_initRing;

      pv.ss.interval = 10000;

      pv.ss.fetchInterval = 300;

      pv.ss.ring = new Object();
      pv.ss.ring.array = new Array(5);
      pv.ss.ring.current = 1;
      pv.ss.ring.prevSlide = 0;
 
      for (var i = 0; i < pv.ss.ring.array.length; ++i) {
        pv.ss.ring.array[i] = new Object();
 pv.ss.ring.array[i].slide = 0;
      }

      pv.style.overflow = 'hidden';

      td.appendChild(pv);

      ss_mining();

    }
-->
</script>


<!--<div id="ss-indicator">Info:</div>-->
<div id="ss-pane" style="width:400px;height:400px;border:none;">
<noscript>Sorry, you have to enable javascript.</noscript>
</div>
<script type="text/javascript">
<!--
  google.setOnLoadCallback(
    function () {ss_begin('ss-pane', 400, 400, '猫');}
  );
-->
</script>

0 件のコメント:

コメントを投稿