ImageZoom image magnifier effect (Multi-Function Extension)

Source: Internet
Author: User

It mainly expands the display modes of the source image and the display box, including the following modes:
"Follow" follow Mode: displays the effect of moving the box following the mouse;
"Handle": There is a slider on the source image to mark the display range;
"Cropper" cutting mode: the original image is marked with an opaque display range, and other parts are displayed with translucent display;
"Handle-cropper" drag-and-drop cutting mode: a mixed version of the drag-and-drop mode. The display range is marked with transparency and drag-and-drop.
Of course, more extensions are waiting for your imagination to explore.
Compatible with: ie6/7/8, firefox 3.6.2, opera 10.51, safari 4.0.4, chrome 4.1

Program description

[Expansion mode]

The last time ImagesLazyLoad used inheritance for extension, this time it was extended in the form of plug-ins.

First, let's look at the basic MODE. These modes are saved in ImageZoom. _ MODE, similar to the following structure:

Copy codeThe Code is as follows:
ImageZoom. _ MODE = {
Mode name :{
Options :{
...
},
Methods :{
Init: function (){
...
},
...
}
},
...
}

The Mode name is the name of the basic mode, options is an optional parameter extension, and methods is an extension of the program structure.
The basic modes include "follow", "handle", and "cropper", which will be detailed later.
Methods contains the hook program to be extended and is the main part of the extension.
Ps: the mode mentioned here is not in the "design mode.

The extension needs to be performed during program initialization and should be executed before the _ initialize program.
In order not to affect the structure of the original program, we use the weaving method to insert a program before _ initialize:

Copy codeThe Code is as follows:
ImageZoom. prototype. _ initialize = (function (){
Var init = ImageZoom. prototype. _ initialize,
...;
Return function (){
...
Init. apply (this, arguments );
}
})();

The principle is to save the original function, insert a program to form a new function, and then replace the original function.

Considering the basic mode of combination, an object storage mode is used:
Copy codeThe Code is as follows:

Mode = ImageZoom. _ MODE,
Modes = {
"Follow": [mode. follow],
"Handle": [mode. handle],
"Cropper": [mode. cropper],
"Handle-cropper": [mode. handle, mode. cropper]
};

We can see that the "handle-cropper" mode is actually a combination of "handle" and "cropper.

The main task of the inserted program is to expand according to the set basic mode:
Copy codeThe Code is as follows:
Var options = arguments [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, method );
}, This );
}, This );
}

First, extend the options optional parameter object. Because the optional parameter is the third parameter, use arguments [2] to obtain it.
If the third parameter of extend is set to false, the same attribute is not overwritten, that is, the custom attribute value is retained.
Then, add the methods in methods to the program one by one as hook functions.

Methods can contain init, load, start, repair, move, end, and dispose methods, which correspond to initialization, loading, start, correction, movement, end, and destruction events in ImageZoom respectively.
During expansion, different events execute different tasks:
Init initialization function: Used to set attributes required for extension. Note that these attributes do not conflict with the attributes of ImageZoom, that is, duplicate names.
Load function: The image is loaded, and relevant parameters are also set. The function is mainly used to prepare for the amplification.
Start function: This function is executed when the amplification is triggered.
Repair correction function: used to modify the coordinates of a large image.
Move function: This function is executed when the mouse moves after the zoom in is triggered.
The end function is executed when the end is enlarged.
Dispose destroy function: clears the program when it is removed.
Ps: see $ CE. fireEvent in ImageZoom for details.

We can see that weave and hook are used to expand the program.
The weaving method is an aop method that can be extended without changing the original program, but can only be added before or after the function.
The Hook method can be used only when the corresponding hook is set in the original program, but the location is relatively flexible.


[Follow Mode]

In the "follow" follow Mode, when you zoom in, the display box will move with the mouse, just like the effect with a magnifier.

First, the display box must be absolutely positioned. To move the display box following the mouse, you just need to set the corresponding left/top in the move:


