下記のサンプルは jQuery プラグインとして公開しています。(2009/05/20 追記)
jquery-scrollview - This jQuery plugin applies grab-and-drag scroll view to block elements. - Google Project Hosting

壁紙などの大きなサイズの画像を表示するのに Google マップのようなインターフェイスを提供したい。
Google マップのような、

  • マウスドラッグでスクロール
  • ダブルクリックした所にセンタリング

するような処理である。ただ、ズームに関しては実装しない。
ということで実装したサンプルは ScrollViewer Sample である。

ScrollViewer

jQuery を必要とする。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function ScrollViewer(){
this.initialize.apply(this, arguments);
}
ScrollViewer.prototype = {
initialize: function(container){
//
// Dragging Cursor Set.
//
// http://docs.jquery.com/Utilities/jQuery.browser
// jQuery.browser Deprecated in jQuery 1.3
//
if (navigator.userAgent.indexOf("Gecko/") != -1) {
this.grab = "-moz-grab";
this.grabbing = "-moz-grabbing";
} else {
this.grab = "default";
this.grabbing = "move";
}
// Get container and image.
this.m = $(container);
this.i = this.m.children().css("cursor", this.grab);
this.isgrabbing = false;
// Set mouse events.
var self = this;
this.i.mousedown(function(e){
self.startgrab();
this.xp = e.pageX;
this.yp = e.pageY;
return false;
}).mousemove(function(e){
if (!self.isgrabbing) return true;
self.scrollTo(this.xp - e.pageX, this.yp - e.pageY);
this.xp = e.pageX;
this.yp = e.pageY;
return false;
})
.mouseout(function(){ self.stopgrab() })
.mouseup(function(){ self.stopgrab() })
.dblclick(function(){
var _m = self.m;
var off = _m.offset();
var dx = this.xp - off.left - _m.width() / 2;
if (dx < 0) {
dx = "+=" + dx + "px";
} else {
dx = "-=" + -dx + "px";
}
var dy = this.yp - off.top - _m.height() / 2;
if (dy < 0) {
dy = "+=" + dy + "px";
} else {
dy = "-=" + -dy + "px";
}
_m.animate({ scrollLeft:  dx, scrollTop: dy },
"normal", "swing");
});
this.centering();
},
centering: function(){
var _m = this.m;
var w = this.i.width() - _m.width();
var h = this.i.height() - _m.height();
_m.scrollLeft(w / 2).scrollTop(h / 2);
},
startgrab: function(){
this.isgrabbing = true;
this.i.css("cursor", this.grabbing);
},
stopgrab: function(){
this.isgrabbing = false;
this.i.css("cursor", this.grab);
},
scrollTo: function(dx, dy){
var _m = this.m;
var x = _m.scrollLeft() + dx;
var y = _m.scrollTop() + dy;
_m.scrollLeft(x).scrollTop(y);
}
}

※ ダブルクリックでのセンタリング時はスムーズにスクロールする。
※ Firefox(Gecko) はマウスカーソルに[握る]アイコンがあるため、そちらを割り当てている。なお、jQuery 1.3 から jQuery.browser は使用しない方がいいようだ。

使い方

コンテナとなるブロック要素を指定して、ScrollViewerのコンストラクタを呼び出すだけ。(サンプルは画像になっているが制限しているわけではない。)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<script  src="jquery-1.3.min.js"  type="text/javascript"></script>
<script  type="text/javascript">
$(document).ready(function(){
  var viewer = new ScrollViewer("#image"));
});
</script>
</head>
<body>
<h1>ScrollViewer Sample</h1>
<div  id="image">
<img  src="xxxxxxxxx.jpg"  width="1024"  height="768" />
</div>
</body>