ホームページ >ウェブフロントエンド >jsチュートリアル >ImageZoom画像拡大鏡エフェクト(多機能拡張)_JavaScriptスキル

ImageZoom画像拡大鏡エフェクト(多機能拡張)_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 18:29:401261ブラウズ

主に元の画像と表示フレームの表示モードを拡張し、次のモードがあります。
「フォロー」フォロー モード: 表示フレームはマウスの動きの効果に追従できます。
「ハンドル」ドラッグ ハンドル モード:表示範囲をマークするためのドラッグハンドルがあります。
「クロッパー」カットモード: 元の画像は表示範囲をマークするために不透明になり、他の部分は半透明で表示されます。
「ハンドル-クロッパー」ドラッグハンドルカットモード: ドラッグ ハンドル モードとカット モードのハイブリッド バージョン。透明度とドラッグ ハンドルを使用して表示範囲をマークします。
もちろん、さらに多くの拡張機能があなたの想像力の探索を待っています。
互換性: ie6/7/8、firefox 3.6.2、opera 10.51、safari 4.0.4、chrome 4.1

プログラムの説明

【 拡張モード 】

前回ImageLazyLoadは拡張に継承を使用しましたが、今回はプラグインを使用して拡張します。

最初に基本モードを見てみましょう。これらのモードは、次のような構造で ImageZoom._MODE に保存されます。コードをコピーします

コードは次のとおりです: ImageZoom._MODE = { モード名: { オプション: { ...
}、
メソッド: {
init: function() {
...
}、
...
}
}、
。 ..
}


モード名は基本モードの名前、オプションはオプションのパラメーター拡張子、メソッドはプログラム構造の拡張子です。
基本モードには「フォロー」、「ハンドル」、「クロッパー」モードがあり、これらについては後ほど詳しく紹介します。
メソッドには拡張するフックプログラムが含まれており、拡張の主要部分です。
ps: ここで説明するパターンは、「デザインパターン」のパターンではありません。
展開はプログラムの初期化中に実行する必要があり、_initialize プログラムの前に実行する必要があります。
元のプログラムの構造に影響を与えないように、ウィービング手法を使用して _initialize の前にプログラムを挿入します:





コードをコピー

コードは次のとおりです。 ImageZoom.prototype._initialize = (function(){ var init = ImageZoom.prototype._initialize, ... ; return function (){
...
init.apply(this, argument )
}
})();まず元の関数を保存し、プログラムを挿入して新しい関数を作成し、次に元の関数を置き換えます。

基本モードの組み合わせを考慮して、実際に使用されるモードを保存するためにオブジェクトが使用されます:




コードをコピー


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

mode = ImageZoom._MODE, modes = { "follow": [ mode.follow ], "handle": [ モード.ハンドル ], "クロッパー": [ モード.クロッパー ], "ハンドル-クロッパー": [ モード.ハンドル, モード.クロッパー ]
}; >閲覧可能 「ハンドルクロッパー」モードは、実際には「ハンドル」と「クロッパー」を組み合わせたモードです。

挿入されたプログラムの主なタスクは、設定された基本モードに従って展開することです:




コードをコピー


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