Var style = this. _ viewer. style;
Style. left = e. pageX-this. _ repairFollowLeft + "px ";
Style. top = e. pageY-this. _ repairFollowTop + "px ";
Here, pageX/pageY is the current coordinate of the mouse, and _ repairFollowLeft/_ repairFollowTop is the correction parameter of the coordinate.

The correction parameters are set in load. If the display box is hidden, use the previous article to obtain the display range:
Copy codeThe Code is as follows:
If (! Viewer. offsetWidth ){
Styles = {display: style. display, visibility: style. visibility };
$ D. setStyle (viewer, {display: "block", visibility: "hidden "});
}
...
If (styles) {$ D. setStyle (viewer, styles );}

To keep the cursor in the center of the display box at any time, first modify the parameters according to the offsetWidth/offsetHeight of the display box:
Copy codeThe Code is as follows:
This. _ repairFollowLeft = viewer. offsetWidth/2;
This. _ repairFollowTop = viewer. offsetHeight/2;

If the offsetParent in the displayed box is not the body, you need to modify the coordinates according to offsetParent:
Copy codeThe Code is as follows:
If (! /BODY | HTML/. test (viewer. offsetParent. nodeName )){
Var parent = viewer. offsetParent, rect = $ D. rect (parent );
This. _ repairFollowLeft + = rect. left + parent. clientLeft;
This. _ repairFollowTop + = rect. top + parent. clientTop;
}

Ps: During the Maxthon test, the offsetParent of the body sub-element is not the body but the html.

To restore the style of the display box after removing the program, a style backup is made in the load program:
Copy codeThe Code is as follows:
Var viewer = this. _ viewer, style = viewer. style, styles;
This. _ stylesFollow = {
Left: style. left, top: style. top, position: style. position
};

And restore in dispose:

$ D. setStyle (this. _ viewer, this. _ stylesFollow );

Now the basic effect has been achieved, but due to the limitation of the range of moving the big picture, when the mouse moves close to the border, the big picture will be stuck and will not be moved.
In order to achieve the effect that the big chart will continue to change when the mouse moves, the moving coordinates are corrected in repair:
Copy codeThe Code is as follows:
Pos. left = (viewerWidth/2-pos. left) * (viewerWidth/zoom. width-1 );
Pos. top = (viewerHeight/2-pos. top) * (viewerHeight/zoom. height-1 );

The principle is somewhat complicated. Take the horizontal coordinates as an example. first look:

A large box represents a large image object, and a small box represents a display box.
The current position is the actual display position based on the mouse coordinates, and the target position is the position to achieve the effect.
Some physical or geometric knowledge should understand this equation: x/y = m/n
Available: y = x * n/m = x * (zoom. width-viewerWidth)/zoom. height
The current coordinate of x can be obtained through pos. left: x = viewerWidth/2-pos. left
Finally, we get: left =-y = (viewerWidth/2-pos. left) * (viewerWidth/zoom. width-1)
The vertical coordinates are similar.


[Pull handle mode]

The slider is a layer on the source image to indicate the position and range of the display range in the source image.
The display range can be obtained based on _ rangeWidth/_ rangeHeight.
You can specify the position based on the coordinates of the mouse or big image positioning.
If the mouse coordinates, you must also do other processing, such as range control, and positioning the coordinates based on the big image is much more convenient and accurate, the program also uses the following method.

First, define a _ handle object in init:
Copy codeThe Code is as follows:
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;
}
$ D. setStyle (handle, {padding: 0, margin: 0, display: "none "});

If you do not have a custom drag-and-drop object, the display box is copied as the drag-and-drop object.
The "_ createbyhandle" attribute is added to automatically generated drag-and-drop objects to facilitate removal in dispose.

When loading, set the drag handle style:
Copy codeThe Code is as follows:
$ D. setStyle (handle ,{
Position: "absolute ",
Width: this. _ rangeWidth + "px ",
Height: this. _ rangeHeight + "px ",
Display: "block ",
Visibility: "hidden"
});

