ホームページ >ウェブフロントエンド >jsチュートリアル >CloudGamer が作成した ImageZoom 画像拡大効果_画像特殊効果

CloudGamer が作成した ImageZoom 画像拡大効果_画像特殊効果

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBオリジナル
2016-05-16 18:30:471181ブラウズ

通常、製品の写真を拡大して表示するために使用されます。Fanke、JD.com、Alibaba などでも同様の効果が利用できます。
利点は、元の画像に近い画像の一部を拡大して表示でき、マウスで表示領域を制御できることです。
少し前に sohighthesky の写真の拡大効果を見て、自分でも書きたいという衝動に駆られました。
このアプリには次の機能があります:
1. 元の画像を拡大するか、新しい画像を使用して大きな画像を設定することをサポートします。
2. 大きな画像をロードする前に、代わりに元の画像を使用します。操作の待ち時間を短縮します。
3. 大きな画像をズームするためのマウススクロールをサポートします。
5.表示ボックスを自動的に非表示にするかどうかを設定します。
6. プラグイン フォームをサポートして、さらに多くの機能を実装します (詳細は次の記事で)。
互換性: ie6/7/8、firefox 3.6.2、opera 10.51、safari 4.0.4、chrome 4.1

コードをコピー コードは次のとおりです。
var style;
if ( !viewer.clientWidth ) {
var style = viewer.style = {
>display: style .display,
position: style.position,
visibility: style.visibility
};
$$D.setStyle( viewer, {
display: "block",位置: "絶対"、可視性: "非表示"
}
this._viewerWidth = viewer.clientWidth;
this._viewerHeight = viewer.clientHeight; { $$D .setStyle( ビューア, スタイル ); }
rangeWidth = Math.ceil(this._viewerWidth /scale );
rangeHeight = Math.ceil(this._viewerHeight /scale ); >
表示範囲は clientWidth/clientHeight を通じて取得されることに注意してください。
表示ボックスが非表示状態で表示が none に設定されている場合、clientWidth/clientHeight を直接取得することはできません。
この場合、プログラムは次のメソッドを使用して取得します:
1、表示/位置/可視性の元の値を記録します。
2、それを「ブロック」/「絶対」/「非表示」に設定します。 " それぞれ、非表示と占有の両方が可能です。
3、パラメータを取得します。
4、元の値にリセットして元の状態に戻します。
表示範囲を取得したら、比率を合わせて範囲パラメータを取得します。
ps: これは、プレースホルダー以外の要素のサイズ パラメーターを取得する一般的なメソッドであり、jquery の CSS もこのメソッドを使用して幅/高さを取得します。
比例計算後に小数を取得することもできますが、サイズは整数のみとなります。プログラムは常に Math.ceil を使用して四捨五入します。
【拡大効果】
すべての設定が完了したら、startを実行してトリガープログラムを設定します。
プログラムは、主に _start プログラムを元の画像オブジェクトのマウスオーバー/マウス移動にバインドする start メソッドを自動的に実行します。
var image = this._image, START = this._START; . addEvent(image, "mouseover", START );
$$E.addEvent(image, "mousemove", START );
は、元の画像オブジェクトに移動する場合と、元の画像上を移動する場合に対応します。それぞれオブジェクト。
追記:attachEvent を使用する場合は、同じ関数を繰り返しバインドするという問題にも注意する必要があります。ここでの addEvent にはこの問題はありません。
バインドされた _start プログラムは、主にいくつかのイベントのバインド解除とバインドに使用されます:




コードをコピー


コードは次のとおりです : window 拡大効果を終了するには、_OUT プログラムをドキュメントのマウスアウトにバインドします:




コードをコピー

コードは次のとおりです。 :
this._OUT = $$F.bindAsEventListener( function(e){ if ( !e.popularTarget ) this._END(); }, this マウスがドキュメントの外に移動すると、mouseout がトリガーされます。現在の関連ターゲットが null の場合、プログラムを終了するために _end の実行が遅れます: var oThis = this, END = function(){ oThis._end() };
this._END = function(){ oThis._timer = setTimeout( END, oThis.lay ) }; _end プログラムでは、が最初に実行され、バインドされている可能性のあるイベントがすべて削除され、その後 start メソッドを実行してトリガーを待ち続けます。
mousemove にバインドされた _move モバイル プログラムは、主にマウスが移動する場所にズームインする機能を実現するために使用されます。
より多くの状況 (拡張の他のモードなど) に適応するために、ドキュメントにバインドされていますが、そのため、mouseout イベントを使用して削除プロセスをトリガーすることはできません。
プログラムは、マウスの座標と元の画像を比較することによって、マウスが元の画像オブジェクトの範囲外に出たかどうかを判断します:



コードをコピー


コードは次のとおりです:

var x = e.pageX, y = e.pageY, rect = this._rect;
if ( x rect.right || y rect.bottom ) {
this._END();
} else {
...
}

画像オブジェクトの場合は、_ENDを実行して拡大効果を終了します。
マウスが元の画像オブジェクト上で移動すると、座標が計算され、_repair プログラムを通じて位置決めに必要な値に変換されます。
最後に、表示ボックスに拡大したい部分が表示されるように、大きな画像の左/上の位置を設定します。
追記: 位置決めにscrollLeft/scrollTopを使ってみましたが、IEだとノコギリのような動きをしてしまい、大きくなるとそれが顕著になってしまうのでやめました。
[マウスのスクロールとズーム]
mouse 属性を true に設定すると、マウスのスクロールとズーム機能が有効になります。
拡大効果中に、マウスホイールを回転させると、大きな画像を拡大または縮小できます。
実際には、スクロールホイールパラメータの変更に応じて拡大率を変更するためです。
マウススクロールイベントについてはスライダーでも触れましたが、その時はieとffの違いだけを分析してみました。ここでもう一度分析してみましょう。
まず、IE はマウスホイールを使用してイベントをバインドし、イベントの WheelDelta を使用してスクロール パラメータを取得します。

function test(e){alert(e.type ":" e.detail "_" e.wheelDelta) } document.addEventListener( "DOMMouseScroll", test, false ); >document .addEventListener( "mousewheel", test, false );
少し下にスクロールすると、次の結果が表示されます:
ff: DOMMouseScroll:3_unknown
opera: Mousewheel:3_-120
chrome/safari: Mousewheel:0_-120
確認できますイベント バインディングについては、ff は DOMMouseScroll のみをサポートし、他のものはマウスホイールのみをサポートします。
スクロールパラメータの取得に関しては、ffはdetailのみサポート、operaは両方サポート、chrome/safariはwheelDeltaをサポートしています。
追伸: chrome/safari の詳細がなぜ 0 なのかわかりません。他に使い道はありますか?
DOMMouseScroll とマウスホイールのもう 1 つの違いは、前者は要素を直接バインドできないのに対し、後者は要素を直接バインドできることです。
つまり、elem.onmousewheel は可能ですが、elem.onDOMMouseScroll は不可能です。
上記の分析に基づいて、_start プログラムでは、_mouse プログラムは次のようにドキュメントのスクロール イベントにバインドされます。
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll " : "mousewheel", this._MOUSE );
_mouse プログラムで、ローリング パラメーターとカスタマイズされたレート スケーリング比に基づいて新しい倍率を取得します。
this._scale = ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * this.rate;
比率を変更すると、プログラムのパラメーターも再計算する必要があります。
_rangeWidth/_rangeHeight は計算プロセスに影響するため、カスタムのデフォルト値に戻す必要があります:
var opt = this.options;
this._rangeWidth =
this。 _rangeHeight = opt.rangeHeight;
次に、_initSize と _initData を実行してサイズとパラメーターをリセットし、_move を実行して位置を変更します。
最後に、ページのスクロールがトリガーされないように、preventDefault を使用することを忘れないでください。
使用上のヒント
[画像設定]
プログラムは大きな画像をサポートしており、元の画像を拡大したり、新しい大きな画像を使用したりできます。
新しい大きな画像を使用し、その画像が比較的大きい場合は、プログラムが自動的に元の画像を使用して拡大してから、大きな画像をロードするように、拡大率を設定することを強くお勧めします。大きな画像がロードされるまで待機します。
また、新しい大きな画像の幅と高さの比率が元の画像と一致している必要があることに注意してください。そうでないと、元の画像を使用して拡大する場合、この問題は発生しません。
[表示フレームの設定]
表示フレームのサイズを設定するには 2 つの方法があります:
表示範囲を固定するには、最初に rangeWidth/rangeHeight を設定します。プログラムが表示フレームのサイズを計算します。 ;
表示ボックスの現在のサイズを使用して表示するには、rangeWidth/rangeHeight を設定しないか、0 に設定します。
【リセット】
さまざまな属性とオブジェクトの間には多くの関係があるため、多くの属性は直接変更できません。
プログラムは、特にそのような属性を変更するためのリセット メソッドをセットアップします。
プログラムのロード後に、元の画像のサイズや表示ボックスのサイズなど、プログラムの計算に影響するスタイルが変更された場合は、パラメーターと属性をリセットするリセットも実行する必要があります。 。
【フローティング位置】
プログラムには表示フレームのフローティング位置を設定する機能がありません。必要に応じて自分で追加できます。
単純な配置の場合は、インスタンス メソッドを参照し、select のオーバーライドに注意してください。
より複雑なフローティング配置が必要な場合は、「フローティング配置プロンプト効果」を参照してください。
【opera のバグ】
テスト中に、opera 10.10 に 2 つのバグが見つかりました。
それぞれ、img 要素が透明に設定されている場合、背景画像が表示され、js を使用してマウス スタイルを変更する際に問題が発生します。
ただし、これら 2 つの問題は 10.50 で修正されています。まだアップグレードしていない場合は、できるだけ早くアップグレードしてください。
【maxthon バグ】
maxthon 2.5.1 でのテスト中に問題が見つかりました。次のコードをテストしてください:
コードをコピー コードは次のとおりです。


<script> >var t= document.getElementById("t"); <BR>t.style.display="none"; <BR></script>> ;


一般に、display で非表示にした後、clientWidth は 0 になるはずですが、maxthon はこの状況を処理していないようです。
これはプログラム内の clientWidth の判定に影響しますが、一般的な使用には影響しません。
この問題を提出しましたが、対処されるでしょうか。
使用説明
インスタンス化するときは、元の画像オブジェクトとして img 要素が必要であり、表示ボックスとしてコンテナーが必要です。
var iz = new ImageZoom( "idImage", "idViewer" ); 🎜> オプションのパラメータは、次のようなシステムのデフォルト属性を設定するために使用されます。
属性: デフォルト値//説明
モード: "simple",//モード
スケール: 0,//スケール (大きな画像/元の画像)
max: 10,//最大比率
min: 1.5,//最小比率
originPic: "",//元の画像アドレス
zoomPic: "",/ /ラージピクチャアドレス
rangeWidth: 0,//表示範囲の幅
rangeHeight:0,//表示範囲の高さ
delay: 20,//遅延終了時間
autoHide: true,//かどうか自動的に非表示にします
mouse: false,//マウス スケーリング
rate: .2,//マウス スケーリング率
onLoad: $$.emptyFunction,//ロード完了時に実行
onStart: $ $.emptyFunction,// ズームイン時に実行
onMove: $$.emptyFunction, // ズームインして移動時に実行
onEnd: $$.emptyFunction// ズームイン終了時に実行
の使い方モードについては次の拡張記事で説明します。
初期化後、reset メソッドを使用して、属性scale、max、min、originPic、zoomPic、rangeWidth、および rangeHeight を変更する必要があります。
次のメソッドも提供されています:
start: 増幅プログラムを開始します (プログラムは自動的に実行されます);
stop: 増幅プログラムを停止します。
破棄: プログラムを破棄します。
プログラムのソースコード


コードをコピー コードは次のとおりです。

var ImageZoom = function(image, viewer, options) {
this._initialize( image, viewer, options );
this._initMode( this.options.mode ); ._oninit();
this._initLoad();
}
//Initializer
_initialize: function(image, viewer, options) {
this._image = $$(image);//元画像
this._zoom = document.createElement("img");//表示画像
this._viewer = $$(viewer);//表示box
this._viewerWidth = 0;//表示ボックスの幅
this._viewerHeight = 0;//表示ボックスの高さ
this._preload = new Image();//オブジェクトをプリロード
this. _rect = null;//元画像の座標
this._repairLeft = 0;//表示画像のx座標補正
this._repairTop = 0;//表示画像のy座標補正
this._rangeWidth = 0; //表示範囲の幅
this._rangeHeight = 0;//表示範囲の高さ
this._timer = null;//タイマー
this._loaded = false;//ロードするかどうか
this. _substitute = false;//
var opt = this._setOptions(options);
this._max = opt.max; = opt.min;
this._originPic = opt.zoomPic;
this._rangeHeight = opt.rangeHeight; 🎜>this.late = opt.late;
this.autoHide = opt.mouse;
this.rate = opt.rate; opt.onLoad;
this.onStart = opt.onStart;
this.onEnd = opt.onEnd;
this = this, END = function( ) { oThis._end() };
this._END = function(){ oThis._timer = setTimeout( END, oThis.delay ) };
this._START = $$F.bindAsEventListener( this . _start, this );
this._MOVE = $$F.bindAsEventListener( this._move, this );
this._MOUSE = $$F.bindAsEventListener( this._mouse, this ); _OUT = $$F.bindAsEventListener( function(e){
if ( !e.popularTarget ) this._END();
}, this ),
//デフォルトを設定します属性
_setOptions: function(options) {
this.options = {//デフォルト値
mode: "simple",//Mode
scale: 0,//Scale (大きい画像/オリジナル)画像)
max: 10,//最大比率
min: 1.5,//最小比率
originPic: "",//元の画像アドレス
zoomPic: "",//大きい画像アドレス
rangeWidth: 0,//表示範囲の幅
rangeHeight:0,//表示範囲の高さ
delay: 20,//遅延終了時間
autoHide: true,//自動的に非表示にするかどうか
mouse: false,//マウス スケーリング
rate: .2,//マウス スケーリング率
onLoad: $$.emptyFunction,//ロード完了時に実行
onStart: $$.emptyFunction, // ズームイン時に実行
onMove: $$.emptyFunction, // ズームインと移動時に実行
onEnd: $$.emptyFunction// ズームイン終了時に実行
}; $.extend(this .options, options || {});
},
//モードに従って関数属性を初期化します
_initMode: function(mode) {
mode = $$.extend ({
オプション :{},
init: $$.emptyFunction,
load: $$.emptyFunction,
start: $$.emptyFunction,
end: $$.emptyFunction,
move: $ $.emptyFunction,
dispose:$$.emptyFunction
}, (ImageZoom._MODE || {})[mode.toLowerCase() ] ||
this .options = $$.extend(mode.options, this.options );
this._onload = mode.start;
this._onend = mode.end;
this._onmove = mode.move;
this._ondispose = mode.dispose;
//初期ロード
_initLoad: function() {
var image = this._image,originPic = this._originPic,
useOrigin = !this._zoomPic && this._scale,
loadImage = $$F.bind( useOrigin ? this._loadOriginImage : this._loadImage, this );
//自動非表示を設定します
if ( this.autoHide ) { this._viewer.style.display = "none" }
// 最初に元の画像を読み込みます
if (originPic && OriginPic != image.src ) {//カスタム アドレスを使用します
image.onload =loadImage;
image.src =
} else if (image.src ) {/ /要素アドレスを使用します
if ( !image.complete ) {//ロードが完了していません
image.onload =loadImage;
} else {//すでにロードされています
loadImage();
} else {
return;//元の画像アドレスなし
}
//大きな画像をロード
if ( !useOrigin ) {
var preload = this._preload,zoomPic = this._zoomPic | image.src,
loadPreload = $$F.bind(this._loadPreload, this );
if (zoomPic != preload.src ) {//新しいアドレス
preload で再ロードします.onload =loadPreload ;
preload.src =zoomPic;
} else {//Loading
if ( !preload.complete ) {//ロードされていません
preload.onload =loadPreload; } else {//ロード済み
this._loadPreload();
}
}
},
//元画像拡大ローダー
_loadOriginImage: function( ) {
this._image.onload = null;
this._zoom.src = this._image.src;
},
//元の画像読み込みプログラム
_loadImage: function() {
this._image.onload = null;
if ( this._loaded ) {//大きな画像がロードされました
this._initLoaded(); } else {
this._loaded = true;
if ( this._scale ) {//カスタム スケールがある場合は、元の画像を使用して拡大し、大きい画像を置き換えます
this._substitute = true ;
this._zoom .src = this._image.src;
this._initLoaded()
}
},
//大きな画像のプリローダー
_loadPreload: function() {
this._preload.onload = null;
this._zoom.src = this._preload.src; ._loaded ) {//元の画像がロードされました
// 置換は使用されません
if ( !this._substitute ) { this._initLoaded() }
} else {
this. _loaded = true;
}
},
//読み込み設定を初期化します
_initLoaded: function(src) {
//表示画像を初期化します
this._initSize(); > //表示ボックスを初期化します
this._initViewer();
//データを初期化します
this._initData();
//実行を開始します
this._onload(); >this .onLoad();
this.start();
},
//表示画像サイズの初期化
_initSize: function() {
varzoom = this._zoom,画像 = this ._image, スケール = this._scale;
if ( !scale ) { スケール = this._preload.width / image.width }
this._scale = スケール = Math.min( Math.max; ( this. _min,scale ), this._max );
// 表示サイズを比例的に設定します
zoom.width = Math.ceil( image.width *scale );
zoom.height = Math. ceil( image.height *scale );
},
// 表示ボックスを初期化します
_initViewer: function() {
varzoom = this._zoom, viewer = this._viewer; >// スタイルを設定します
varstyles = {padding: 0, overflow: "hidden" }, p = $$D.getStyle( viewer, "position" );
if ( p != "relative" && p != "絶対" ){ スタイル.ポジション = "相対" };
$$D.setStyle( ビューア, スタイル );
zoom.style.position = "絶対";表示画像の挿入
if ( !$$D.contains( viewer,zoom) ){ viewer.appendChild(zoom) }
},
//初期化データ
_initData: function();
varzoom = this._zoom, image = this._image, viewer = this._viewer,
scale = this._scale, rangeWidth = this._rangeWidth, rangeHeight = this._rangeHeight
//元の画像座標
this._rect = $$D.rect( image );
//パラメータを修復します
this._repairLeft = image.clientLeft parseInt($$D.getStyle( image, "padding-left" ) );
this._repairTop = image.clientTop parseInt($$D.getStyle( image, "padding-top" ));
//範囲パラメーターと表示ボックス サイズを設定します
if ( rangeWidth > 0 && rangeHeight > ) {
rangeWidth = Math.ceil( rangeWidth );
this._viewerWidth = Math.ceil( rangeWidth *scale ); >this. _viewerHeight = Math.ceil( rangeHeight *scale );
$$D.setStyle( viewer, {
width: this._viewerWidth "px",
height: this._viewerHeight "px"
} );
} else {
var style;
if ( !viewer.clientWidth ) {//Hide
var style = viewer.styles = {
表示: スタイル .display,
位置: style.position,
可視性: style.visibility
};
$$D.setStyle( viewer, {
表示: "ブロック", 位置: "絶対 "、可視性: "隠し"
}
this._viewerWidth = viewer.clientWidth;
this._viewerHeight = viewer.clientHeight; $$D .setStyle( ビューア, スタイル ); }
rangeWidth = Math.ceil(this._viewerWidth /scale );
rangeHeight = Math.ceil(this._viewerHeight /scale ); >this._rangeWidth = rangeWidth;
this._rangeHeight = rangeHeight;
//Start
_start: function() {
clearTimeout( this._timer );ビューアー = this ._viewer、イメージ = this._image、スケール = this._scale;
this._onstart();
this.onStart(); 🎜>$ $E.removeEvent( image, "mouseover", this._START );
$$E.removeEvent( image, "mousemove", this._START );
$$E.addEvent( document, "mousemove" , this._MOVE );
$$E.addEvent( document, "mouseout", this._OUT );
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE );
},
//Move
_move: function(e) {
clearTimeout( this._timer ); e.pageX 、 y = e.pageY、rect = this._rect;
if ( x rect.right || y rect. bottom ) {
this._END();//元の画像範囲外に移動
} else {
varzoom = this._zoom,
pos = this._repair(
x -rect.left - this ._repairLeft,
y -rect.top - this._repairTop
);
this._onmove( e, pos ); // 位置決め
ズームを設定します。 style.left = pos.left "px";
this.onMove()
},
//補正座標
_repair : function(x, y) {
varscale = this._scale、zoom = this._zoom、
viewerWidth = this._viewerWidth、
viewerHeight = this._viewerHeight //補正座標
x = Math.ceil( viewerWidth / 2 - x *scale );
y = Math.ceil(viewerHeight / 2 - y *scale ); >x = Math.min ( Math.max( x, viewerWidth -zoom.width ), 0 );
y = Math.min( Math.max( y, viewerHeight -zoom.height ), 0 ); >return { left: x , top: y };
},
//End
_end: function() {
this._onend();
this.onEnd();
if ( this .autoHide ) { this._viewer.style.display = "none" }
this.stop();
this.start();,
// 鼠标缩放
_mouse: function(e) {
this._scale = ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * このレート;
var opt = this.options;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
this._initSize();
this._initData();
this._move(e);
e.preventDefault();
},
//開始
start: function() {
if ( this._viewerWidth && this._viewerHeight ) {
var image = this._image, START = this._START;
$$E.addEvent(image, "マウスオーバー", START );
$$E.addEvent(image, "mousemove", START );
}
},
// 停止
stop: function() {
clearTimeout( this._timer );
$$E.removeEvent( this._image, "mouseover", this._START );
$$E.removeEvent( this._image, "mousemove", this._START );
$$E.removeEvent( document, "mousemove", this._MOVE );
$$E.removeEvent( document, "mouseout", this._OUT );
$$E.removeEvent( document, $$B.firefox ? "DOMMouseScroll" : "マウスホイール", this._MOUSE );
},
//修正設定
reset: function(options) {
this.stop();
var viewer = this._viewer、zoom = this._zoom;
if ( $$D.contains( viewer,zoom ) ) { viewer.removeChild(zoom);
var opt = $$.extend( this.options, options || {} );
this._scale = opt.scale;
this._max = opt.max;
this._min = opt.min;
this._originPic = opt.originPic;
this._zoomPic = opt.zoomPic;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
// 重置プロパティ
this._loaded = this._substitute = false;
this._rect = null;
this._repairLeft = this._repairTop =
this._viewerWidth = this._viewerHeight = 0;
this._initLoad();
},
//销毁程序
dispose: function() {
this._ondispose();
this.stop();
if ( $$D.contains( this._viewer, this._zoom ) ) {
this._viewer.removeChild( this._zoom );
}
this._image.onload = this._preload.onload =
this._image = this._preload = this._zoom = this._viewer =
this.onLoad = this.onStart = this .onMove = this.onEnd =
this._START = this._MOVE = this._END = this._OUT = null
}
}

转下请注明出处: http://www.cnblogs.com/cloudgamer/

何らかの建議や疑念がある場合は、迎留め言论。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。