View Full Version : Expando + move onto screen
dbooksta
08-21-2013, 04:32 AM
I've spent hours on this to no avail: Trying to add a feature to Expando (http://www.dynamicdrive.com/dynamicindex4/expandoimage.htm) that will detect if the expanded image will be off the viewable screen, and if so to move it either during or after the expansion routine so that, while expanded, its offsetLeft is not negative, but on contraction it returns to its original position.
Any help appreciated!
vwphillips
08-21-2013, 02:18 PM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title></title>
<style type="text/css">
/*<![CDATA[*/
.expand {
position:relative;left:0px
}
/*]]>*/
</style>
</head>
<body>
<center>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<img src="http://www.vicsjavascripts.org.uk/StdImages/Egypt5.jpg" class="expand Magnify:2 Group:tom Animate:500 SRC:http://www.vicsjavascripts.org.uk/StdImages/Egypt6.jpg" />
<img src="http://www.vicsjavascripts.org.uk/StdImages/Egypt7.jpg" class="expand Magnify:1.5 Group:tom MagWidth:500" />
</center>
<div style="width:3000px;height:2000px;" ></div>
<script type="text/javascript">
/*<![CDATA[*/
// Image Expand III (30-August-2013) DRAFT
// by Vic Phillips - http://www.vicsjavascripts.org.uk/
/*
Images on the page may be magnified and displayed centered in the window or overlayed over the original image
on clicking or mouseover of the original image. Clicking the enlarged image will close the magnified image.
Script options are defined in the class name of each image.
These options include:
the magnification factor or defined width,
the enlarged image src,
the animation speed,
the enlarged image z-Index,
the execution event type,
the display centered in the window or overlayed over the original image,
and grouping of images so only one enlarged image is open at one time.
The functional code size is 3.79K.
****** Application Notes.
**** The HTML and CSS Code.
The images to enlarge must be assigned a class attribute.
This class attribute must include a key word to identify the image enlarge requirement to the script.
This class attribute may also include script options specific to the image.
These options will have priority over the script initialization options.
** Examples.
<img src="Egypt5.jpg" class="expand Magnify:2 Group:tom Animate:500 SRC:Egypt6.jpg" />
<img src="Egypt7.jpg" class="expand Magnify:1.5 EventType:mouseover Group:tom MagWidth:500" />
**** Class Name Script Options
Magnify: = the magnification of the enlarged image. (default = 2)
MagWidth: = the defined width of the enlarged image(the height is scaled). (default = option Magnify)
SRC: = the src of the magnified image. (default = the image src)
Animate: = the animation duration in milli seconds. (default = 1000)
zIndex: = the z-Index of the magnified image. (default = 101)
EventType: = the event type to execute magnify image, click or mouseover. (default = click)
Toggle: = true = toggle the enlarged image on clicking the original image. (default = no toggle)
Display: = center = center in the window, overlay = overlay the original image. (default = center)
Group: = only one magnified image with the same group name can be open at one time. (default = no grouping)
**** Initializing the Script
The script is initialized after the page has loaded passing the 'keyword' and optional default script options as a object'
e.g.
zxcImageExpandIII({
KeyWord:'expand', // the image class attribute 'keyword' to identify the enlarge image requirement. (string)
// Optional Default Options(Class Name Script Options have priority).
Magnify:2, // the magnification of the enlarged image. (number, default = 2)
MagWidth:500, // the defined width of the enlarged image(the height is scaled). (number, default = option Magnify)
Animate:1000, // the animation duration in milli seconds. (number, default = 1000)
zIndex:101, // the z-Index of the magnified image. (number, default = 101)
EventType:'click', // the event type to execute magnify image, click or mouseover. (string, default = click)
Toggle:false, // true = toggle the enlarged image on clicking the original image. (boolean, default = no toggle)
Display:'center', // center = center in the window, overlay = overlay the original image. (string, default = center)
Group:'tom' // only one magnified image with the same group name can be open at one time. (string, default = no grouping)
});
*/
// Functional Code - NO NEED to Change.
function zxcImageExpandIII(op){
var imgs=document.body.getElementsByTagName('IMG'),mk=document.createElement('DIV'),c,o,i,z0=0,z0a;
mk.style.position='absolute';
mk.style.bottom=mk.style.right='0px';
mk.style.width=mk.style.height='0px';
document.body.appendChild(mk);
for (;z0<imgs.length;z0++){
c=imgs[z0].className;
if ((' '+c+' ').match(' '+op.KeyWord+' ')){
o={mk:mk,img:imgs[z0]};
c=c.split(' ');
for (z0a=0;z0a<c.length;z0a++){
i=c[z0a].indexOf(':');
if (i>2){
o[c[z0a].slice(o,i).toLowerCase()]=c[z0a].slice(i+1);
}
}
new zxcImageExpandIIIOOP(o,op);
}
}
}
function zxcImageExpandIIIOOP(o,op){
var ms=o.animate,m=o.magnify||op.Magnify,mw=o.magwidth||op.MagWidth,z=o.zindex||op.zIndex,t=o.eventtype||op.EventType,t=t=='mouseover'?'mouseover':'click',c=documen t.createElement('IMG');
c.style.position='absolute';
c.style.zIndex=isFinite(z*1)?Math.max(z*1,2):'101';
c.style.left=c.style.top='-3000px';
c.src=o.src||o.img.src;
o.ld=new Image();
o.ld.src=c.src;
o.c=c;
o.grp=(o.group||op.Group)&&o.group!='false';
o.ctr=o.display!='overlay'&&op.Display!='overlay';
o.ms=isFinite(ms*1)?Math.max(ms*1,20):1000;
o.m=isFinite(m*1)?Math.max(m*1,1.1):2;
o.mw=isFinite(mw*1)?mw*1:null;
o.a=[['left'],['top'],['width'],['height'],[false]];
o.t=o.toggle=='true'&&t=='click';
o.ud=false;
t=='click'?o.img.parentNode.removeAttribute('href'):null;
this.addevt(o.img,t,'expand',o,true);
this.addevt(o.c,'mouseup','expand',o,false);
this.addevt(window,'resize','resize',o);
this.addevt(window,'scroll','resize',o);
}
zxcImageExpandIIIOOP.prototype={
expand:function(o,ud,ms){
var grp=zxcImageExpandIII[o.grp];
grp&&grp!=o&&grp.ud?this.expand(grp,false):null;
o.t?ud=!o.ud:null;
if (o.ld.width>40&&(o.ud!=ud||ms)){
o.ud=ud;
var mS=ms||o.ms,p=this.pos(o.img),iw=o.img.width,ih=o.img.height,cw=o.mw?o.mw:iw*o.m,ch=o.mw?o.mw/o.ld.width*o.ld.height:ih*o.m,ww=o.mk.offsetLeft,wh=o.mk.offsetTop,s=window.innerHeight?[window.pageXOffset,window.pageYOffset]:document.documentElement.clientHeight?[document.documentElement.scrollLeft,document.documentElement.scrollTop]:[document.body.scrollLeft,document.body.scrollTop];
document.body.appendChild(o.c);
this.animate(o,o.a[0],ud&&!ms?p[0]:o.a[0][1],ud?o.ctr?s[0]+(ww-cw)/2:Math.max(Math.min(p[0]-(ud?(cw-iw)/2:0),s[0]+ww-cw-5),s[0]+5):p[0],new Date(),mS);
this.animate(o,o.a[1],ud&&!ms?p[1]:o.a[1][1],ud?o.ctr?s[1]+(wh-ch)/2:Math.max(Math.min(p[1]-(ud?(ch-ih)/2:0),s[1]+wh-ch-5),s[1]+5):p[1],new Date(),mS,!ud);
this.animate(o,o.a[2],ud&&!ms?iw:o.a[2][1],(ud?cw:iw),new Date(),mS);
this.animate(o,o.a[3],ud&&!ms?ih:o.a[3][1],(ud?ch:ih),new Date(),mS);
this.animate(o,o.a[4],ud&&!ms?0:o.a[4][1],(ud?100:0),new Date(),mS);
o.grp?zxcImageExpandIII[o.grp]=o:null;
}
},
resize:function(o){
o.ud?this.expand(o,true,500):null;
},
animate:function(o,a,f,t,srt,mS,ud){
clearTimeout(a[2]);
var oop=this,ms=new Date()-srt,n=(t-f)/mS*ms+f;
if (isFinite(n)){
a[1]=Math.max(f<0||t<0?n:0,n);
a[0]?o.c.style[a[0]]=a[1]+'px':oop.opc(o.c,a[1]);
}
if (ms<mS){
a[2]=setTimeout(function(){ oop.animate(o,a,f,t,srt,mS,ud); },10);
}
else {
a[1]=t;
a[0]?o.c.style[a[0]]=(ud?-3000:t)+'px':oop.opc(o.c,t);
}
},
opc:function(o,t){
o.style.filter='alpha(opacity='+t+')';
o.style.opacity=o.style.MozOpacity=o.style.WebkitOpacity=o.style.KhtmlOpacity=t/100-.001;
},
pos:function(obj){
var rtn=[0,0];
while(obj){
rtn[0]+=obj.offsetLeft;
rtn[1]+=obj.offsetTop;
obj=obj.offsetParent;
}
return rtn;
},
addevt:function(o,t,f,p,p1){
var oop=this;
o.addEventListener?o.addEventListener(t,function(e){ return oop[f](p,p1);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return oop[f](p,p1); }):null;
}
}
zxcImageExpandIII({
KeyWord:'expand', // the image class attribute 'keyword' to identify the enlarge image requirement. (string)
// Optional Default Options.
Magnify:2, // the magnification of the enlarged image. (number, default = 2)
Animate:1000, // the animation duration in milli seconds. (number, default = 1000)
EventType:'mouseover', // the event type to execute magnify image, click or mouseover. (string, default = click)
Display:'overlay', // center = center in the window, overlay = overlay the original image. (string, default = center)
zIndex:101, // the z-Index of the magnified image. (number, default = 101)
Group:'tom' // only one magnified image with the same group name can be open at one time. (string, default = no grouping)
});
/*]]>*/
</script>
</body>
</html>
dbooksta
08-21-2013, 03:40 PM
Vic, thanks again: That does what I needed!
One bug I found is that any value set for "Animate" in the initialization call zxcImageExpandIII() does not take effect, but Animate values set in the IMG class definitions do.
I tried adding a zoom-out cursor to the expanded image by inserting
o.c.style.cursor='zoomout.cur'; in the penultimate line of
expand:function. Why doesn't that work?
Also, if you (or anyone) could provide code-level comments I'd love to use this as a learning case, but your code is too concise and clever for me to figure out how it's doing everything!
vwphillips
08-21-2013, 04:32 PM
see change in red
function zxcImageExpandIIIOOP(o,op){
var ms=o.animate||op.Animate,m=o.magnify||op.Magnify,mw=o.magwidth||op.MagWidth,z=o.zindex||op.zIndex,t=o.eventtype||op.EventType,t=t=='mouseover'?'mouseover':'clic k',c=document.createElement('IMG');
c.style.position='absolute';
c.style.zIndex=isFinite(z*1)?Math.max(z*1,2):'101';
c.style.left=c.style.top='-3000px';
c.src=o.src||o.img.src;
o.ld=new Image();
o.ld.src=c.src;
o.c=c;
o.grp=(o.group||op.Group)&&o.group!='false';
o.ctr=o.display!='overlay'&&op.Display!='overlay';
o.ms=isFinite(ms*1)?Math.max(ms*1,20):1000;
o.m=isFinite(m*1)?Math.max(m*1,1.1):2;
o.mw=isFinite(mw*1)?mw*1:null;
o.a=[['left'],['top'],['width'],['height'],[false]];
o.t=o.toggle=='true'&&t=='click';
o.ud=false;
t=='click'?o.img.parentNode.removeAttribute('href'):null;
this.addevt(o.img,t,'expand',o,true);
this.addevt(o.c,'mouseup','expand',o,false);
this.addevt(window,'resize','resize',o);
this.addevt(window,'scroll','resize',o);
}
in the penultimate line of
Code:
expand:function
. Why doesn't that work?
not sure what you mean
could provide code-level comments
I will try a add basic comments tomorrow
dbooksta
08-21-2013, 04:53 PM
Thanks!
Once the image has been expanded I want it to show a zoom-out cursor. My attempt was the following, but it doesn't work. Can you show me how I can correctly set that CSS property?
expand:function(o,ud,ms){
var grp=zxcImageExpandIII[o.grp];
grp&&grp!=o&&grp.ud?this.expand(grp,false):null;
o.t?ud=!o.ud:null;
if (o.ld.width>40&&(o.ud!=ud||ms)){
o.ud=ud;
var ms=ms||o.ms,p=this.pos(o.img),iw=o.img.width,ih=o.img.height,cw=o.mw?o.mw:iw*o.m,ch=o.mw?o.mw/o.ld.width*o.ld.height:ih*o.m,ww=o.mk.offsetLeft,wh=o.mk.offsetTop,s=window.innerHeight?[window.pageXOffset,window.pageYOffset]:document.documentElement.clientHeight?[document.documentElement.scrollLeft,document.documentElement.scrollTop]:[document.body.scrollLeft,document.body.scrollTop];
document.body.appendChild(o.c);
this.animate(o,o.a[0],ud?p[0]:o.a[0][1],ud?o.ctr?s[0]+(ww-cw)/2:Math.max(Math.min(p[0]-(ud?(cw-iw)/2:0),s[0]+ww-cw-5),s[0]+5):p[0],new Date(),ms);
this.animate(o,o.a[1],ud?p[1]:o.a[1][1],ud?o.ctr?s[1]+(wh-ch)/2:Math.max(Math.min(p[1]-(ud?(ch-ih)/2:0),s[1]+wh-ch-5),s[1]+5):p[1],new Date(),ms,!ud);
this.animate(o,o.a[2],ud?iw:o.a[2][1],(ud?cw:iw),new Date(),ms);
this.animate(o,o.a[3],ud?ih:o.a[3][1],(ud?ch:ih),new Date(),ms);
this.animate(o,o.a[4],ud?0:o.a[4][1],(ud?100:0),new Date(),ms);
o.c.style.cursor='zoomout.cur';
o.grp?zxcImageExpandIII[o.grp]=o:null;
}
},
vwphillips
08-21-2013, 05:29 PM
with some comments
<script type="text/javascript">
/*<![CDATA[*/
// Image Expand III (30-August-2013) DRAFT
// by Vic Phillips - http://www.vicsjavascripts.org.uk/
// Functional Code - NO NEED to Change.
function zxcImageExpandIII(op){
var imgs=document.body.getElementsByTagName('IMG'),mk=document.createElement('DIV'),c,o,i,z0=0,z0a;
mk.style.position='absolute'; // the mk DIV is use to calculte the window size
mk.style.bottom=mk.style.right='0px';
mk.style.width=mk.style.height='0px';
document.body.appendChild(mk);
for (;z0<imgs.length;z0++){ // loop through all images
c=imgs[z0].className;
if ((' '+c+' ').match(' '+op.KeyWord+' ')){ // if the keyword is matched in the claas attribute
o={mk:mk,img:imgs[z0]}; // an options object
c=c.split(' '); // split the claas attribute
for (z0a=0;z0a<c.length;z0a++){
i=c[z0a].indexOf(':'); // the position of the':' charecter
if (i>2){
// object property name = characters before ':'
o[c[z0a].slice(o,i).toLowerCase()]=c[z0a].slice(i+1);
// object property value = characters after ':'
}
}
new zxcImageExpandIIIOOP(o,op);
}
}
}
function zxcImageExpandIIIOOP(o,op){
var ms=o.animate||op.Animate,m=o.magnify||op.Magnify,mw=o.magwidth||op.MagWidth,z=o.zindex||op.zIndex,t=o.eventtype||op.EventType,t=t=='mouseover'?'mouseover':'clic k',grp=o.group||op.Group,c=document.createElement('IMG');
c.style.position='absolute'; // the enlared image
c.style.zIndex=isFinite(z*1)?Math.max(z*1,2):'101';
c.style.left=c.style.top='-3000px'; // initial position out of view
c.src=o.src||o.img.src;
o.ld=new Image(); // to check for a valid SCR for the enlared image
o.ld.src=c.src;
o.c=c;
o.grp=grp&&o.group!='false'?grp:null; // check the image is in a 'group'
o.ctr=o.display!='overlay'&&op.Display!='overlay';
o.ms=isFinite(ms*1)?Math.max(ms*1,20):1000; // isFinite checks for a number
o.m=isFinite(m*1)?Math.max(m*1,1.1):2;
o.mw=isFinite(mw*1)?mw*1:null;
o.a=[['left'],['top'],['width'],['height'],[false]]; // an array for each of the animation modes
o.t=o.toggle=='true'&&t=='click';
o.ud=false;
t=='click'?o.img.parentNode.removeAttribute('href'):null; // if click remove the href of the parent node
this.addevt(o.img,t,'expand',o,true); // add an event to open
this.addevt(o.c,'mouseup','expand',o,false); // add an event to close
this.addevt(window,'resize','resize',o); // add an event to reposition an open image
this.addevt(window,'scroll','resize',o); // add an event to reposition an open image
}
zxcImageExpandIIIOOP.prototype={
expand:function(o,ud,ms){
var grp=zxcImageExpandIII[o.grp];
grp&&grp!=o&&grp.ud?this.expand(grp,false):null; // close the last open image of the group
o.t?ud=!o.ud:null; // if toggle
if (o.ld.width>40&&(o.ud!=ud||ms)){ // the image has loaded && o.ud!=ud or resize calls the function
o.ud=ud;
var mS=ms||o.ms,p=this.pos(o.img),iw=o.img.width,ih=o.img.height,cw=o.mw?o.mw:iw*o.m,ch=o.mw?o.mw/o.ld.width*o.ld.height:ih*o.m,ww=o.mk.offsetLeft,wh=o.mk.offsetTop,s=window.innerHeight?[window.pageXOffset,window.pageYOffset]:document.documentElement.clientHeight?[document.documentElement.scrollLeft,document.documentElement.scrollTop]:[document.body.scrollLeft,document.body.scrollTop];
document.body.appendChild(o.c);
// o.a[0] = the left animation array
// o.a[0][1] = the stored left position
// p[0] = the left position of the original image
// if ud position the image at window center or over and centered over the original image
// if not ud return the image to the original image position
this.animate(o,o.a[0],ud&&!ms?p[0]:o.a[0][1],ud?o.ctr?s[0]+(ww-cw)/2:Math.max(Math.min(p[0]-(ud?(cw-iw)/2:0),s[0]+ww-cw-5),s[0]+5):p[0],new Date(),mS);
this.animate(o,o.a[1],ud&&!ms?p[1]:o.a[1][1],ud?o.ctr?s[1]+(wh-ch)/2:Math.max(Math.min(p[1]-(ud?(ch-ih)/2:0),s[1]+wh-ch-5),s[1]+5):p[1],new Date(),mS,!ud);
this.animate(o,o.a[2],ud&&!ms?iw:o.a[2][1],(ud?cw:iw),new Date(),mS);
this.animate(o,o.a[3],ud&&!ms?ih:o.a[3][1],(ud?ch:ih),new Date(),mS);
this.animate(o,o.a[4],ud&&!ms?0:o.a[4][1],(ud?100:0),new Date(),mS);
o.grp?zxcImageExpandIII[o.grp]=o:null;
}
},
resize:function(o){
o.ud?this.expand(o,true,500):null;
},
// a = the animation array, f = the from value, t = the to value, srt = the start date, mS = the animation duration
animate:function(o,a,f,t,srt,mS,ud){
clearTimeout(a[2]); // cancel the previous animation for the array
var oop=this,ms=new Date()-srt,n=(t-f)/mS*ms+f; // the value wrt the elapsed time
if (isFinite(n)){
a[1]=Math.max(f<0||t<0?n:0,n); // the current value
a[0]?o.c.style[a[0]]=a[1]+'px':oop.opc(o.c,a[1]); // a[0] = the property type
}
if (ms<mS){
a[2]=setTimeout(function(){ oop.animate(o,a,f,t,srt,mS,ud); },10);
}
else {
a[1]=t;
a[0]?o.c.style[a[0]]=(ud?-3000:t)+'px':oop.opc(o.c,t); // if ud === true position the image out of view
}
},
opc:function(o,t){
o.style.filter='alpha(opacity='+t+')';
o.style.opacity=o.style.MozOpacity=o.style.WebkitOpacity=o.style.KhtmlOpacity=t/100-.001;
},
pos:function(obj){
var rtn=[0,0];
while(obj){
rtn[0]+=obj.offsetLeft;
rtn[1]+=obj.offsetTop;
obj=obj.offsetParent;
}
return rtn;
},
addevt:function(o,t,f,p,p1){
var oop=this;
o.addEventListener?o.addEventListener(t,function(e){ return oop[f](p,p1);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return oop[f](p,p1); }):null;
}
}
dbooksta
08-21-2013, 07:42 PM
Thanks again!
BTW, I was able to implement the zoom-out cursor on expanded graphics by adding the following:
function zxcImageExpandIIIOOP(o,op){
var ms=o.animate||op.Animate,m=o.magnify||op.Magnify,mw=o.magwidth||op.MagWidth,z=o.zindex||op.zIndex,t=o.eventtype||op.EventType,t=t=='mouseover'?'mouseover':'clic k',grp=o.group||op.Group,c=document.createElement('IMG');
c.style.position='absolute'; // the enlarged image
c.style.cursor = 'url(zoomout.cur), auto'
c.style.cursor = '-webkit-zoom-out';
c.style.cursor = '-moz-zoom-out';
vwphillips
08-22-2013, 12:41 PM
http://www.vicsjavascripts.org.uk/ImageMagnifyIII/ImageMagnifyIII.htm
dbooksta
08-28-2013, 10:14 PM
"Learning JS" question: Why is it that the following does not work:
window.addEventListener?window.addEventListener('resize',function(e){ return this['resize'](o, null);},false):null;
in place of:
this.addevt(window,'resize','resize',o);
... given that the definition of addevt is:
addevt:function(o,t,f,p,p1){
var oop=this;
o.addEventListener?o.addEventListener(t,function(e){ return oop[f](p,p1);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return oop[f](p,p1); }):null;
}
vwphillips
08-29-2013, 09:45 AM
addevt:function(o,t,f,p,p1){
var oop=this;
o.addEventListener?o.addEventListener(t,function(e){ return oop[f](p,p1);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return oop[f](p,p1); }):null;
}
dbooksta
08-29-2013, 03:18 PM
Why is it that if "var oop=this" then "this" is not a synonym for "oop"?
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.