Absolute positioning is required, and the size is set according to _ rangeWidth/_ rangeHeight.
Set display and visibility to obtain the following parameters.

Obtain the correction parameters based on the source coordinate:


This. _ repairHandleLeft = rect. left + this. _ repairLeft-handle. clientLeft;
This. _ repairHandleTop = rect. top + this. _ repairTop-handle. clientTop;

Similar to the following mode, you must also modify the offsetParent location:

Copy codeThe Code is as follows:
If (handle. offsetParent. nodeName. toUpperCase ()! = "BODY "){
Var parent = handle. offsetParent, rect = $ D. rect (parent );
This. _ repairHandleLeft-= rect. left + parent. clientLeft;
This. _ repairHandleTop-= rect. top + parent. clientTop;
}


Then hide again:

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

The drag-and-drop objects are displayed at start.

When moving, set the drag-and-pull Positioning Based on the positioning coordinates of the big image:

Copy codeThe Code is as follows:
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 ";

Hide the drag-and-handle object at end.


[Cutting mode]

"Cutting" means that the selected part is completely transparent, and the other part is translucent.
It is mainly implemented through clip. The specific principle can be used to see the image cutting effect.

To achieve the cutting effect, you need to create a _ cropper cutting layer in init:

Copy codeThe Code is as follows:
Var body = document. body,
Cropper = body. insertBefore (document. createElement ("img"), body. childNodes [0]);
Cropper. style. display = "none ";

Set the cutting layer in load:

Copy codeThe Code is as follows:
Cropper. src = image. src;
Cropper. width = image. width;
Cropper. height = image. height;
$ D. setStyle (cropper ,{
Position: "absolute ",
Left: rect. left + this. _ repairLeft + "px ",
Top: rect. top + this. _ repairTop + "px"
});

It is similar to copying an original image object and absolutely locating it on the source image object.

At start, the cutting layer is displayed and the source image is translucent Based on the transparency.

When moving, set the clip range for the cut Layer Based on the coordinates of moving the big image:
Copy codeThe Code is as follows:
Var w = this. _ rangeWidth, h = this. _ rangeHeight, scale = this. _ scale;
X = Math. ceil (-x/scale); y = Math. ceil (-y/scale );
This. _ cropper. style. clip = "rect (" + y + "px" + (x + w) + "px" + (y + h) + "px" + x + "px )";

At the end, hide the cut layer and reset the source image to be opaque to restore the original state.

Remember to remove the cut layer in dispose.


Tips

You need to add this extension only when you need the extension effect.

You can expand ImageZoom. _ MODE on your own. After the extension, remember to add the corresponding MODE in modes.

You can combine multiple basic modes to use them at the same time. For details, refer to the "handle-cropper" mode.


Instructions for use

