>  기사  >  웹 프론트엔드  >  ImageZoom 그림돋보기 효과(다기능 확장)_자바스크립트 능력

ImageZoom 그림돋보기 효과(다기능 확장)_자바스크립트 능력

WBOY
WBOY원래의
2016-05-16 18:29:401244검색

주로 원본 이미지와 디스플레이 프레임의 디스플레이 모드를 확장하며 다음과 같은 모드가 있습니다.
"따라가기" 팔로우 모드: 디스플레이 프레임이 마우스 이동 효과를 따를 수 있습니다.
"핸들" 드래그 핸들 모드: 표시 범위를 표시하는 드래그 핸들이 있습니다.
"자르기" 절단 모드: 원본 이미지는 표시 범위를 표시하기 위해 불투명하고 다른 부분은 반투명하게 표시됩니다.
"핸들-자르기" 핸들 절단; 모드: 드래그 핸들 모드와 절단 모드의 하이브리드 버전, 투명도와 드래그 핸들을 사용하여 표시 범위를 표시합니다.
물론 더 많은 확장 프로그램이 여러분의 상상력을 기다리고 있습니다.
호환 대상: ie6/7/8, firefox 3.6.2, Opera 10.51, safari 4.0.4, chrome 4.1

프로그램 설명

【 확장 모드]

지난번에는 ImagesLazyLoad가 확장을 위해 상속을 사용했다면, 이번에는 확장을 위해 플러그인을 사용합니다.

먼저 기본 모드를 살펴보겠습니다. 이러한 모드는 다음과 유사한 구조로 ImageZoom._MODE에 저장됩니다.

코드 복사 코드는 다음과 같습니다.
ImageZoom._MODE = {
모드 이름: {
옵션: {
...
},
메서드: {
init: function() {
...
},
...
}
},
. ..
}

모드 이름은 기본 모드의 이름이고, 옵션은 선택적 매개변수 확장이며, 메소드는 프로그램 구조의 확장입니다.
기본 모드에는 '팔로우', '처리', '자르기' 모드가 있으며, 이에 대해서는 나중에 자세히 소개하겠습니다.
methods에는 확장할 Hook 프로그램이 포함되어 있으며 확장의 주요 부분입니다.
ps: 여기서 언급한 패턴은 "디자인 패턴"에 있는 패턴이 아닙니다.

확장은 프로그램 초기화 시 수행되어야 하며, _initialize 프로그램 이전에 실행되어야 합니다.
원본 프로그램의 구조에 영향을 주지 않기 위해 weaving 방식을 사용하여 _initialize 전에 프로그램을 삽입합니다:


코드 복사 코드는 다음과 같습니다.
ImageZoom.prototype._initialize = (function(){
var init = ImageZoom.prototype._initialize,
... ;
return 함수(){
...
init.apply( this, 인수 )
}
})(); 원래의 기능을 먼저 저장하고 프로그램을 삽입하여 새로운 기능을 만든 다음 원래의 기능을 대체하는 것입니다.

기본 모드의 조합을 고려하여 실제 사용된 모드를 객체에 저장합니다.




코드 복사
코드는 다음과 같습니다: mode = ImageZoom._MODE,
modes = {
"follow": [ mode.follow ],
"handle": [ mode.handle ],
"cropper": [ mode.cropper ],
"handle-cropper": [ mode.handle, mode.cropper ]
}


볼 수 있습니다. "handle-cropper" 모드는 실제로 "handle"과 "cropper"의 조합 모드입니다.

삽입된 프로그램의 주요 작업은 설정된 기본 모드에 따라 확장하는 것입니다.




