Log in

View Full Version : Looking for a Ken Burns slideshow



ukstormer
08-23-2012, 02:23 PM
There are some fantastic image galleries here but good as they are I cannot find one with a Ken Burns pan & zoom effect, any help much appreciated.

Pete

jscheuer1
08-23-2012, 03:37 PM
That's actually quite a complex effect. There are several choices out there though:

https://www.google.com/search?client=opera&rls=en&q=ken+burns+slideshow&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest

vwphillips
08-24-2012, 02:41 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[*/

.KenBurns {
position:relative;left:20px;top:20px;width:200px;height:150px;border:solid red 1px;
}

/*]]>*/
</style>
</head>

<body>

<!-- <div class="KenBurns">
<img src="http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg" alt="img" width="200"/>
<div style="position:absolute;left:128px;top:82px;width:10px;height:10px;border:solid red 1px;" ></div>
</div>
-->
<input type="button" name="" value="GoTo 0" onmouseup="zxcKBSlideShow.GoTo('ss',0);" />
<input type="button" name="" value="GoTo 1" onmouseup="zxcKBSlideShow.GoTo('ss',1);" />
<input type="button" name="" value="GoTo 2" onmouseup="zxcKBSlideShow.GoTo('ss',2);" />
<div id="ss" class="KenBurns" onmouseover="zxcKBSlideShow.Pause('ss');" onmouseout="zxcKBSlideShow.Auto('ss');" >
<img src="http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg" alt="img" width="200"/>
</div>


<script type="text/javascript">
/*<![CDATA[*/
// KB Slide Show (24-August-2012)
// by Vic Phillips - http://www.vicsjavascripts.org.uk/

var zxcKBSlideShow={

init:function(o){
var id=o.SlideShowID,obj=document.getElementById(id),img=obj.getElementsByTagName('IMG')[0],w=obj.offsetWidth,h=obj.offsetHeight,z=o.DefaultZoom,ms=o.ZoomDuration,ms=typeof(ms)=='number'&&ms>0?ms:1000,hold=o.AutoHold,srt=o.AutoStart,z=typeof(z)=='number'&&z>=1?z:2,zary=o.ZoomArray,zary=typeof(zary)=='object'&&zary.constructor==Array?zary:[],clone,zz,ary=[],z0=0;
obj.style.overflow='hidden';
img.style.position='absolute';
img.style.zIndex='0';
img.style.left='0px';
img.style.top='0px';
img.style.width=w+'px';
img.style.height=h+'px';
clone=img.cloneNode(false);
clone.style.zIndex='2';
obj.appendChild(clone);
for (;z0<zary.length;z0++){
zz=zary[z0]&&typeof(zary[z0][1])=='number'&&zary[z0][1]>=1?zary[z0][1]:z;
ary[z0]=[new Image(),['left',0,0,typeof(zary[z0][2])=='number'?Math.min(Math.max(-zary[z0][2]*zz+w/2,-h*zz+h),0):-(w*zz-w)/2,'l'+z0],['top',0,0,typeof(zary[z0][3])=='number'?Math.min(Math.max(-zary[z0][3]*zz+h/2,-h*zz+h),0):-(h*zz-h)/2,'t'+z0],['width',w,w,w*zz,'w'+z0],['height',h,h,h*zz,'h'+z0],[null,0,0,100,'o'+z0]];
ary[z0][0].src=zary[z0][0];
}
this['zxc'+id]={
id:id,
ary:ary,
img:img,
lgth:ary.length-1,
clone:clone,
effects:5,
ms:ms,
auto:false,
hold:typeof(hold)=='number'&&hold>0?hold:ms*2,
ud:1,
cnt:0
}
if (typeof(srt)=='number'){
this.Auto(id,srt);
}
},

GoTo:function(id,nu){
var o=this['zxc'+id];
if (o&&o.ary[nu]&&nu!=o.cnt){
this.pan(id,nu);
}
},

Auto:function(id,ms){
var o=this['zxc'+id],oop=this;
if (o){
o.dly=setTimeout(function(){ oop.pan(id,true); },ms||200);
}
},

Pause:function(id){
var o=this['zxc'+id];
if (o){
clearTimeout(o.dly);
o.auto=false;
}
},

pan:function(id,nu){
var o=this['zxc'+id];
if (o){
this.Pause(id);
o.auto=nu===true;
if (o.auto){
nu=o.cnt+o.ud;
nu=nu<0?o.lgth:nu>o.lgth?0:nu;
}
if (o.ary[nu]){
o.clone.src=o.ary[nu][0].src;
for (var ary=o.ary[nu],z0=1;z0<=o.effects;z0++){
clearTimeout(o[ary[z0][5]]);
this.animate(o,ary[z0],ary[z0][1],ary[z0][3],new Date(),o.ms,z0);
}
o.cnt=nu;
}
}
},

animate:function(o,ary,f,t,srt,mS,cnt){
var oop=this,ms=new Date().getTime()-srt,now=(t-f)/mS*ms+f;
if (isFinite(now)){
ary[1]=now;
if (ary[0]){
o.clone.style[ary[0]]=now+'px';
}
else {
this.opac(o.clone,now);
}
}
if (ms<mS){
o[ary[4]]=setTimeout(function(){ oop.animate(o,ary,f,t,srt,mS,cnt); },10);
}
else {
ary[1]=ary[2];
if (ary[1]){
o.clone.style[ary[0]]=t+'px';
}
if (cnt==o.effects){
o.img.src=o.clone.src;
if (o.auto){
oop.Auto(o.id,o.hold);
}
}
}
},

opac:function(obj,now){
obj.style.filter='alpha(opacity='+now+')';
obj.style.opacity=obj.style.MozOpacity=obj.style.WebkitOpacity=obj.style.KhtmlOpacity=now/100-.001;
}

}

zxcKBSlideShow.init({
SlideShowID:'ss', // the unique ID name of the parent DIV. (string)
ZoomArray:[ // an array defining the slideshow images SRCs, zoom and zoom positiom. (array)
// field 0 = the image src. (string)
// field 1 =(optional) the image zoom. (number, default = DefaultZoom)
// field 2 =(optional) the image x coordinate to zoom to. (number, default = center)
// field 3 =(optional) the image y coordinate to zoom to. (number, default = center)
['http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg',3,138,87],
['http://www.vicsjavascripts.org.uk/StdImages/Listening.jpg'],
['http://www.vicsjavascripts.org.uk/StdImages/Egypt5.jpg']
],
DefaultZoom:2, //(optional) the default zoom. (number, default = 2)
ZoomDuration:1000, //(optional) the zoom duration in milli seconds. (number, default = 1000)
AutoHold:2000, //(optional) the auto rotate 'hold' duration in milli seconds. (number, default = ms*2)
AutoStart:2000 //(optional) the auto rotate 'start' delay in milli seconds. (number, default = ms*2)
});
/*]]>*/
</script>
</body>

</html>

jscheuer1
08-24-2012, 03:10 PM
Hi Vic,

Unless I've misread the code in your post (I tried it out as well), that's not the full Ken Burns effect. The full effect is that on a random basis each new image is either pre zoomed then panned (sometimes non-linearly) from a location to a location these locations varying at least among two or three possibilities, or is zoomed in and/or panned (again, sometimes non-linearly), or simply zoomed in or out. Each time this happens though it is also fading in over the previous image which remains in its last state of having zoomed and/or panned until completely covered, then presumably returning to its native state awaiting its next transformation.

I have some what I think is public domain/MIT style license code on this (the Ken Burns effect) somewhere that I put into a proprietary slider, the WOW Slider, which I reworked as the OMG (working title) Slider. WOW also has it's own proprietary Ken Burns affect. The WOW Slider does a good job of it though and isn't very expensive if someone wants to go that route. I think some of the other links turned up from a Google search of this (as indicated in my previous post) might do an equally good job of the effect and perhaps be free.

Here's my demo so you can see the effect in its full glory (images are probably copyright as well):

http://home.comcast.net/~jscheuer1/side/files/sliders/omg_slider_3_h.htm

But as I say, it's proprietary. Last I checked you either need a license from the WOW people, or free for non-commercial use. That may have changed. A lot of their code is from the public domain or similar (MIT style license) though, so it's a tough call on precisely what you need a license for. I contacted them, they never said they had the rights to the basic slider, they never said they didn't, it's very close to the MIT style licensed NIVO slider, but different enough to raise eyebrows, I know they don't have the rights to the coin-slider that's used as a helper. The Ken Burns 'plugin', as I mentioned, I'm not so sure about. They (The WOW Slider people) do have a web site and offer all this with a cool GUI executable installer/creator. I'm sure all of that (the web site and the assembly/c or whatever code for the installer/creator) is strictly proprietary and under copyright.

djr33
08-24-2012, 09:44 PM
That's correct for what the "Ken Burns" effect is. It's popular in documentaries (as in what Ken Burns originally made).

The only point I'd add is that it isn't necessarily random. Often it's very specifically intended to be one kind of movement to highlight something in the image or time to the music, etc.
So a fully powerful script should allow customization of the type of zoom and pan, as well as (why not?) the option for a random zoom/pan if the designer doesn't want to pick it for each image.

vwphillips
08-26-2012, 04:03 PM
latest version


<!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[*/

.KenBurns {
position:relative;left:200px;top:200px;width:200px;height:150px;border:solid red 1px;
}

.div {
position:absolute;z-Index:4;width:100px;height:75px;border:solid red 1px;
}

/*]]>*/
</style>
</head>

<body>

<!-- <div class="KenBurns">
<img src="http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg" alt="img" width="200"/>
<div style="position:absolute;left:128px;top:82px;width:10px;height:10px;border:solid red 1px;" ></div>
</div>
-->
<input type="button" name="" value="GoTo 0" onmouseup="zxcKBSlideShow.GoTo('ss',0);" />
<input type="button" name="" value="GoTo 1" onmouseup="zxcKBSlideShow.GoTo('ss',1);" />
<input type="button" name="" value="GoTo 2" onmouseup="zxcKBSlideShow.GoTo('ss',2);" />
<div id="ss" class="KenBurns" onmouseover="zxcKBSlideShow.Pause('ss');" onmouseout="zxcKBSlideShow.Auto('ss');" >
<img src="http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg" alt="img" width="200"/>
</div>

<script> vic=0; </script>
<form name=Show id=Show style="position:absolute;visibility:visible;top:700px;left:0px;" >
<input size=100 name=Show0 >
<input size=100 name=Show1 >
<input size=10 name=Show2 >
<input size=10 name=Show3 >
<input size=10 name=Show4 >
<input size=10 name=Show5 >
<input size=10 name=Show6 >
<input size=10 name=Show7 >
<input size=10 name=Show8 >
<input size=10 name=Show9 ><br>
<textarea name=TA rows=1 cols=100 ></textarea>
</form>

<script type="text/javascript">
/*<![CDATA[*/
// KB Slide Show (24-August-2012)
// by Vic Phillips - http://www.vicsjavascripts.org.uk/

var zxcKBSlideShow={

init:function(o){
var id=o.SlideShowID,obj=document.getElementById(id),img=obj.getElementsByTagName('IMG')[0],w=obj.offsetWidth,h=obj.offsetHeight,ms=o.ZoomDuration,ms=typeof(ms)=='number'&&ms>0?ms:1000,hold=o.AutoHold,srt=o.AutoStart,z=typeof(z)=='number'&&z>=1?z:2,ary=o.ImageArray,ary=typeof(ary)=='object'&&ary.constructor==Array?ary:[],clone,lk=document.createElement('A'),nary=[],a,m,c,cnt=0,z0=0,z0a;
obj.style.overflow='hidden';
obj.appendChild(lk);
img.style.position='absolute';
img.style.zIndex='0';
img.style.left='0px';
img.style.top='0px';
img.style.width=w+'px';
img.style.height=h+'px';
img.style.borderWidth='0px';
clone=img.cloneNode(false);
clone.style.zIndex='2';
lk.appendChild(img);
lk.appendChild(clone);
for (;z0<ary.length;z0++){
if (typeof(ary[z0][0])=='string'){
nary[cnt]=[new Image(),[],[]];
nary[cnt][0].src=ary[z0][0];
a=typeof(ary[z0][1])=='object'&&ary[z0][1].constructor==Array?ary[z0][1]:[];
m=typeof(a[0])=='number'&&a[0]>=2?a[0]:2;
nary[cnt][1]=[['width',w,w,w*m,'w'+z0],['height',h,h,h*m,'h'+z0]];
c=ary[z0][2];
c=typeof(a[1])=='number'?a[1]>=2?Math.floor(a[1]):0:2;
if (c>0){
for (z0a=0;z0a<c*c;z0a++){
nary[cnt][2][z0a]=[['left',0,0,-w/m*(z0a%m)*m,'l'+z0a],['top',0,0,-h/m*Math.floor(z0a/m)*m,'t'+z0a]];
}
}
else {
nary[cnt][2][0]=[['left',0,0,(w-w*m)/2,'l'],['top',0,0,(h-h*m)/2,'t']];
}
nary[cnt][3]=a[2]!==false;
nary[cnt][4]=Math.min(nary[cnt][2].length,typeof(a[3])=='number'&&a[3]>0?a[3]:1000)-1;
nary[cnt][5]=ary[z0][2];
nary[cnt][6]=ary[z0][3];
cnt++;
}
}
o=this['zxc'+id]={
id:id,
ary:nary,
img:img,
iw:w,
ih:h,
lgth:nary.length-1,
clone:clone,
lk:lk,
fade:[null,0,o.Opacity!==false?0:100,100,'o'],
ms:ms,
auto:false,
hold:typeof(hold)=='number'&&hold>0?hold:ms*2,
ud:1,
cnt:-1
}
this.links(o,0);
if (typeof(srt)=='number'){
this.Auto(id,srt);
}
},

GoTo:function(id,nu){
var o=this['zxc'+id];
if (o&&o.ary[nu]&&nu!=o.cnt){
this.pan(id,nu);
}
},

Auto:function(id,ms){
var o=this['zxc'+id],oop=this,nu;
if (o){
o.dly=setTimeout(function(){ oop.pan(id,true); },ms||200);
}
},

Pause:function(id){
var o=this['zxc'+id];
if (o){
clearTimeout(o.dly);
clearTimeout(o.sdly);
o.auto=false;
}
},

pan:function(id,nu){
var o=this['zxc'+id],oop=this;
if (o){
this.Pause(id);
o.auto=nu===true;
if (o.auto){
nu=o.cnt+1;
nu=nu<0?o.lgth:nu>o.lgth?0:nu;
}
if (o.ary[nu][3]){
o.ary[nu][2]=this.shuffle(o.ary[nu][2]);
}
this.opac(o.clone,o.fade);
o.clone.src=o.ary[nu][0].src;
o.clone.style.left='0px';
o.clone.style.top='0px';
o.clone.style.width=o.iw+'px';
o.clone.style.height=o.ih+'px';
o.cnt=nu;
this.links(o,nu);
this.animate(o,o.fade,o.fade[2],100,new Date(),o.ms);
}
},

srt:function(o,nu){
o.scnt=0;
for (var a,z0=0;z0<2;z0++){
a=o.ary[o.cnt][1];
clearTimeout(o[a[z0][4]]);
this.animate(o,a[z0],a[z0][1],a[z0][3],new Date(),o.ms,z0);
if (z0<2){
a=o.ary[o.cnt][2][0];
clearTimeout(o[a[z0][4]]);
this.animate(o,a[z0],a[z0][1],a[z0][3],new Date(),o.ms,z0);
}
}
},


animate:function(o,ary,f,t,srt,mS){
var oop=this,ms=new Date().getTime()-srt,now=(t-f)/mS*ms+f;
if (isFinite(now)){
ary[1]=now;
if (ary[0]){
o.clone.style[ary[0]]=now+'px';
}
else {
this.opac(o.clone,now);
}
}
if (ms<mS){
o[ary[4]]=setTimeout(function(){ oop.animate(o,ary,f,t,srt,mS); },10);
}
else {
ary[1]=ary[2];
if (ary[0]){
o.clone.style[ary[0]]=t+'px';
}
else {
this.opac(o.clone,100);
o.img.src=o.clone.src;
o.dly=setTimeout(function(){ oop.srt(o); },o.ms);
}
if (ary[0]=='left'){
if (o.scnt<o.ary[o.cnt][4]){
o.sdly=setTimeout(function(){ oop.sequence(o); },o.ms);
}
else {
if (o.auto){
oop.Auto(o.id,o.hold);
}
}
}
}
},

links:function(o,nu){
o.lk.removeAttribute('href');
if (o.ary[nu][5]){
o.lk.href=o.ary[nu][5];
}
o.lk.removeAttribute('title');
if (o.ary[nu][6]){
o.clone.title=o.ary[nu][6];
}
},

shuffle:function(ary){
for (var r,t,z0=0;z0<ary.length;z0++){
r=Math.floor(Math.random()*ary.length);
t=ary[z0];
ary[z0]=ary[r];
ary[r]=t;
}
return ary;
},

sequence:function(o){
o.scnt++;
for (var a,z0=0;z0<2;z0++){
a=o.ary[o.cnt][2][o.scnt][z0];
clearTimeout(o[a[4]]);
this.animate(o,a,o.ary[o.cnt][2][o.scnt-1][z0][3],a[3],new Date(),o.ms);
}
},

opac:function(obj,now){
obj.style.filter='alpha(opacity='+now+')';
obj.style.opacity=obj.style.MozOpacity=obj.style.WebkitOpacity=obj.style.KhtmlOpacity=now/100-.001;
}

}

zxcKBSlideShow.init({
SlideShowID:'ss', // the unique ID name of the parent DIV. (string)
ImageArray:[ // an array defining the slideshow images SRCs. (array)
// field 0 = the image src. (string)
// field 1 = an array defining the zoom in and pan data. (array)
// field 0 =(optional) the image zoom. (number, default = option 2)
// field 1 =(optional) the number of pan rows and colums. (number, default = 2, if <2 pan center once)
// field 2 =(optional) false = pan will sequence by colum and row. (boolean, default = true = randomise the rows and colums to pan)
// field 3 =(optional) limit the number of pan rows and colums to pan. (number, default = rows*colums)
// field 2 =(optional) the link href of the current image. (string, default = no href)
// field 3 =(optional) the title of the current image. (string, default = no title)
['http://www.vicsjavascripts.org.uk/StdImages/WinterPalace.jpg',[2,2,false,2],'http://www.vicsjavascripts.org.uk/','Winter Palace'],
['http://www.vicsjavascripts.org.uk/StdImages/Egypt5.jpg',[2,0]],
['http://www.vicsjavascripts.org.uk/StdImages/Listening.jpg',[2,2]],
['http://www.vicsjavascripts.org.uk/StdImages/Egypt7.jpg']
],
ZoomDuration:1000, //(optional) the zoom duration in milli seconds. (number, default = 1000)
Opacity:true, //(optional) false = the image swap will not fade in. (boolean, default = true = the image swap will fade in)
AutoHold:2000, //(optional) the auto rotate 'hold' duration in milli seconds. (number, default = ms*2)
AutoStart:2000 //(optional) the auto rotate 'start' delay in milli seconds. (number, default = ms*2)
});
/*]]>*/
</script>
</body>

</html>

jscheuer1
08-26-2012, 04:20 PM
A step in the right direction.

Still doesn't have that non-linear pan and zoom happening at times concurrently. Things seem really drawn out for some of the effects. When more than one pan is used, you can tell where one ends and the other begins.

As in the demo I put up it's supposed do whatever it's going to do in one smooth uninterrupted motion lasting approximately the same amount of time for each image.

ukstormer
08-29-2012, 11:22 AM
Many thanks for all your input, I really like the OMG Slider and had seen the WOW stuff previously, I have also recently seen some other stuff but again I think it was based around the WOW software.

vwphillips
09-01-2012, 11:24 AM
http://www.vicsjavascripts.org.uk/KenBurnsSlideShow/KenBurnsSlideShow.htm

Brownmarsh12
09-19-2012, 09:43 AM
as I can see too your website works fine "for real". What do you think, to send your question to Aeron Glemann, aeron.glemann at gmail.com, who elaborated this extension. Maybe there is a Windows 7 "intolerance" and the program would have to be adjusted.

jscheuer1
09-19-2012, 02:05 PM
as I can see too your website works fine "for real". What do you think, to send your question to Aeron Glemann, aeron.glemann at gmail.com, who elaborated this extension. Maybe there is a Windows 7 "intolerance" and the program would have to be adjusted.

After doing a search I see Glemann's "Ken Burns" work (at least some of it) is for MooTools and uses otherwise 'normal' javascript and HTML as filtered via the MooTools library. What I did is jQuery based and involves the use of the canvas tag. Vic's script is all javascript and HTML.

I couldn't easily find a live demo of Glemann's work though, are you saying it doesn't work on Win 7? Is there a live demo you're aware of?

jscheuer1
09-10-2013, 09:02 PM
I know this is an old thread, but I've been playing around with this again recently and am almost there. In jQuery (and in general) it's actually much simpler than we all thought, or at least than I thought. Instead of mutiple pans and zooms occurring at once, it's just a "setup", which prepares the image for the particular effect by changing its size (width and height - proportionally) and moving to a position (absolute, left and/or top, bottom right) within the frame (parent div, position relative, overflow hidden). The effect itself is then a single pan (animated position change(s) with or without a concurrent change in size (width and height again). All of which can be expressed rather simply in jQuery (this was the starting point):


// jQuery Ken Burns Effect Script (c)2013 John Davenport Scheuer
// as first seen in http://www.dynamicdrive.com/forums/
// username: jscheuer1 - This Notice Must Remain for Legal Use

(function($){
burns = [
{//0
setup: {width: '136%', height: 'auto', position: 'absolute', top: 0, left: 0},
ani: {width: '100%'}
},
{//1
setup: {width: '136%', height: 'auto', position: 'absolute', top: '-36%', left: 0},
ani: {width: '100%', top: 0}
},
{//2
setup: {width: '136%', height: 'auto', position: 'absolute', top: 0, left: '-36%'},
ani: {width: '100%', left: 0}
},
{//3
setup: {width: '136%', height: 'auto', position: 'absolute', top: '-36%', left: '-15%'},
ani: {width: '100%', top: 0, left: 0}
},
{//4
setup: {width: '100%', height: '100%', position: 'absolute', top: 0, left: 0},
ani: {width: '136%', height: '136%', top: '-15%'}
},
{//5
setup: {width: '115%', height: '115%', position: 'absolute', bottom: 0, left: '-15%'},
ani: {width: '136%', height: '136%', bottom: '-15%', left: 0}
},
{//6
setup: {width: '136%', height: 'auto', position: 'absolute', top: '-15%', left: 0},
ani: {left: '-36%'}
}
];
$.fn.kenburns = function(burn, duration){
this.css(burns[burn].setup).animate(burns[burn].ani, {queue: false, easing: 'linear', duration: duration});
};
})(jQuery);



Some of the "burns" are pretty similar, as I was fine tuning with some of them, others can be added. I worked this out for use with The Ultimate Fade-in Slideshow, and it's pretty close to what the WOW slider does, with much less code and no canvas tag. Things aren't perfected yet (they almost never are with me - but I see some things this still really needs), but here's a demo:

http://home.comcast.net/~jscheuer1/side/demos/ufade/kburns1.htm

One thing though, even in the WOW slider version, there are some slight distortions of the image as it's panning/zooming. This can be particularly seen with fine lines. The images used in the WOW demo I linked to earlier in this thread don't have very many of those though, so it's hardly noticeable. You can see it around the doorways on the airplanes though, as those are fine lines. This might be browser and/or monitor dependent.