画像の一部を拡大して別枠に表示する

2014-09-16


画像の一部を別枠に拡大表示する

ショッピングサイトなんかで見かける、写真上の枠を移動し、その部分を拡大して表示するものを作ってみました。


写真は茅野愛衣さんです。えーと、好みのタイプでして…拾った画像なんで問題あれば差し替えます…

サンプル1- 2倍
サンプル 2 -3倍

Flash使ったりなど、方法は色々あると思うのですが、作成したものはjQueryを使ったものです。やっている事は割と単純で、ドラッグする枠の左と上からの位置を取得し、倍率を掛けたものを右の枠の背景画像 background-position へ指定します。ドラッグする度にpositionが変化するので、リアルタイムに動いているように見えるって感じです。

ブラウザ対応

IE6がバツ。それ以外は大丈夫なようです。

画像の準備

仕様的には何倍でもいけますが、元画像の大きさや倍率、ドラッグする枠の大きさで左右画像の大きさが変化します。拡大した画像をより詳細にするには、3倍~4倍の画像を用意して下さい。

サンプル1を4倍 元画像小さめ
サンプル1を4倍 ドラッグ枠を小さく
サンプル2を4倍 元画像大きめ
サンプル2を4倍ドラッグ枠を小さく

左の画像は倍率で割った幅をmax-width に設定し、右の枠はドラッグ枠を倍率で掛けた数値を縦横に設定していますので、同じ倍率でも表示が変わってきます。調整しながらお好みで。

CSS

#expansion{
  overflow: hidden;
  display:none;
}
#expansion #pan_image{
	float: left;
	margin-left: 10px;
	border: 2px solid #FF00B6;
	background-repeat: no-repeat;
}
#image_expansion {
	float: left;
	position: relative;
}
#image_expansion #pan_mouse{
	position: absolute;
	border: 2px solid #FF00B6;
	cursor: move;
}
#loading{
  position:absolute;
  left:50%;
}

jQueryなどの読み込み

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="jquery.ImageExpansion.js"></script>

GoogleCodeからロードしていますが、自前設置でももちろんOKです。

HTMLとjQuery

  <div id="loading"><img src="img/loading.gif"></div>
    <div id="expansion">
      <div id="image_expansion">
        <div id="pan_mouse"></div>
      	<img src="img/img1.png" width="800" height="1100" alt=""/>
      </div>
      <div id="pan_image"></div>
    </div>

<script type="text/javascript">
window.onload = function(){
  $(function() {
    $("#loading").fadeOut();
    $("#expansion").fadeIn();
    $('#image_expansion').ImageExpansion({
       'pan' : 2,   //倍率
       'drag' : 100 //ドラッグ枠の大きさ
    });
  });
}
</script>

 最初はオプションに画像を指定し、HTMLをjQueryで生成する単純なコードだったのですが、画像をロードするまで待機させる必要があったり、jQueryでappendなどした枠がドラッグ出来なかったり(よく調べてない)しましたので、ちょっとごちゃっとしてます。

余計なコードを省いたシンプルなサンプルを欲しい方はこちらからどうぞ

jquery.ImageExpansion.js 解説