코드 복사
코드는 다음과 같습니다: var options = 인수[2] if ( options && options.mode &&modes[ options.mode ] ) {
$$A.forEach( 모드[ options.mode ], function( 모드 ){
$$.extend( options, mode.options, false )
$$A.forEach( mode.methods, function( 메소드, 이름 ); 🎜> $$CE.addEvent( this, 이름, 메소드 )
},
}, this );
먼저 옵션 선택적 매개변수 객체를 확장합니다. 선택적 매개변수는 세 번째 매개변수이므로 인수[2]로 얻습니다.
extend의 ​​세 번째 매개변수는 false로 설정됩니다. 이는 동일한 속성이 다시 작성되지 않음, 즉 사용자 정의된 속성 값이 유지됨을 의미합니다.
그런 다음 메소드의 메소드를 후크 함수로 프로그램에 하나씩 추가합니다.

메서드에는 init, load, start, Repair, move, end, dispose가 포함될 수 있으며 이는 각각 ImageZoom의 초기화, 로드, 시작, 수정, 이동, 종료 및 소멸 이벤트에 해당합니다.
확장 중에 다양한 이벤트가 다양한 작업을 수행합니다.
초기화 기능: 확장에 필요한 속성을 설정하는 데 사용됩니다. 이러한 속성은 ImageZoom 자체의 속성과 충돌하지 않습니다. 즉, 이름이 동일합니다.
로드 로딩 기능: 이미지 로딩이 완료되며, 관련 매개변수도 설정됩니다. 주로 확대 효과를 준비하는 데 사용됩니다.
시작 기능: 증폭 효과가 발동될 때 실행됩니다.
수정 수정 기능: 대형 이미지 위치 지정의 좌표 값을 수정하는 데 사용됩니다.
이동 기능: 확대 효과 발동 후 마우스가 움직일 때 실행됩니다.
종료 기능은 확대 효과가 종료될 때 실행됩니다.
폐기 기능: 프로그램을 제거할 때 프로그램을 정리합니다.
ps: 구체적인 위치는 ImageZoom에서 $$CE.fireEvent를 사용하는 섹션을 참조하세요.

위브(weave)와 후크(hook)를 사용하여 프로그램을 확장한 것을 볼 수 있습니다.
위빙 방식은 AOP의 일종으로 원래 프로그램을 변경하지 않고도 확장이 가능하지만 기능 앞이나 뒤에만 프로그램을 추가할 수 있다.
후크 방식은 원본 프로그램에 해당 후크를 설정해야 함께 사용할 수 있지만 위치는 비교적 유연합니다.


【팔로우 모드】

"팔로우" 모드에서는 확대하면 돋보기를 들고 있는 것처럼 디스플레이 프레임이 마우스의 움직임을 따라갑니다.

우선, 디스플레이 프레임이 절대 위치에 있어야 합니다. 디스플레이 프레임이 마우스의 움직임을 따른다는 것을 인식하려면 move에서 해당 왼쪽/상단을 설정하면 됩니다.


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, visible : style.visibility };
$$D.setStyle( Viewer, { display: "block", visible: "hidden" })
}
...
if ( 스타일 ) $$D.setStyle( Viewer, styles );

따라하려면 마우스를 디스플레이 프레임 중앙에 고정하고 먼저 offsetWidth/offsetHeight에 따라 매개변수를 수정합니다. 디스플레이 프레임:
코드 복사 코드는 다음과 같습니다.

this._repairFollowLeft = 뷰어 .offsetWidth / 2; this._repairFollowTop = Viewer.offsetHeight / 2;

디스플레이 상자의 offsetParent가 본체가 아닌 경우 offsetParent를 기준으로 좌표를 수정해야 합니다.

코드 복사 코드는 다음과 같습니다.
if ( !/BODY|HTML/. test(viewer.offsetParent.nodeName ) ) {
var parent = Viewer.offsetParent, ret = $$D.ect( parent )
this._repairFollowLeft = ret.left parent.clientLeft; _repairFollowTop = ret.top parent.clientTop;
}


ps: Maxthon 테스트 중 본문 발견 요소의 offsetParent가 본문이 아니라 html입니다.

프로그램 제거 후 디스플레이 상자 스타일을 복원하려면 로드 프로그램에서 스타일 백업을 수행합니다.


var Viewer = this._viewer, style = Viewer.style, styles;
this._stylesFollow = {
왼쪽: style.left, top: style.top, position: style.position
}


처분에 복원됨:

