2015-10-25

javascript:パノラマ写真をドラッグでスクロール(Jqueryプラグイン)

サンプル

javascript:パノラマ写真をドラッグでスクロール を Jqueryプラグインに変更。

プラグインよりもjqueryを先に読み込むこと[]。


2~3機能も追加した。

  • スクロールボタンを追加(オプションで非表示も可能)
  • 切り替え画像に対応(オプション)。例えば、説明を追記した画像を切り替え画像に用いる。
  • 360°パノラマ対応(オプション)

◆html

11~13行目:width, height, src で画像を表示するサイズと画像を定義する(必須)
19~25行目:オプションでパラメータを定義する。
<html>
<head>
<title>dragPanorama</title>
<meta http-equiv="imagetoolbar" content="no" />
<script src="jquery.js"></script>
<script src="jQuery.dragPanorama.js"></script>

<script>
$(function() {
 $("#panorama_wrapper").dragPanorama({
  width: 800,
  height: 400,
  src: "001.jpg"
 });
 $("#panorama_wrapper2").dragPanorama({
  width: 1000,
  height: 300,
  src: "00.jpg",
  round: true,
  buttonSize: "20px",
  buttonTextLeft: "左",
  buttonTextRight: "右",
  buttonTextPause: "停止",
  switchText: "表示切替",
  src2: "00_2.jpg",
 });
});
</script>

</head>

<body>
<div align="center">
     <h1>九十九谷</h1>
     <div id="panorama_wrapper"></div>
     <br/>
     <h1>谷川岳</h1>
     <div id="panorama_wrapper2"></div>
</div>
</body>
</html>

◆javascript(panorama.js)

10~29行のパラメータをオプションで設定できる。