(function($){
   $.fn.ImageExpansion = function(options) {
      
      var settings = $.extend( {
                       'pan'  : 2,
                       'drag' : 100
                     }, options);
   /*
    * 初期設定
    */
      var setImage = function(obj){
        
        //画像のSRC取得
          var src = $("#image_expansion img").attr('src');
        //右の枠の大きさ ドラッグ枠の数値 * 倍率
          var hw = settings.drag*settings.pan; 
          $("#pan_image").css({'width':hw,'height':hw});
        //右の枠へ背景画像を設定
          $("#pan_image").css({'background-image':'url('+src+')'});
        //左の画像の幅を倍率で割り、max-widthに指定する幅を得る
          var img_w = $("#image_expansion img").width();
              img_w = Math.floor(img_w / settings.pan); 
          var img_h = $("#image_expansion img").height();
              img_h = Math.floor(img_h / settings.pan); 
        //左の枠の幅を上で計算した幅と高さに設定  
          $("#image_expansion").css({'width':img_w,'height':img_h});
        //左の画像を上で計算した幅と高さに設定
          $("#image_expansion img").css({'max-width':img_w,'height':img_h});
        //ドラッグ枠の大きさを設定
          $("#pan_mouse").css({'width':settings.drag,'height':settings.drag});
      };
      
   /*
    * ドラッグ
    */
      $("#pan_mouse").draggable({
        containment: "parent"
      });

   /*
    * ドラッグした距離で背景画像の位置を変更
    */
      $(document).on('mousemove','#pan_mouse',function(e){
        //image_expansion ウインド上の位置
          var div  = $('div#image_expansion').offset();
          var ex_left = Math.floor(div.left);
          var ex_top  = Math.floor(div.top);
        //pan_mouse ウインド上の位置
          var div  = $('div#pan_mouse').offset();
          var pan_left = Math.floor(div.left);
          var pan_top  = Math.floor(div.top);
        //image_expansion内におけるpan_mouseの上下位置差分
          var left = (pan_left-ex_left)*settings.pan;
          var top  = (pan_top-ex_top)*settings.pan;
          
          $("#pan_image").css({'background-position':'-'+left+'px -'+top+'px'});
      });
      return setImage( $(this) );
  };
})(jQuery);

右の枠の大きさを背景画像を設定

        //画像のSRC取得
          var src = $("#image_expansion img").attr('src');
        //右の枠の大きさ ドラッグ枠の数値 * 倍率
          var hw = settings.drag*settings.pan; 
          $("#pan_image").css({'width':hw,'height':hw});
        //右の枠へ背景画像を設定
          $("#pan_image").css({'background-image':'url('+src+')'});

右の拡大枠は、左のドラッグ枠の○倍の四角になれば良いので、設定値から計算します。で、元画像をCSSで背景とします。

左の画像を縮小表示する

        //左の画像の幅を倍率で割り、max-widthに指定する幅を得る
          var img_w = $("#image_expansion img").width();
              img_w = Math.floor(img_w / settings.pan); 
          var img_h = $("#image_expansion img").height();
              img_h = Math.floor(img_h / settings.pan); 
        //左の枠の幅を上で計算した幅と高さに設定  
          $("#image_expansion").css({'width':img_w,'height':img_h});
        //左の画像を上で計算した幅と高さに設定
          $("#image_expansion img").css({'max-width':img_w,'height':img_h});
        //ドラッグ枠の大きさを設定
          $("#pan_mouse").css({'width':settings.drag,'height':settings.drag});

元画像の縦横サイズを取得し、倍率で割った数値をCSSで画像及びそれを囲う枠の縦横サイズとして設定します。倍率や元画像のサイズによって小数点以下の端数が出ますので、そこは切り捨てで。

右枠背景画像のpositionを変更する

      $(document).on('mousemove','#pan_mouse',function(e){
        //image_expansion ウインド上の位置
          var div  = $('div#image_expansion').offset();
          var ex_left = Math.floor(div.left);
          var ex_top  = Math.floor(div.top);
        //pan_mouse ウインド上の位置
          var div  = $('div#pan_mouse').offset();
          var pan_left = Math.floor(div.left);
          var pan_top  = Math.floor(div.top);
        //image_expansion内におけるpan_mouseの上下位置差分
          var left = (pan_left-ex_left)*settings.pan;
          var top  = (pan_top-ex_top)*settings.pan;
          
          $("#pan_image").css({'background-position':'-'+left+'px -'+top+'px'});
      });


ドラッグ枠を移動(mousemove)した時にブラウザ上の上からの距離と左からの距離を取得します。同様に画像を囲う枠の距離も取得します。ドラッグ枠の距離から画像を囲う枠の距離を引く事で、枠内におけるドラッグした距離が計算出来ます。

この距離に設定倍率を掛けた数値を右枠の背景画像のpositionに設定する事で、同じ位置を枠内に表示するって形です。

同様のことがもっと効率よく実現可能なものがおそらく有ると思います。調べてはいませんが、仕様も様々かと思いますので、1つの考え方として参考程度にどうぞ。右の拡大枠をドラッグ枠に吸着させる、なんてのも良いかもしれません。