var options = argument[2];
if ( options && options.mode && modes[ options.mode ] ) {
$$A.forEach( modes[ options.mode ], function( mode ){
$$.extend( options, mode.options, false ); $$A.forEach( mode.methods, function( method, name ){ $$CE.addEvent( this, name, メソッド ); }, this );
まずoptionsのオプションパラメータオブジェクトを展開します。オプションパラメータは3番目のパラメータなのでarguments[2]で取得します。
extend の 3 番目のパラメーターは false に設定されます。これは、同じ属性が書き換えられない、つまり、カスタマイズされた属性値が保持されることを意味します。
次に、メソッド内のメソッドをフック関数としてプログラムに 1 つずつ追加します。

メソッドには、init、load、start、repair、move、end、dispose を含めることができます。これらは、ImageZoom の初期化、load、start、modification、move、end、destruction イベントにそれぞれ対応します。
展開中、さまざまなイベントがさまざまなタスクを実行します。
init 初期化関数: 展開に必要な属性を設定するために使用されます。これらの属性は ImageZoom 自体の属性と競合しない、つまり同じ名前を持つことに注意してください。
load 読み込み関数: 画像の読み込みが完了し、関連するパラメータも設定されます。これは主に拡大効果の準備に使用されます。
start関数: 増幅効果がトリガーされたときに実行されます。
修復補正機能: 大きな画像の位置決めの座標値を補正するために使用されます。
move 関数: 拡大効果をトリガーした後にマウスが移動すると実行されます。
終了関数は: 拡大効果を終了するときに実行されます。
dispose 破壊関数: プログラムを削除するときにプログラムをクリーンアップします。
追記: 特定の場所については、ImageZoom で $$CE.fireEvent を使用するセクションを参照してください。

ウィーブとフックを使用してプログラムを拡張していることがわかります。
Weaving メソッドは AOP の一種で、元のプログラムを変更せずに拡張できますが、関数の前後にプログラムを追加することしかできません。
フック メソッドを一緒に使用するには、元のプログラムで対応するフックを設定する必要がありますが、その位置は比較的柔軟です。


【フォローモード】

「フォロー」モードでは、ズームインすると、虫眼鏡を持っているように、マウスの動きに表示枠が追従します。

まず、表示フレームがマウスの動きに追従するようにするには、表示フレームを絶対的に配置する必要があります。


で、対応する左/上を設定するだけです。 var style = this._viewer.style;
style.left = e.pageX - this._repairFollowLeft "px";
style.top = e.pageY - this._repairFollowTop "px"; /pageY はマウスの現在の座標、_repairFollowLeft/_repairFollowTop は座標の補正パラメータです。

表示ボックスが非表示の場合は、前回の表示範囲の取得方法でパラメータを取得します:

コードをコピーします コードは次のとおりです:
if ( !viewer.offsetWidth ) {
styles = { display: style.display, Visibility : style.visibility };
$$D.setStyle( viewer, { 表示: "ブロック"、可視性: "非表示" });
}
...
if (styles) $$D.setStyle( viewer,styles ); }

以下のように、マウスを表示フレームの中央に固定し、最初にパラメータの offsetWidth/offsetHeight に従って修正します。表示フレーム:

コードをコピー コードは次のとおりです:
this._repairFollowLeft = viewer .offsetWidth / 2;
this._repairFollowTop = viewer.offsetHeight / 2;

表示ボックスの offsetParent が body でない場合は、offsetParent に基づいて座標を修正する必要があります。

コードをコピー コードは次のとおりです。
if ( !/BODY|HTML/. test( viewer.offsetParent.nodeName ) ) {
varparent = viewer.offsetParent, rect = $$D.rect(parent );
this._repairFollowLeft = rect.leftparent.clientLeft;
this. _repairFollowTop = rect.topparent.clientTop;
}

ps: Maxthon テスト中に body が見つかりました 要素の offsetParent は body ではなく html です。

プログラムを削除した後に表示ボックスのスタイルを復元するために、ロード プログラムでスタイルのバックアップが作成されます:

コードをコピー コードは次のとおりです:
var viewer = this._viewer, style = viewer.style,styles;
this._stylesFollow = {
left: style.left、top: style.top、position: style.position


、dispose:

$$D.setStyle( this._viewer, this._stylesFollow );

これで基本的な効果は得られましたが、大きな画像の移動範囲に制限があるため、マウスが境界線に近づくと大きな画像が引っかかってしまいます。動かない。
マウスが移動すると大きな画像が変化し続けるという効果を実現するために、移動座標が修復で修正されました:


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

pos.left = ( viewerWidth / 2 - pos.left ) * ( viewerWidth /zoom.width - 1 );
pos.top = ( viewerHeight / 2 - pos.top ) * ( viewerHeight / zoom.height - 1 );

原理は少し複雑です。水平座標を例として、下の図を見てください。
ImageZoom画像拡大鏡エフェクト(多機能拡張)_JavaScriptスキル
大きなボックスは大きな画像オブジェクト、小さなボックス Frame は表示フレームを表します。
現在位置はマウス座標に基づいて取得される実際の表示位置であり、ターゲット位置は効果が達成される位置です。
物理学または幾何学の知識があれば、次の方程式を理解できるはずです: x / y = m / n
次のように推測できます: y = x * n / m = x * (zoom.width - viewerWidth ) /zoom.height
x の現在の座標は pos.left で取得できます: x = viewerWidth / 2 - pos.left
最後に、 left = -y = (viewerWidth / 2 - pos.left ) * ( viewerWidth / zoom.width - 1)
垂直方向の座標は似ています。


[ドラッグハンドルモード]

ドラッグハンドルは、元画像の上にあるレイヤーで、元画像内の表示範囲の位置と範囲を示すために使用されます。
表示範囲は_rangeWidth/_rangeHeightに基づいて取得できます。
位置指定は、マウス座標または大きな画像の配置座標に従って設定できます。
マウス座標を使用する場合、範囲制御などの他の処理を行う必要がありますが、大きな画像に基づいて座標を配置する方が比較的便利で正確です。プログラムでも後者の方法を使用します。

最初に init で _handle ドラッグ ハンドル オブジェクトを定義します:
コードをコピーします コードは次のとおりです:

var handle = $$( this.options.handle );
if ( !handle ) {
var body = document.body
handle = body.insertBefore(this) ._viewer.cloneNode(false), body.childNodes[0]);
handle.id = "";
handle["_createbyhandle"] = true; ( handle, { padding: 0, margin: 0, display: "none" } );


カスタムのドラッグ ハンドル オブジェクトがない場合は、表示ボックスがドラッグ ハンドル オブジェクトとしてコピーされます。
自動生成されたドラッグ ハンドル オブジェクトには、破棄時に削除しやすくするためのマークとして「_createbyhandle」属性が追加されます。

ロード時に、ドラッグ ハンドル スタイルを設定します:


コードをコピーします コードは次のとおりです:
$$D.setStyle( handle, {
position: "absolute",
width: this._rangeWidth "px",
height: this._rangeHeight "px",
display: "block",
visibility: "hidden"
});


絶対位置指定が必要であり、サイズは _rangeWidth/_rangeHeight に従って設定されます。
表示・可視性の設定は以下のパラメータを取得します。

まず、元の画像の座標に基づいて補正パラメータを取得します。


this._repairHandleLeft = rect.left this._repairLeft - handle.clientLeft
this._repairHandleTop = rect; .top this ._repairTop - handle.clientTop;

フォロー モードと同様に、offsetParent の位置も修正する必要があります:



if (handle.offsetParent.nodeName.toUpperCase() != "BODY" ) {
varparent = handle.offsetParent 、rect = $$D .rect(parent);
this._repairHandleLeft -= rect.leftparent.clientLeft;
this._repairHandleTop -= rect.topparent.clientTop; 🎜>

その後、再度非表示にします:

$$D.setStyle( handle, { display: "none", Visibility: "visible" }); 、ドラッグ ハンドル オブジェクトを表示します。
移動するときは、大きな画像の位置座標に従ってドラッグ ハンドルの位置を設定します:





コードをコピー


コードは次のとおりです: 最後に、ドラッグ ハンドル オブジェクトを非表示にします。


【カットモード】

「カット」とは、選択した部分を完全に透明にし、その他の部分を半透明にする効果です。
主にクリッピングによって実現されますが、特定の原理は画像のカット効果で見ることができます。

カット効果を実現するには、init で新しい _cropper カッティング レイヤーを作成する必要があります:





コードをコピー


コードは次のとおりです:
var body = document.body, cropper = body.insertBefore(document.createElement("img"), body.childNodes[0 ]); クロッパー .style.display = "なし";
そして、この切断レイヤーをロードに設定します:

コードをコピーします コードは次のとおりです:

cropper.src = image.src;
cropper.width = image.width;
$$D.setStyle( Cropper, {
位置: "絶対",
left:rect.left this._repairLeft "px",
top:rect.top this._repairTop "px"
}); >元の画像オブジェクトをほぼコピーし、元の画像オブジェクトの上に完全に配置します。

起動時に切り抜きレイヤーを表示し、透明度に合わせて元画像を半透明状態にします。

移動する場合、大きな画像の移動の座標に応じて切り取りレイヤーのクリッピング範囲を設定します:




コードをコピー
コードは次のとおりです。 var w = this._rangeWidth、h = this._rangeHeight、scale = this._scale x = Math.ceil( -x /scale; ); y = Math.( -y / スケール );
this._cropper.style.clip = "rect(" y "px " (x w) "px " (y h)" ;


最後に、切り抜きレイヤーを非表示にし、元の画像を不透明にリセットして元の状態に戻します。

廃棄の際は、切断層も忘れずに取り除いてください。


使用上のヒント

この拡張機能は拡張効果が必要な場合にのみ追加する必要があります。

ImageZoom._MODE は自分で展開できます。展開後、必ず対応するモードをモードに追加してください。

複数の基本モードを組み合わせて同時に使用することができます。詳細については、「ハンドルクロッパー」モードを参照してください。



使用説明


使用方法は ImageZoom と似ていますが、表示モードを設定する追加のオプションの参照モードがある点が異なります。 「ハンドル」モードを使用する場合、オプションのパラメータの「ハンドル」属性でドラッグ ハンドル オブジェクトを設定できます。 「クロッパー」モードを使用する場合、オプションのパラメーターの「不透明度」属性で透明度を設定できます。
「ハンドルクロッパー」モードを使用する場合、上記のパラメータの両方を使用できます。

プログラムのソースコード



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

ImageZoom._MODE = {
//Follow
"follow": {
methods: {
init: function() {
this._stylesFollow = null;/ /バックアップ スタイル
this._repairFollowLeft = 0;//左の補正座標
this._repairFollowTop = 0;//上側の補正座標
},
load: function() {
var viewer = this._viewer、style = viewer.style、styles;
this._stylesFollow = {
left: style.left、top: style.top、position: style.position
}; .style.position = "absolute";
//補正パラメータを取得します
if ( !viewer.offsetWidth ) {//Hide
styles = { display: style.display, Visibility: style.visibility } ;
$$D.setStyle(viewer, { display: "block", Visibility: "hidden" });
}
//中心位置を修正
this._repairFollowLeft = viewer.offsetWidth / 2 ;
this._repairFollowTop = viewer.offsetHeight / 2;
//オフセット親の位置を修正します
if ( !/BODY|HTML/.test( viewer.offsetParent.nodeName ) ) {
var parent = viewer.offsetParent、rect = $$D.rect(parent );
this._repairFollowLeft = rect.leftparent.clientLeft;
this._repairFollowTop = rect.topparent.clientTop; 🎜> if (styles) { $$D.setStyle(viewer,styles); }
},
repair: function(e, pos) {
varzoom = this._zoom,
viewerWidth = this ._viewerWidth,
viewerHeight = this._viewerHeight;
pos.left = ( viewerWidth / 2 - pos.left ) * ( viewerWidth /zoom.width - 1 ); / 2 - pos.top ) * ( viewerHeight /zoom.height - 1 );
},
move: function(e) {
var style = this._viewer.style; left = e.pageX - this._repairFollowLeft "px";
style.top = e.pageY - this._repairFollowTop "px"
},
dispose: function() {
$$ D. setStyle( this._viewer, this._stylesFollow );
}
}
},
//ドラッグ ハンドル
"handle": {
options: {//デフォルトvalue
handle: ""//ドラッグ ハンドル オブジェクト
},
methods: {
init: function() {
var handle = $$( this.options.handle ); 🎜> if ( !handle ) {//定義されていない場合は、表示ボックスをコピーで置き換えます
var body = document.body;
handle = body.insertBefore(this._viewer.cloneNode(false), body) .childNodes[0] ; 0, margin: 0, display: "none" } );

this._handle = handle;
this._repairHandleLeft = 0;//左の座標._repairHandleTop = 0;/ /修正トップ
},
load: function() {
var handle = this._handle, rect = this._rect;
$$D.setStyle( handle, {
位置 : "絶対"、
幅: this._rangeWidth "px"、
高さ: this._rangeHeight "px"、
表示: "ブロック"、
可視性: "非表示"
} );
//補正パラメータを取得します
this._repairHandleLeft = rect.left this._repairLeft - handle.clientLeft;
this._repairHandleTop = rect.top this._repairTop - handle. clientTop;
/ /オフセット親の位置を修正します
if ( !/BODY|HTML/.test( handle.offsetParent.nodeName ) ) {
varparent = handle.offsetParent, rect = $$D.rect(親);
this._repairHandleLeft -= rect.leftparent.clientLeft;
this._repairHandleTop -= rect.topparent.clientTop;
//Hide
$$D. setStyle( handle, { 表示 : "なし"、可視性: "表示" });
},
start: function() {
this._handle.style.display = "ブロック"; >},
move: function(e, x, y) {
var style = this._handle.style,scale = this._scale;
style.left = Math.ceil( this._repairHandleLeft - x / スケール ) "px ";
style.top = Math.ceil(this._repairHandleTop - y / スケール ) "px";
},
end: function() {
this. _handle.style.display = "none";
},
dispose: function() {
if( "_createbyhandle" in this._handle ){ document.body.removeChild( this._handle );
this._handle = null;
}
}
},
//Cut
"cropper": {
options: {//デフォルト値
不透明度: .5//透明性
},
メソッド: {
init: function() {
var body = document.body,
cropper = body.insertBefore(document.createElement(" img"), body.childNodes[0]);
cropper.style.display = "none";

this._cropper = Cropper;
this.opacity = this.options.opacity;
}、
load: function() {
var Cropper = this._cropper、image = this._image、rect = this._rect;
cropper.src = image.src;クロッパー.幅 = 画像.幅;
クロッパー.高さ = 画像.高さ;
位置: "絶対",
左: これ。 _repairLeft "px",
top: rect.top this._repairTop "px"
});
},
start: function() {
this._cropper.style.display = "ブロック";
$$D.setStyle(this._image, "opacity", this.opacity );
move: function(e, x, y) {
var w = this._rangeWidth, h = this._rangeHeight, スケール = this._scale;
x = Math.ceil( -x / スケール ) y = Math.ceil( -y / スケール ); .style.clip = "rect(" y "px " (x w) "px " (y h) "px " x "px)";,
end: function() {
$$D.setStyle( this._image, "opacity", 1 );
this._cropper.style.display = "なし";
},
dispose: function() {
document.body.removeChild( this._cropper );
this._cropper = null;
}
}
}
}

ImageZoom.prototype._initialize = (function(){
var init = ImageZoom.prototype._initialize,
mode = ImageZoom._MODE,
modes = {
"follow": [ mode.follow ],
"handle": [ mode.handle ],
"cropper": [ mode.cropper ],
"handle-cropper": [mode.handle, mode.cropper ]
};
return function(){
var options = argument[2];
if ( options && options. mode && modes[ options.mode ] ) {
$$A.forEach( modes[ options.mode ], function( mode ){
//扩展options
$$.extend( options, mode. options, false );
//扩展钩子
$$A.forEach(mode.methods, function(method, name ){
$$CE.addEvent(this, name, method );
}, this );
}, this );
init.apply( this, argument )
}
});地址
http://demo.jb51.net/js/ImageZoom_ext/ImageZoom_ext.htm

打包下ダウンロード地址
http://www.jb51.net/jiaoben/25809.html
出处:http://www.cnblogs.com/cloudgamer/
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。