(function($) { // 無名関数でラップしてプラグインを独立させておく。jQueryキーワードの代わりにドル記号($)を使用する。

 $.fn.dragPanorama = function(opts) { // プラグインを定義する。
  return this.each(function() { // each();で回して全ての要素に対して同様に処理していく
   new $.Panorama(this,opts);
  });
 };

 var defaults = {
  dx: 0, // マウスダウンした場所の画像の座標
  xcache: 0,  // 画像の左端のスクリーンの左端に対する座標
  dragObj: false,  // ドラッグの状態を表す。 null→ドラッグしていない状況
  width: 320,
  height: 240,
  round: false, // 360°パノラマのときはtrue
  scroll: true, // 自動スクロールをするときは true
  speed: 100, // 自動スクロールのスピード
  mouseoverVisibility: "visible", // mouseover の時のスクロールボタンの表示/非表示
  mouseoutVisibility: "hidden", // mouseout の時のスクロールボタンの表示/非表示
  buttonSize: "100px", // スクロールボタンの大きさ
  buttonColor: "grey", // スクロールボタンの色
  buttonOpacity: "0.5", // スクロールボタンの透明度
  buttonTextLeft: "<", // スクロールボタン(左)のテキスト
  buttonTextRight: ">", // スクロールボタン(右)のテキスト
  buttonTextPause: "=", // スクロールボタン(pause)のテキスト
  switchSize: "18px", // 切り替えボタンのサイズ
  switchText: "switch", // 切り替えボタンのテキスト
  src2: "", // 切り替え用の画像
  durationTime: 1000 // 画像切り替え時間
 };

 $.Panorama = function(elements, opts){

  this.opts = $.extend({}, defaults, opts); // デフォルトオプションと渡されたオプションのマージ

  this.$id = $(elements);
  this.$id.width(this.opts.width).height(this.opts.height);
  this.srcCurrent = this.opts.src;
 
  var self = this; // 以下の関数で用いるために要素(this)を変数(self)に退避

  var baseBlockCss = {
   position: "absolute",
   cursor: "pointer",
   height: "100%",
   width: "100%"
  };
  var baseInlineCss = {
   position: "absolute",
   cursor: "pointer",
  };

  this.$id.css({ 
   overflow: "hidden",
   position: "relative",
   textAlign: "left",
  }).append(
   $('<div></div>').css(baseBlockCss) // 画像用の<div>
  ).append(
   $('<div></div>').css(baseBlockCss) // 切り替え画像用の<div>
  );

  if ( this.opts.scroll == true || this.opts.src2) {
   this.$id.mouseover(function(){
     $(this).find('span').css({
      visibility: self.opts.mouseoverVisibility
     })
   }).mouseout(function(){
     $(this).find('span').css({
      visibility: self.opts.mouseoutVisibility
     }) 
   });
  }

  if ( this.opts.scroll == true ) {
   var $table = $('<table></table>').css(baseBlockCss).css({  
    border: "0", 
    borderSpacing: "0",
    tableLayout: "fixed", // <td>を均等に割り付ける(キャメルケースで記載)
    fontSize: self.opts.buttonSize,
    color: self.opts.buttonColor,
    opacity: self.opts.buttonOpacity,
    verticalAlign: "middle",
    visibility: self.opts.mouseoutVisibility
   }).append(
    $('<tr></tr>').append(
     $('<td></td>').css({
      textAlign: "left",
     }).append(
      $('<span></span>', { text: self.opts.buttonTextLeft}).click(function(){
       self.automovePrc(-1);
      })
     )
    ).append(
     $('<td></td>').css({
      textAlign: "center"
     }).append(
      $('<span></span>', { text: self.opts.buttonTextPause}).click(function(){
       clearInterval(self.timer);
       self.timer = "";
       })
     )
    ).append(
     $('<td></td>').css({
      textAlign: "right"
     }).append(
      $('<span></span>', { text: self.opts.buttonTextRight}).click(function(){
       self.automovePrc(1);
      })
     )
    )
   );
   this.$id.append($table);
  }

  if ( this.opts.src2 ) { // 画像の切り替え
   var $switch = $('<span></span>', { text: self.opts.switchText }).css(baseInlineCss).css({
    fontSize: self.opts.switchSize,
    color: self.opts.buttonColor,
    opacity: self.opts.buttonOpacity,
    verticalAlign: "top",
    textAlign: "left",
    visibility: self.opts.mouseoutVisibility
   }).click(function(){
    if ( self.$id.find('div:last').css("opacity") == 0 ) {
     self.$id.find('div:last').animate({opacity: 1.0},self.opts.durationTime);
    } else {
     self.$id.find('div:last').animate({opacity: 0.0},self.opts.durationTime);
    }
   });
   this.$id.append($switch);
  }

  this.img = new Image();

  this.img.onload = function(){ // imageが読み込まれたら、imageの幅を取得して、maxLeftを定義する。

   var imgRatio = self.$id.height() / self.img.height;  // 画像の高さを合わせて表示するための変形比率を定義
   self.imgWidth = self.img.width * imgRatio; // 変形画像の幅
   self.imgHeight = self.$id.height(); // 変形画像の高さ

   if ( self.opts.round == false ) {
    self.maxLeft = self.$id.width() - self.imgWidth; 
     // もっとも左に移動したときの画像の左端のスクリーンの左端に対する座標<0
   } else {  // 360°パノラマの場合
    self.maxLeft = self.$id.width() - self.imgWidth * 2;
     // もっとも左に移動したときの画像の左端のスクリーンの左端に対する座標<0
   }
   self.$id.find('div:first').css({ // 画像用の<div>を設定
    opacity: 1.0,
    backgroundImage: "url(" + self.opts.src + ")", // キャメルケースで記載("background-image"→backgroundImage)
    backgroundSize: self.imgWidth + "px," + self.imgHeight + "px", // 変形比率で表示 
    width: self.imgWidth*2 + "px"
   });
   self.$id.find('div:last').css({ // 切り替え画像用の<div>を設定
    opacity: 0.0,
    backgroundImage: "url(" + self.opts.src2 + ")", // キャメルケースで記載("background-image"→backgroundImage)
    backgroundSize: self.imgWidth + "px," + self.imgHeight + "px", // 変形比率で表示 
    width: self.imgWidth*2 + "px"
   });
  }

  this.img.src = this.opts.src;
  this.maxLeft = self.maxLeft;
  this.imgWidth = self.imgWidth;
  this.imgHeight = self.Height;
 
  this.$id.mousedown( function(e) { 
   self.opts.dragObj = true;
   var x = e.pageX ;  // マウスダウンした場所のスクリーンの座標
   self.opts.dx = x - self.opts.xcache;  // マウスダウンした場所の画像の座標
   return false;  // ドラッグで文字が選択されないようにする。
  });
  this.$id.mouseup( function(e) { 
   self.opts.dragObj = false;
  });
  this.$id.mousemove( function(e) { 
   if(!self.opts.dragObj)return;
   var x = e.pageX ;
   self.xcache_tmp = x - self.opts.dx; // ドラッグによる移動量
   if ( self.opts.round == true ) { self.roundPrc(); }; // 360°パノラマの場合
   if(self.maxLeft < self.xcache_tmp && 0 > self.xcache_tmp){ self.movePrc(); }; // 画像が可動の範囲であれば実行
  });
 
 };

 $.extend($.Panorama.prototype,{

  roundPrc: function() { // 360°パノラマの場合の処理
   if ( this.xcache_tmp >= 0 ) {this.xcache_tmp -= this.imgWidth;}
   if ( this.xcache_tmp <= this.maxLeft ) {this.xcache_tmp += this.imgWidth;}
  },

  movePrc: function() { // 移動処理
   this.$id.find('div').css("left", this.xcache_tmp + "px");
   this.opts.xcache = this.xcache_tmp; // 画像の左端のスクリーンの左端に対する座標
  },

  automovePrc: function(moveStep) { // 自動移動
   if (this.timer) return;
   var self = this;
   this.timer = setInterval(function(){
    self.xcache_tmp = self.opts.xcache - moveStep;
    if ( self.opts.round == true ) { self.roundPrc(); }; // 360°パノラマの場合
    if(self.maxLeft < self.xcache_tmp && self.xcache_tmp < 0){ // 画像が可動の範囲であれば実行
     self.movePrc();
    } else {
     clearInterval(self.timer);
     self.timer = "";
    }
   }, 1000/self.opts.speed )
  }
 });

})(jQuery);

◆その他

パノラマ写真を作るにはImage Composite Editorが便利です。

参考にしたページ

Javascriptでパノラマ写真をドラッグ