Cover flow in Javascript

My wife is a scrapbook consultant. She was looking for a way to showcase her artwork on her web page. Instead of your typical list of thumbnails, I thought it would be more interesting to put her scrapbook pages in iTunes cover flow. So after a weekend of messing with javascript, this is the result:

It doesn't have the oblique angles, but I think I know how to achieve that effect. There is also a Safari compatibility issue, and a performance improvement I can make. More to come.

Finn Rudolph has added many enhancements to the original script. I highly recommend using his Image Flow.

90 Responses to “Cover flow in Javascript”

  1. Douglas Boyce Says:

    Totally Cool ! Thanks for Sharing. It gives me ideas for my photography.

  2. Aleks Says:

    Its a great cover flow. Congratulations.
    Are you thinking of explaining how to achive that result?

    Have a nice day.

  3. Michael L Perry Says:

    All of the code is available directly in the page. (Yes, I know it should be broken out, but this was an experiment.) You can take this code and use it as your own.

    There are three ideas in the code.

    First, the use of setTimeout to perform animation. setTimeout schedules a function call to occur at some time in the future. If the animation is not yet finished, this function should again call setTimeout.

    Second, the math behind the manipulation of the images. The path is a 100-unit hyperbola, where the observer is standing 100 diagonal units away from the origin. Divide the image height by the perpendicular distance from the observer to simulate vanishing. Change the zIndex to simulate occlusion.

    Third, the use of hidden div tags to hold data. Set the inner text of a visible div tag to the inner text of a hidden one in order to place the data on the screen.


  4. Francois Says:

    Great job !
    I really would like to understand how it works. I've passed 2 days on it but I can't figure out.
    Would it be possible for you (or someone that did understand how it works) to email me some detailed explanations ? Thanks in advance, and again, congrats for the work !

  5. Quan Says:

    Thanks for your work! It looks fantastic!

  6. Stanley Says:

    I've just had a quick look at it and was able to substitute on of my pics for cocoa1.jpg but couldn't get the reflection. Which bit of the code governs the reflections? 'Scuse my ignorance and thanks for any help.

    I'd like to use it as a portfolio.

  7. Michael L Perry Says:

    The reflections are part of the raw images. I generated the images using the code at this location:

    I was unable to integrate the reflection code into the coverflow directly. If you are able to do so, please post a link.

  8. Blake Says:

    I too am trying to implement a Coverflow effect - for browsing podcast album art.

    One of the pages I turned up looking for javascript offers the code for doing reflections:

    Thanks for posting your work.

  9. Yim Lee Says:

    Hi Michael,

    Thanks so much for sharing your work! I was able to use you code on the latest launch of Your code was very easy to integrate and it works beautifully!

  10. i-wannebe » Achieving the Cover Flow effect Says:

    [...] scrapbook work, so he wrote some JavaScript code to mimic the Cover Flow effect and shared his results in one of his blog posts. Here is the URL to Perry’s [...]

  11. Craigh Says:

    I'm trying to use this code to present my artwork on my website but when I substitute your images with the web address for mine the size ratio is wrong and I can't seem to find where I can change that. Please help.

  12. Michael L Perry Says:


    The magic is in this line: = 110.25 / z * biggest;

    The number 110.25 is the percentage of height to width of my images. Just divide height by width and multiply by 100 to get the exact ratio to plug in.


  13. Finn Says:

    Hi Michael,

    thanks for the nice Javascript Code. I made some "improvements" on it. Now it scales the Images in other formats than square and aligns at the bottom. At this time I'm working on (hopefully) massive performance improvements by implementing the scriptaculous framework ( See the following link for my version. You can drop a comment in the shoutbox.

    Have a nice day.

  14. Ray Says:

    Hi Mike,

    Is there a way to add code so that when a page is selected as desired and user cliks on it it follows that link?
    I could do it modifing the code at the bottom, but not through direct click (or double click) in the image itself.

  15. Finn Says:

    @Ray: Try adding the following code inside the tag:


    That should redirect the user to this page by simply doubleclicking on the image... for single click action use onclick=""

    Hope it works ;D

  16. nev Says:

    Nice looking effect! - sure this will become popular.

    Can someone give tips* as to best way of inserting this display inside a fixed-width div? I tried modifying it but I keep getting small images! Unh!

    (*read: 'instructions' !!)

  17. Finn Says:

    Jepp, I had some ideas on this one. Check out Version 0.2 of my ImageFlow build on the code of Michael Perry. It now scales dynamically in relation to the div container called "images". I also added a changelog to the previous demo:

    I would like to see what you build with it!

  18. nev Says:

    Finn - I think that's another great effect, and I see you've placed the images successfully inside a containing div.

    However I do like the way the images on change size as they skip to the front, as if they are "coming forward" in a "presentation" style.

    That's the effect I'd like to reproduce, but inside a fixed-width div.

    Basically I'm trying to put this effect in a page which has a wide but fixed-width central area (a centred layout).

    I feel sure it must be possible!

  19. Finn Says:

    @nev: You don't get it. If something can be described in a dynamic div it always can be described in a STATIC div too.

    Simply check my sourcecode and replace all dynamic style definitions like width:70% with a static width:750px. And you have the images in a static div. Now delete the div containing the changelog completely and the images and the effect should be in a aligned STATIC div container...

    so long...

  20. nev Says:

    Hey sorry - I was looking in Safari/Mac and forgot about the bug! The effect is lost in Safari and I thought that what I saw was what you intended! That's what got me confused. I see however it works very nicely in every other browser/os.

    The version however DOES work in Safari.

  21. Finn Says:

    @nev... hmmm... I develop on a Machine running Windows XP and tested the Stuff on Opera 9.x IE6 to IE7 and Firefox 1.5 to Firefox 2. But I saw the script on Safari running on a mac today... seems to screw up the image-height. Any Idea on a workaround? The version does not read out the image height, but scales everything to a square format in relation to the total window-width... That's why it works on Safari.

    So long...

  22. Finn Says:

    @nev: I tested ImageFlow 0.2 on Safari 3.0.3/Windows XP and found no problems:

    I don't have a Mac, but it seems to run on Safari for Windows ;D

  23. nev Says:

    Seems like it's only Safari/Mac that throws it. As you say, the images stretch to the full height of the div.

  24. jenny Says:

    cool. is there a way to make this start on say the 3rd or 4th etc image?

  25. Finn Rudolph Says:

    @jenny: Sure, just add the following code to the body tag:

    onload="refresh(); glideTo( -450, 'i4')"

    That calls the refresh and the glideTo function. In this case ImageFlow glides to the 4th image. This code refers to my version of Michael Perrys scraproom:

  26. jenny Says:

    that works well. thanks ;)

  27. Bob Strupp Says:

    I love the script. How do i get it to fit inside of a table? right now it spans across the whole browser. Please advise.

  28. Michael Says:

    I'm trying to implement this function on my site, but was wondering how I go about changing the size of the function from the span of the entire page, to something in a more controlled environment- like something in pixels?

  29. rico Says:

    Has anyone tried viewing it on an iphone/ipod touch?

  30. Michael L Perry Says:

    Bob and Michael,

    Finn embedded the effect within a div tag. He achieved this by changing the windowWidth function to return only the width of the tag:

    /* Get width of the images div container in px */
    function windowWidth()
    	var width = document.getElementById("images").offsetWidth;
    	return width;


    I just got my iPod Touch, and I love it. I've installed a Wordpress plugin to render the blog correctly on the screen. And, yes, the Javascript coverflow effect works on the small screen, albeit a little slowly.

  31. rico Says:

    Michael L,

    Thanks for this neat script. I haven't tried getting it to do real work yet, but have the start of an ipod touch/iphone launchpad for my iphone apps...

    What I need for the script to do is... when the user clicks the image displayed in the center, to open a new page. I could bury the link in the caption tag, but thats not as sexy.

    I don't believe that iphone safari supports ondblclick.... any hint?

    here's the mockup...

    if you want to play some of my games...

  32. Michael L Perry Says:

    Cool mockup! Yours is a bit smoother on the Touch, since it uses smaller images.

    One thing that would work is to compare the captionId to the newCaptionId in glideTo. If they are the same, then the user has tapped the front-most image. This works better than double-clicking anyway, since the second click can be delayed.

    You can probably make the target an attribute of the div tag so that you can retrieve it from the captionId. Then you can just navigate to it.

    Good luck! Can't wait to see the finished product.

  33. rico Says:


    Thanks for the tip... I added your suggestion of comparing the captionID... and it works

  34. Kevin Says:

    This is so cool! I have added dbl click goto url to images, and adjusted onload to go to whatever slide I want it to start on. I am working on the reflection part on the images and a now I am going to work on image and links from a database on Cold Fusion. Has anyone worked on a slider control?
    Thanks for sharing !

  35. Finn Says:

    Dynamically generated reflections anyone? Those are NOT Javascript, but server sided PHP generated reflections. I hacked Richard Daveys Easy Reflections v2 a bit and this is what it looks like:

    I also improved some of the code . o O ( I think... ) ;D

  36. Finn Says:

    *phew* I implemented a improved JavaScript Implementation of a Duff's Device Loop. That was kind of tricky... At this moment i couldn't think of anything else to improve. Now the main limiting factor should be the rendering engine of the browser. The speed scales in relation to the image quality of resized images: IE is fast, but the resized images look messy, Opera and Safari do a way better job, but are therefore somewhat slower... This version is testing only at the moment, you can check it out here:

    @ Michael L Perry: Could you take a short look on what i did to your code. Do you have any ideas how to improve a thing, or do you agree with me, that the browser engine is the limiting factor? Code:

  37. Michael L Perry Says:


    I think that image resizing will always be the bottleneck. Have you measured the performance improvement that you achieved? Seems like it would get lost in all the high-cost image processing. But, yes, there is one minor improvement you can make to the Duff Device Loop. You can use a switch/case with fall-through to avoid the initial remainder loop.

    I love the server-side reflections in PHP. You'd better believe I'm incorporating that. It was a pain manually applying the reflection to each image in Paint Shop Pro.

  38. Finn Says:

    Mouse wheel support and loading bar anyone? Okay this should be the last one... now I like it ;D

    @ Michael L Perry: Thanks, I measured the stuff I did and found it slower than the previous desing. Perhaps because there are function calls within the loop? Anyway, I tried another way and cached all I could. I also made only those variables global, that must be global. See the final code here:

  39. Finn Says:

    I did some JavaScript performance benchmarking and Opera is by far the slowest browser! I started a thread including my benchmark results:

    In general Michael is right: The main performance drops are induced by the browsers high-cost image processing! This leads to only one feasible solution: Rewrite the code, that it can handle >100 images, but only displays a maximum of 10 at a time. Perhaps by hiding them width CSS when they are not focussed?!

  40. MediaEvent Services Blog » Blog Archive » AJAX Image Gallery powered by Slideflow (like Cover Flow) Says:

    [...] Based on code by Michael L Perry [...]

  41. Christian Becker Says:

    Hey, awesome code! We used it as a starting point for our CC-licensed project and added Photoshop-generated perspectives, dragging and mouse wheel navigation!

  42. Finn Says:

    As I posted above: I rewrote the code to avoid performance drops by hiding all images (display:none) that are not in the viewing focus. Now it can handle large amounts of images (>100)... To keep the usability I also added a scrollbar. Which is a handy thing when there are hundreds of images to scroll ;D

    BTW: If anyone uses Opera - try switching the InterpolateImages feature OFF (opera:config#Multimedia|InterpolateImages) the quality of resized images drops, but there is a massive speed increase!

  43. Bob Says:

    Please help! I have been trying to get this cover flow to fit into my table for the longest time. I am not very good at this stuff. I tried everything that was stated above but I can not figure it out. Can someone please look at my link and show me how to get this cover flow into the table?


  44. Michael L Perry Says:


    At this point, I'd recommend starting with Finn's ImageFlow code. In addition to the features he added, he has refactored the code in such a way that it is easier to place within a smaller space. He defines that container with another div tag, not a table cell. Maybe that is significant.

    I spent a few minutes trying to reproduce the changes he made. He has changed the windowWidth function to get the width of the div tag itself, rather than the entire window. And he has changed the moveTo function to offset the image positions relative to the container. But there is something else that is eluding me. Again, perhaps it has to do with the table cell vs. the div tag.

    So download ImageFlow. Finn has taken this farther than I could have, and he seems prepared to support it. When I redesign MyScrapRoom, I'm going to adopt his code.

  45. Steven Says:

    Excellent cover flow, one of the best I've seen ^^
    I guess it would be easy to make a PHP script to give the images a perspective like cover flow and then request it with AJAX...
    But I'm not sure, haven't really worked with image manipulation in PHP.

  46. Bob Says:

    Hi, I was wondering about what the author says:

    "There is also a Safari compatibility issue, and a performance improvement I can make."

    Does it means, it'll not work or iPhone? bec as far as i know, iPhone uses safari web browser for internet applications...

    I test on safari browser with Max OS X, and it didn't work well... I am asking because i don't have an iPhone... any help or info please?


  47. Bryne Says:

    Can this script work or interact with iPhone's photo album feature?
    e.g. I have a web application, and i'd love to open it or browse it with the iPhone's Photo album feature (not by Safari browser). help?

  48. Michael L Perry Says:


    The Safari compatibility issue I originally talked about has been fixed. It was that Safari does not automatically scale images in both dimensions when you change just one dimension. I fixed this by changing both the width and the height proportionally. Finn improved on this by making that proportion variable, so that both portrait and landscape images are supported.

    So it works on the iPhone and iPod touch. It's just slow because those devices can't scale images very quickly. And you can't drag the slider; you have to tap the images themselves.


    Sorry, but this script does not work with the iPhone photo album. Sliding your finger across a web page always scrolls it. You have no opportunity to capture that event and do something else with it. So you can't flick the images the same way you can in photos.

    You have to sync photos to the device before the photo app will work. It can't pull photos directly from the web. Perhaps there will be a third-party app that can do that, but none that I know of right now.

  49. Finn Says:


    there still is a Safari Problem: ImageFlow (and probably this Michaels version too) does not work with Safari versions below version 3.0! And I have really no Idea why. I enabled the javascript debug console ( ) but Safari 2.x did not spit out any error messages. It has some kind of problem to read out the correct .width and .height attributes of the image object. But no one I asked had any idea on a workaround. Do you?

    @ Michael: Thanks for your positive feedback on ImageFlow ;D BTW: There is a brand new version of it!

  50. Jeremy Burgess Says:

    Cool! That is a weekend to be proud of. I am really impressed with the result...

  51. RandyTamayo Says:

    Here is the latest version from Finn I used for testing on my website (with very minor modifications of course.)

    Tested on Safari 3 (windows and mac), IE, Firefox and Camino.

  52. jenny Says:

    Hey Randy that's great! How do I use the code?

  53. Finn Says:


    ImageFlow is now fully compatible with ALL Safari Versions!

    And I finished the english translation of the documentation:

    @ Randy: Wow, this is what I developed ImageFlow for ;D I Suggest, that you update to the new version, to make it fully browser compatible...

  54. RandyTamayo Says:

    Hi Finn,

    Thanks, I will definitely do that!!!

    Happy New Year to all!


  55. JEDI » Blog Archive » links for 2008-01-20 Says:

    [...] Adventures in Software » Blog Archive » Cover flow in Javascript (tags: coverflow) [...]

  56. Adventures in Software » Blog Archive » Composability and orthogonality in language design Says:

    [...] by the way). But I’d like a solution that requires no plug-in. And having had success with cover flow, I thought I would give it a [...]

  57. Steve Says:

    Fantastic script - thankyou for sharing it.

    Is there any way to allow dragging of the actual images themselves, so the user can click and hold on an image that's off to the side, and drag it to the centre, or click and hold on the centre image and drag it to the side?
    I find that users seem to expect this, and try doing that before finding the slider.

  58. Mammy Says:

    That's great.

    Thank you for sharing it!!!

  59. fajar Says:

    great script.. i like itunes , so i like this script too... thanks..

  60. Sateesh Says:

    This is really very, very useful and cool script. Everyone to whom I showed it loves it...

    I am trying to use it on my website, however, i would like to get the 4th image as default one in the middle with 3 on each side. I saw your previous reply to this suggesting adding an onload() event to the body where we refresh and use slideTo(). i faced two problems with this: 1. when i used it with the body tag, it just went on displaying the Loading Images part and never loaded. So, i used jQuery's document.ready function and put the refresh and slideTo calls inside jQuery. It seems to be working well in IE7 but does not work in Mozzila Firefox or Google's Chrome. I haven't checked it in IE 6. What happens in Firefox is that it stops in middle of the slide while loading and this leaves some space on the left hand side of the middle image making it look uneven. It looks fine in IE 7 though... any clues why this is happening?

    Once again for sharing this great script.... !

  61. Sateesh Says:

    Also, Finn, I have tried adding the code to the window.onload function inside imageflow.js file. i am still facing the same issue with lot of space left on left hand side.... thanks for any help you can offer... !

  62. Michael L Perry Says:

    Hey, Sateesh. This isn't Finn's blog, but I hope he's watching and will respond.

    The easiest thing to do is just initialize current to 450 (3 * xstep). That should make the page initially display with the 4th image in the center. You won't need to add or modify any of the code.

    Hope this helps.

  63. Sateesh Says:

    Oops! I think I goofed up....

    Anyway, I'd like to thank you for sharing your wonderful script, Michael.... Are you saying that I directly set the current value to 450(3 * xstep) in the imageflow.js? I will try that...

  64. Terry Riegel Says:

    I just added this to my website with a few tweaks, its under Gallery. Is there a way to hide only the items for the category that is currently selected?


  65. Michael L Perry Says:

    Do you mean you want to show only the current category items? If so, it's probably easier to just have separate pages for each category.

    If you want to do something more complex than that, you will have to add some code to the main loop in moveTo. One good technique is to add a category attribute to each image, and test that attribute inside of moveTo to add some sort of effect. For example, you could set the opacity of the image to 50% if it is not in the current category.

    Let us know what you end up doing.

  66. Finn Says:

    Hi there,

    I just wanted to drop a note, that ImageFlow is now finally object-oriented. That means many(!) ImageFlow instances on one website are possible. Check the demo and the examples

    enjoy! ;D

  67. Paul Whitrow Says:

    Hey Michael,

    Just wanted to point you toward this and say thanks.

  68. Toshifumi Sugawara Says:


  69. Bartolomea Says:

    Nice work! I’ll have to do a cross post on this one ;)

  70. ALEXREM Says:


  71. programlar Says:

    Thanks great post

  72. Scrapbook Software Says:

    I am basically a cinematographer. This post gave me more ideas.

  73. Jason Says:

    How can i add this to a .aspx page in my webpage??? is ther a place where i can view all the source

  74. Simon Says:

    Fantastic script, however.... I was wondering if it's at all possible to have links from each image to a different address?
    This would be wonderfull, and I would be WILLING TO PAY!!!!

  75. wolf Says:

    script don't work with cross domain images...i can't make reflection

  76. boba Says:

    Here is another CoverFlow effect. Easy to install and modify. And you can add a link to the image

  77. charms Says:

    can i get access for this?

  78. christian louboutin Says:

    hi, where can i find this?

  79. Michael L Perry Says:

  80. Satellite Direct Says:

    Hello..please point out...where can i find this.....

  81. Mano Says:

    Hi Michael,
    Really your coverflow effect is wonderful and it helps me a lot.. Thanks for it..
    But i need to start from 3 image at first, i had seen your code as current=300(2*xstep), but it doesnt works..
    Help me.. Thanks in advance.. Hope i will have response from you..

  82. AJAX Image Gallery powered by Slideflow (like Cover Flow) | Mundo Python Says:

    [...] Basierend auf Code von Michael L Perry [...]

  83. cheap jerseys Says:

    Perhaps this is one of the most interesting blogs that I have ever seen. Interesting article, Funny comment. Keep it up!

  84. christian louboutin sale Says:

    Choo lives in London. jimmy choo He is currently involved in a project to set up a shoemaking institute in Malaysia, where his iconic status is often evoked to inspire budding shoemakers and fashion designers. His company Jimmy Choo Ltd. produces some of the most expensive high-end shoes.Our designer replica handbags can wear well with any accessory on purpose.jimmy choo shoes Meticulous pieces on the replica handbags absolutely shock your eyes.Jimmy Choo Keenan Patent Leather Sandals Black patent leather strappy sandals. Peep toe silhouette. Ankle closure with told toned side buckle. Leather upper, in-sole and sole.

  85. pandora jewelry Says:

    Really your coverflow effect is wonderful and it helps me a lot.. Thanks for it..
    But i need to start from 3 image at first, i had seen your code as current=300(2*xstep), but it doesnt works..

  86. Mojamel Says:

    Thanks for the incredible work. I am using it in my web site but there is one problem. When I run in IE 8, the images do not slide smoothly. They flicker when moving. With other browsers it works perfectly. Has anyone faced this problem. Please let me know what should be done. Thanks.

  87. moncler Says:

    But i need to start from 3 image at first, i had seen your code as current=300(2*xstep), but it doesnt works..

  88. Marian Emmz Says:

    Totally cool.... but it is not working properly for me.. :( some space issues...

  89. Free Online Games Says:

    Great job !I really would like to understand how it works. I've passed 2 days on it but I can't figure out.Would it be possible for you (or someone that did understand how it works) to email me some detailed explanations ? Thanks in advance, and again, congrats for the work !

  90. Elmer Bulthuis Says:

    check this out:

    it's not finished yet, but looks very promising i think