$$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 그림돋보기 효과(다기능 확장)_자바스크립트 능력
큰 상자는 큰 이미지 객체이고 작은 상자인 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 handler = $$( this.options.handle );
if ( !handle ) {
var body = document.body
handle = body.insertBefore(this ._viewer.cloneNode(false), body.childNodes[0]);
handle.id = "";
handle["_createbyhandle"] =
$$D.setStyle ( handler, { padding: 0, margin: 0, display: "none" } );

사용자 정의 드래그 핸들 개체가 없으면 표시 상자가 드래그 핸들 개체로 복사됩니다.
자동으로 생성된 드래그 핸들 객체의 경우 폐기 시 쉽게 제거할 수 있도록 "_createbyhandle" 속성이 표시로 추가됩니다.

로드할 때 드래그 핸들 스타일을 설정하세요.

코드 복사 코드는 다음과 같습니다.
$$D.setStyle( 핸들, {
위치: "절대",
너비: this._rangeWidth "px",
높이: this._rangeHeight "px",
display: "block",
visibility: "hidden"
})

절대 위치 지정이 필요하며 크기는 _rangeWidth/_rangeHeight에 따라 설정됩니다.
표시 및 가시성을 설정하는 것은 아래 매개변수를 구하는 것입니다.

먼저 원본 이미지 좌표를 기준으로 수정 매개변수를 가져옵니다.


this._repairHandleLeft = ret.left this._repairLeft - handler.clientLeft
this._repairHandleTop = ect; .top this ._repairTop - handler.clientTop

추종 모드와 유사하며 offsetParent 위치도 수정해야 합니다.


코드 복사 코드는 다음과 같습니다.
if (handle.offsetParent.nodeName.toUpperCase() != "BODY" ) {
var parent = handler.offsetParent , ret = $$D .direct( parent );
this._repairHandleLeft -= ret.left parent.clientLeft;
this._repairHandleTop -= ret.top parent.clientTop; 🎜>

다시 숨기기:

$$D.setStyle(handle, { display: "none", visible: "visible" })

시작 시 , 드래그 핸들 객체를 표시합니다.

이동 시 대형 이미지 위치 지정 좌표에 따라 드래그 핸들 위치 설정:





코드 복사
코드는 다음과 같습니다. var style = this._handle.style, scale = this._scale style.left = Math.ceil( this._repairHandleLeft - x / scale ) "px ";
style.top = Math.ceil( this._repairHandleTop - y / scale ) "px";


마지막으로 드래그 핸들 개체를 숨깁니다.

【컷 모드】

"컷"은 선택한 부분이 완전히 투명해지고 나머지 부분은 반투명해지는 효과입니다.
주로 클리핑을 통해 이루어지지만 구체적인 원리는 사진 자르기 효과에서 확인할 수 있습니다.

커팅 효과를 얻으려면 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;
cropper.height = image.height;
$$D.setStyle( 자르기, {
위치: "절대",
왼쪽: ret.left this._repairLeft "px",
상단: ret.top this._repairTop "px"
})

원본 이미지 개체를 거의 복사하여 원본 이미지 개체 위에 완전히 배치합니다.

시작할 때 커팅 레이어를 표시하고 투명도에 따라 원본 이미지를 반투명 상태로 설정합니다.

이동 시 큰 이미지 이동 좌표에 따라 자르기 레이어의 클리핑 범위를 설정하세요.
코드 복사 코드는 다음과 같습니다.

var w = this._rangeWidth, h = this._rangeHeight, scale = this._scale
x = Math.ceil( -x / scale; ); y = Math.ceil( -y / scale );
this._cropper.style.clip = "ret(" y "px " (x w) "px " (y h) "px " x "px)" ;

마지막으로 커팅 레이어를 숨기고 원본 이미지를 불투명하게 재설정하여 원래 상태로 복원합니다.

절단층을 제거한 후 폐기하는 것도 잊지 마세요.


사용 팁

확장 효과가 필요한 경우에만 이 확장 기능을 추가하면 됩니다.

ImageZoom._MODE를 직접 확장할 수 있습니다. 확장 후에는 모드에 해당 모드를 추가해야 합니다.

여러 기본 모드를 결합하여 동시에 사용할 수 있으며, 자세한 내용은 "손잡이-자르기" 모드를 참고하세요.


사용 지침

디스플레이 모드를 설정하는 추가 선택적 참조 모드가 있다는 점을 제외하면 사용 방법은 ImageZoom과 유사합니다.
"handle" 모드를 사용하는 경우 선택적 매개변수의 "handle" 속성으로 드래그 핸들 개체를 설정할 수 있습니다.
'자르기' 모드를 사용할 때 선택적 매개변수의 'opacity' 속성으로 투명도를 설정할 수 있습니다.
"자르기 핸들" 모드를 사용하는 경우 위의 매개변수를 모두 사용할 수 있습니다.
프로그램 소스 코드
코드 복사 코드는 다음과 같습니다.

ImageZoom._MODE = {
//Follow
"follow": {
메서드: {
init: function() {
this._stylesFollow = null;/ /백업 스타일
this._repairFollowLeft = 0;//수정 좌표 왼쪽
this._repairFollowTop = 0;//수정 좌표 상단
},
load: function() {
var 뷰어 = this._viewer, style = Viewer.style, styles;
this._stylesFollow = {
왼쪽: style.left, 위쪽: style.top, 위치: style.position
}; .style.position = "absolute";
//수정 매개변수 가져오기
if ( !viewer.offsetWidth ) {//Hide
styles = { display: style.display, visible: style.visibility } ;
$$D.setStyle( Viewer, { display: "block", visible: "hidden" })
}
//중앙 위치 수정
this._repairFollowLeft = Viewer.offsetWidth / 2 ; this._repairFollowTop = Viewer.offsetHeight / 2;
//offsetParent 위치 수정
if ( !/BODY|HTML/.test( Viewer.offsetParent.nodeName ) ) {
var parent = Viewer.offsetParent, ret = $$D.direct( parent );
this._repairFollowLeft = ret.left parent.clientLeft;
this._repairFollowTop = ret.top parent.clientTop
} 🎜> if ( 스타일 ) { $$D.setStyle( 뷰어, 스타일 ) }
},
repair: function(e, pos) {
var Zoom = this._zoom,
viewerWidth = this ._viewerWidth,
viewerHeight = this._viewerHeight;
pos.left = (viewerWidth / 2 - pos.left ) * (viewerWidth / Zoom.width - 1 )
viewerHeight / 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": {
옵션: {//기본값 value
handle: ""//드래그 핸들 객체
},
methods: {
init: function() {
var handler = $$( this.options.handle )
if ( !handle ) {//정의되지 않은 경우 표시 상자를 복사본으로 교체합니다.
var body = document.body
handle = body.insertBefore(this._viewer.cloneNode(false), body .childNodes[0] ; 0, 여백: 0, 표시: "none" } );

this._handle = handler;
this._repairHandleLeft = 0;//왼쪽 좌표
._repairHandleTop = 0;/ /수정 상단
},
load: function() {
var handler = this._handle, ret = this._direct
$$D.setStyle(handle, {
위치: "절대",
너비: this._rangeWidth "px",
높이: this._rangeHeight "px",
디스플레이: "블록",
가시성: "숨김 "
} );
//수정 매개변수 가져오기
this._repairHandleLeft = ret.left this._repairLeft - handler.clientLeft;
this._repairHandleTop = ret.top this._repairTop - 핸들. clientTop;
/ /offsetParent 위치 수정
if ( !/BODY|HTML/.test(handle.offsetParent.nodeName) ) {
var parent = handler.offsetParent, ret = $$D.lect( parent );
this._repairHandleLeft -= ret.left parent.clientLeft;
this._repairHandleTop -= ret.top parent.clientTop;
//Hide
$$D. setStyle(handle, {display: "none", visible: "visible" });
start: function() {
this._handle.style.display = "block" >},
move: function(e, x, y) {
var style = this._handle.style, scale = this._scale
style.left = Math.ceil( this._repairHandleLeft - x / scale ) "px ";
style.top = Math.ceil( this._repairHandleTop - y / scale ) "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": {
옵션: {//기본값
불투명도 : .5//투명성
},
메서드: {
init: function() {
var body = document.body,
cropper = body.insertBefore(document.createElement(" img"), body.childNodes[0]);
cropper.style.display = "none";

this._cropper = 자르기;
this.opacity = this.options.opacity;
},
load: function() {
varcropper = this._cropper, image = this._image, ret = this._ect
cropper.src = image.src; Cropper.width = image.width;
cropper.height = image.height;
$$D.setStyle( Cropper, {
position: "absolute",
left: ret.left. _repairLeft "px",
top: ret.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, scale = this._scale;
x = Math.ceil( -x / scale ) y = Math.ceil( -y / scale ); .style.clip = " ret(" 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 =args[2]
if ( options && options. 모드 && 모드[ options.mode ] ) {
$$A.forEach( 모드[ options.mode ], function( 모드 ){
//扩 Exhibitionoptions
$$.extend( 옵션, 모드. options, false );
//추가 확장
$$A.forEach( mode.methods, function( method, name ){
$$CE.addEvent( this, name, method );
}, this );
}, this );
}
init.apply( this, 인수 )
})();
地址
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으로 문의하세요.