The usage is similar to that of ImageZoom, but an optional reference mode is provided to set the display mode.
When the "handle" mode is used, you can set the "handle" attribute of the optional parameter.
When the "cropper" mode is used, you can set the transparency of the "opacity" attribute of the optional parameter.
The preceding two parameters can be used when the "handle-cropper" mode is used.
Program source code
Copy codeThe Code is as follows:
ImageZoom. _ MODE = {
// Follow
"Follow ":{
Methods :{
Init: function (){
This. _ stylesFollow = null; // backup Style
This. _ repairFollowLeft = 0; // you can modify the coordinate left.
This. _ repairFollowTop = 0; // you can specify the top coordinates.
},
Load: function (){
Var viewer = this. _ viewer, style = viewer. style, styles;
This. _ stylesFollow = {
Left: style. left, top: style. top, position: style. position
};
Viewer. style. position = "absolute ";
// Obtain the corrected parameters
If (! Viewer. offsetWidth) {// hide
Styles = {display: style. display, visibility: style. visibility };
$ D. setStyle (viewer, {display: "block", visibility: "hidden "});
}
// Correction center location
This. _ repairFollowLeft = viewer. offsetWidth/2;
This. _ repairFollowTop = viewer. offsetHeight/2;
// Modify the offsetParent position
If (! /BODY | HTML/. test (viewer. offsetParent. nodeName )){
Var parent = viewer. offsetParent, rect = $ D. rect (parent );
This. _ repairFollowLeft + = rect. left + parent. clientLeft;
This. _ repairFollowTop + = rect. top + parent. clientTop;
}
If (styles) {$ D. setStyle (viewer, styles );}
},
Repair: function (e, pos ){
Var zoom = this. _ zoom,
ViewerWidth = this. _ viewerWidth,
ViewerHeight = this. _ viewerHeight;
Pos. left = (viewerWidth/2-pos. left) * (viewerWidth/zoom. width-1 );
Pos. top = (viewerHeight/2-pos. top) * (viewerHeight/zoom. height-1 );
},
Move: function (e ){
Var style = this. _ viewer. style;
Style. left = e. pageX-this. _ repairFollowLeft + "px ";
Style. top = e. pageY-this. _ repairFollowTop + "px ";
},
Dispose: function (){
$ D. setStyle (this. _ viewer, this. _ stylesFollow );
}
}
},
// Drag handle
"Handle ":{
Options: {// Default Value
Handle: "" // drag handle object
},
Methods :{
Init: function (){
Var handle =$ $ (this. options. handle );
If (! Handle) {// replace it with the copy display box if it is not defined
Var body = document. body;
Handle = body. insertBefore (this. _ viewer. cloneNode (false), body. childNodes [0]);
Handle. id = "";
Handle ["_ createbyhandle"] = true; // generate an identifier for removing
}
$ D. setStyle (handle, {padding: 0, margin: 0, display: "none "});

This. _ handle = handle;
This. _ repairHandleLeft = 0; // The left coordinate is corrected.
This. _ repairHandleTop = 0; // you can specify the top coordinates.
},
Load: function (){
Var handle = this. _ handle, rect = this. _ rect;
$ D. setStyle (handle ,{
Position: "absolute ",
Width: this. _ rangeWidth + "px ",
Height: this. _ rangeHeight + "px ",
Display: "block ",
Visibility: "hidden"
});
// Obtain the corrected parameters
This. _ repairHandleLeft = rect. left + this. _ repairLeft-handle. clientLeft;
This. _ repairHandleTop = rect. top + this. _ repairTop-handle. clientTop;
// Modify the offsetParent position
If (! /BODY | HTML/. test (handle. offsetParent. nodeName )){
Var parent = handle. offsetParent, rect = $ D. rect (parent );
This. _ repairHandleLeft-= rect. left + parent. clientLeft;
This. _ repairHandleTop-= rect. top + parent. clientTop;
}
// Hide
$ D. setStyle (handle, {display: "none", visibility: "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 ":{
Options: {// Default Value
Opacity:. 5 // transparency
},
Methods :{
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;
Cropper. width = image. width;
Cropper. height = image. height;
$ D. setStyle (cropper ,{
Position: "absolute ",
Left: rect. left + this. _ repairLeft + "px ",
Top: rect. top + this. _ repairTop + "px"
});
},
Start: function (){
This. _ cropper. style. display = "block ";
$ 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 );
This. _ cropper. 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 = "none ";
},
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 = arguments [2];
If (options & options. mode & modes [options. mode]) {
$ A. forEach (modes [options. mode], function (mode ){
// Extended options
$. Extend (options, mode. options, false );
// Extended hook
$ A. forEach (mode. methods, function (method, name ){
$ CE. addEvent (this, name, method );
}, This );
}, This );
}
Init. apply (this, arguments );
}
})();
Online Demo address http://demo.jb51.net/js/ImageZoom_ext/ImageZoom_ext.htm
Packaging http://www.jb51.net/jiaoben/25809.html
Source: http://www.cnblogs.com/cloudgamer/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.