The
Mainly expands the display mode of the original image and display box, and has the following modes:
"Follow" following mode: The Display box can follow the effect of mouse movement;
Handle drag handle mode: There is a drag handle on the original to mark the display range;
"Cropper" Cutting mode: The original image with opaque to mark the display range, the other parts with semitransparent display;
Handle-cropper drag-and-drop mode: A mixed version of drag-and-cut mode, with transparency and drag handles to mark the display range.
Of course more extensions await your imagination to discover.
Compatible: IE6/7/8, Firefox 3.6.2, opera 10.51, Safari 4.0.4, Chrome 4.1
Program Description
Extended mode
Last imageslazyload used inheritance to do the extension, This time in the form of plug-ins to do expansion.
First look at the underlying pattern, which is stored in Imagezoom._mode, similar to the structure:
Copy code code as follows:
Imagezoom._mode = {
Schema name: {
Options: {
. ..
},
methods: {
Init:function () {
...
},
...
}
},
...
}
Where the schema name is the name of the underlying schema, options is an optional parameter extension, and methods is an extension of the program structure.
The underlying pattern includes "follow", "Handle" and "cropper" modes, which are described in detail later.
The methods contains the hook program to extend, which is the main part of the expansion.
PS Tutorial: The pattern here is not the pattern inside the "design pattern".
Extensions need to be performed when the program is initialized, and before the _initialize program.
In order not to affect the structure of the original program, here the Weave method is used to insert a program before _initialize:
Copy code code 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.
Taking into account the combined underlying pattern, an object is used to save the pattern that is actually used:
Copy code code as follows:
mode = Imagezoom._mode,
Modes = {
"Follow": [Mode.follow],
"Handle": [Mode.handle],
"Cropper": [Mode.cropper],
"Handle-cropper": [Mode.handle, Mode.cropper]
};
You can see that the "Handle-cropper" mode is actually a combination of "handle" and "cropper". The main task of the
inserted program is to extend it according to the set base pattern:
Copy the Code as follows:
var options = arguments[2];
if (options && options.mode && modes[Options.mode]) {
$ $A. ForEach (modes[options.mode), Fu Nction (mode) {
$$.extend (options, mode.options, false);
$ $A. ForEach (Mode.methods, function (method, name) {
$ $CE. Addevent (This, name, method);
}, this);
}, this);
}
First, the options optional Parameter object is extended, and because the optional parameter is the third parameter, it is obtained with arguments[2].
The third parameter of extend is set to false, which means that the same property is not overridden, which preserves the custom property value.
Then add the method inside the methods as a hook function to the program.
Methods can include init, load, start, repair, move, end, dispose of the methods, respectively, corresponding to the imagezoom initialization, loading, starting, correcting, moving, ending and destroying events.
At the time of the extension, different events perform different tasks:
Init initialization function: Used to set the properties required for the extension, note that these properties do not conflict with the properties of the imagezoom itself, that is, the duplicate name.
Load load function: The picture loading completes, the correlation parameter also sets up completes, mainly does performs the amplification effect before the preparation work.
Start function: Executes when a magnification effect is triggered.
Repair correction function: The coordinate value used to correct large image positioning.
Move moving function: When the mouse is moved, after the magnification is triggered.
End function is performed when the magnification effect is ended.
Dispose destroy function: Cleans the program when the program is removed.
PS: Specific location reference Imagezoom use the $ $CE. FireEvent section.
You can see that this is an extension of the program using the Weaving Method (weave) and the hook method (hook).
The weaving method is an AOP that can be extended without altering the original program, but only before or after the function is added to the program.
The hook method must be set up in the original program to match the hook in order to use, but the position is relatively flexible.
"Follow Mode"
In the "Follow" follow mode, when zooming in, the display box will move with the mouse, just like the effect of holding a magnifying glass.
First show the box to absolute positioning, to achieve the display box to follow the mouse movement, as long as in move to set the corresponding left/top on the line:
var style = This._viewer.style;
Style.left = e.pagex-this._repairfollowleft + "px";
Style.top = e.pagey-this._repairfollowtop + "px";
Where Pagex/pagey is the current coordinate of the mouse, _repairfollowleft/_repairfollowtop is the correction parameter of the coordinate.
The correction parameters are set in load and, if the display box is hidden, get the parameters using the previous method to get the display range:
Copy code code 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);}
In order to follow, let the mouse fixed in the center of the display box, first, according to the display box offsetwidth/offsetheight correction parameters:
Copy code code as follows:
This._repairfollowleft = VIEWER.OFFSETWIDTH/2;
This._repairfollowtop = VIEWER.OFFSETHEIGHT/2;
If the offsetparent of the display box is not body, you also need to modify the coordinates according to offsetparent:
Copy code code 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: In the Maxthon test found that the body child elements of the offsetparent is not the body but HTML.
To restore the style of the display box after removing the program, a style backup is made in the load program:
Copy code code 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 that the basic effect has been achieved, but due to the large size of the movement limit, when the mouse moved close to the boundary, the large image will not move.
In order to achieve the effect that the large image will change continuously when the mouse is moving, the moving coordinates are fixed in the repair:
Copy code code 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 slightly complicated, take the horizontal coordinate as an example, look at the following figure first:
A generous box represents a large drawing object, and a small box represents a display box.
The current position is where the actual display is based on the mouse coordinates, and where the destination wants to achieve the effect.
Some physical or geometrical knowledge should understand this equation: x/y = m/n
Can be launched: y = x * n/m = x * (zoom.width-viewerwidth)/Zoom.height
x current coordinates can be obtained by pos.left: x = VIEWERWIDTH/2-Pos.left
Finally got: left =-y = (VIEWERWIDTH/2-pos.left) * (viewerwidth/zoom.width-1)
The vertical coordinates are similar.
"Drag handle Mode"
The drag handle is a layer, above the original image, used to indicate the position and range of the display range in the original image.
The display range can be obtained according to _rangewidth/_rangeheight.
As for the location of the specified can be based on mouse coordinates or large map positioning coordinates to set.
If the mouse coordinates must also do other processing, such as range control, and according to the large map positioning coordinates relatively convenient and more accurate, the program is also used in the latter method.
First, define a _handle drag handle object in init:
Copy code code 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 handle object, the display box is copied as a drag handle object.
For automatically generated drag-handle objects, the "_createbyhandle" property is added as a marker to facilitate removal in Dispose.
When load, set the drag handle style:
Copy code code 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 dimensions are set according to the _rangewidth/_rangeheight.
Display and visibility are set up to get the parameters below.
First, according to the original coordinates to get the correction parameters:
This._repairhandleleft = Rect.left + this._repairleft-handle.clientleft;
This._repairhandletop = Rect.top + this._repairtop-handle.clienttop;
Similar to follow pattern, also do offsetparent positioning correction:
Copy code code 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;
}
And then hide it again:
$ $D. SetStyle (handle, {display: "None", Visibility: "visible"});
At start, the drag handle object is displayed.
At move time, set the drag handle position according to the large figure positioning coordinates:
Copy code code 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";
Hides the drag handle object at end.
"Cutting Mode"
"Cutting" is the choice of partially transparent, the other partially translucent effect.
Mainly through clip to achieve, the specific principle can see the picture cutting effect.
In order to achieve the cutting effect, you need to create a new _cropper cutting layer in init:
Copy code code as follows:
var BODY = document.body,
Cropper = Body.insertbefore (document.createelement ("img"), body.childnodes[0]);
Cropper.style.display = "None";
and set this cutting layer in load:
Copy code code 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 almost a copy of an original object, and absolutely positioned above the original object.
At start, the cutting layer is displayed, and the artwork is semi-transparent based on the transparency.
In move, set the range of the cutting layer to be clip according to the coordinates of the large figure moving:
Copy code code 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 end, hide the cutting layer and reset the original image to be opaque to restore the old state.
Also remember to remove the cutting layer in Dispose.
Use Tips
You need to add this extender if you want to extend the effect.
Imagezoom._mode can be extended on its own, after expansion to remember to add the corresponding pattern in modes.
You can combine multiple base modes to use at the same time, referring specifically to "Handle-cropper" mode.
Instructions for use
The use method is similar to Imagezoom, just one more optional reference mode setting display modes.
When using handle mode, the handle property of an optional parameter can set a drag handle object.
When using cropper mode, the "opacity" property of an optional parameter can set transparency.
The above two parameters are available when using the Handle-cropper mode.
Program Source Tutorial
Copy code code as follows:
Imagezoom._mode = {
Follow
"Follow": {
Methods: {
Init:function () {
This._stylesfollow = null;//Backup style
This._repairfollowleft = 0;//Correction coordinate left
This._repairfollowtop = 0;//correction coordinates top
},
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";
Get correction parameters
if (!viewer.offsetwidth) {//hidden
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;
Fixed 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 values
Handle: ""///Drag handle Object
},
Methods: {
Init:function () {
var handle = $$ (This.options.handle);
if (!handle) {//without definition, replace with a copy display box
var body = document.body;
Handle = Body.insertbefore (This._viewer.clonenode (false), body.childnodes[0]);
Handle.id = "";
handle["_createbyhandle"] = true;//build identity for removing
}
$ $D. SetStyle (handle, {padding:0, margin:0, display: "None"});
This._handle = handle;
This._repairhandleleft = 0;//Correction coordinate left
This._repairhandletop = 0;//correction coordinates top
},
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"
});
Get correction parameters
This._repairhandleleft = Rect.left + this._repairleft-handle.clientleft;
This._repairhandletop = Rect.top + this._repairtop-handle.clienttop;
Fixed 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;
}
}
},
Cutting
"Cropper": {
Options: {//default values
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) {
Expand Options
$$.extend (Options, mode.options, false);
Extend Hook
$ $A. ForEach (Mode.methods, function (method, name) {
$ $CE. Addevent (This, name, method);
}, this);
}, this);
}
Init.apply (this, arguments);
}
})();