ProtoFlow - Now supports Keyboard and Mouse Wheel Events!
March 31st, 2008 | Published in Javascript, Projects, ProtoFlow, Prototype, Scriptaculous | 38 Comments
Well it doesn’t get any better than this. I have been over whelmed by the response that community has given to ProtoFlow. While I am still working to fix some issues with image positioning, Fabian and Martin posted a add-on for keyboard and mouse wheel support. After integrating their code I had to release it to general public asap. Thank you guys for your contribution.
By default both keyboard and mouse wheel support is turned on. To turn keyboard support off you can set options: enableKeyboard to false and to disable the mouse wheel events just turn enableMouse to false. Notice how the mouse wheel effect only works when your mouse is over the ProtoFlow object.
The latest code should be up here.

April 8th, 2008 at 8:48 am (#)
Hey, sorry I was away for a while because I had a look at another implementation called ImageFlow. It works a bit more stable but the code is ugly
The new navigation code is great. However I would tweak it:
if(this.options.enableKeyboard) {
document.observe(’keyup’, (function(e) {
var code = e.keyCode;
if(37 == code) {this.previous(); Event.stop(e);}
if(39 == code) {this.next(); Event.stop(e);}
}).bind(this));
}
You should stop the event. I have a page layout that somehow magically scrolls to the right (even if there is no scrollbar to that and without ProtoFlow it also would not scroll right on right arrow
I noticed that you get a different image behaviour when you turn reflection on and off. With reflection being off all images get resized to a square, with reflection I got the original image size. But the images were top aligned rather than bottom (but that acutally did not bother me its also looking neat when you turn the slider off)
For now I am prototyping on ProtoFlow and migtht bring you some more suggestions (especially for lightbox integration :-))
April 8th, 2008 at 8:50 am (#)
gnarf. it has to be “keydown” to make Event.stop(e); work correctly
April 8th, 2008 at 9:13 am (#)
Oh that was fast,
seems that other changes from you made it a lot easier:
handleClick: function(e){
var elem = Event.element(e);
var v = elem.getAttribute(”index”);
if (!v && this.options.useReflection) {
elem = elem.up(’a');
v = elem.getAttribute(”index”);
}
if (this.currIndex != v){
Event.stop(e);
this.currIndex = v;
this.goTo(v);
this.updateSlider(v);
}
},
I introduced that “this.currIndex != v” check for two purposes:
Performance: do not scroll to an element you are at already.
Lightbox Integration: Actually neat also for other purposes. If we do need to scroll then the image was not centered and we want to stop other actions on the image. If it was, the action goes through.
So click to scroll and click to lightbox nicely playing together.
April 15th, 2008 at 4:18 am (#)
hi everybody.
First, this a great script ! thank you for your work.
I use this script and all my images are linked to product pages.
But i want to let users slide with the mouse click. So i had to enable the enableOnClickScroll flag.
But how can i enable link on the focused image ?
So, how to disable links except for the focused image.?
Sorry for my englsh , i’m french ..
Thanks by advance.
Bruno
April 15th, 2008 at 7:34 am (#)
hi, i made a small protoflow powered (and google image serach powered) image search engine
please check it out, feedback welcome, great js, i had to tweak it here and there
http://www.creativspace.at/
April 21st, 2008 at 4:54 am (#)
creativspace.at just made it to the TechCrunch home page.
http://www.techcrunch.com/2008/04/21/a-better-interface-for-image-search/
I posted a comment with the link to ProtoFlow, which I already used in a site of mine (http://www.netgamestech.com/screenshots/ no tweaking required).
April 21st, 2008 at 7:22 am (#)
[…] to google images, google api, prototype, protoflow, script.aculo.us, firefox, firebug, webdeveloper toolbar Link 2.0: These icons link to social […]
April 22nd, 2008 at 9:37 am (#)
Great work Paolo! That looks amazing ..
April 25th, 2008 at 5:57 pm (#)
The ‘Flow’ is such an elegant display; thanks for sharing your work.
I asked the following question in both the ImageFlow and LightFlow sites, but haven’t heard back - perhaps you could figure out the way to do this?:
Rather than just plain images such as photos, would it be possible to add an embedded object such as a video? When I embed a YouTube video on a web site, for instance, the site is served a preview image and then the video when that image is clicked. This seems to me to be consistant with the philosophy here: show a bunch of previews and click on the one you want.
How would you do that?
April 30th, 2008 at 1:11 pm (#)
Hi
I just noticed that on the protoflow demo page as well as on my downloaded version, the links are not actually being opened/launched. Hovering over the image with focus does correctly display the HREF, but clicking it doesn’t do anything…
Interestingly, the links seem to work as expected on creativespace.
Any help would be apprciated.
Thanks
May 5th, 2008 at 1:05 am (#)
hi, i tweaked - the code a bit (matched to my site and the use i intended it for). now if you click on a picture it gets the focus -> scrolled into the middle. when it is in there, the default behavior of the click (follow the link) is enabled. would love to see this feature default in the code.
May 5th, 2008 at 6:53 am (#)
Franz.. if you want to contribute to the project feel free to email me and we can get your changes merged.
I really like the way you have implemented the script!
May 21st, 2008 at 2:24 pm (#)
hi obaid
change one
i kicke out the whole disableLinks mambojumbo and instead implemented this logic into the handleclick
handleClick: function(e){
var elem = Event.element(e);
var v = elem.getAttribute(”index”);
//FS the link go / no go logic comes into the handeClick
if(v != this.currIndex)
{
e.preventDefault();
}
if (!v && this.options.useReflection) {
elem = elem.up(’a');
v = elem.getAttribute(”index”);
}
this.currIndex = v;
this.goTo(v);
this.updateSlider(v);
},
hmmm… bye the way, there seem to handleWheel function in place, the second one works, but still switching from click or slide navigation to wheel navigation is still buggy
other thing.. on test i pimped up the slider, but saddly IE6 doesn’t include it in the DOM any more…. tricky, but i’m working on it.
May 23rd, 2008 at 6:06 am (#)
Thanks Franz. I will update the script accordingly. Is it possible for you to send me the modified JS and I will just merge them in?
May 31st, 2008 at 3:03 pm (#)
Hi,
I noticed the same problem, clicking the images doesn’t launch the URLs (both Firefox and IE). However, when I right-click the image and choose “Open in a new tab”, it works correctly!
Can you help me, please.
Thanks.
June 12th, 2008 at 10:13 am (#)
Hi. This is a great script. I seem to be having the same issue other people are having. When onclick scrolling is enabled, the picture hyperlinks do not work.
Please help.
Thanks
June 17th, 2008 at 8:09 am (#)
Hi! Great work!
I’ve found it is nice to emit a custom event on the div element in order to alert other elements on the page when paging through the images. To acheive this I added:
this.elem.fire(”protoflow:focus-change”, { ‘index’ : index })
to the goTo function
Then to listen to the event add:
function focus_change(event) { /* blah */ }
Event.observe($(”cover_flow_div”), ‘protoflow:focus-change’, focus_change);
before the construction of the ProtoFlow class.
June 17th, 2008 at 3:33 pm (#)
Thanks Adam. That is an interesting way of handling the events.
June 18th, 2008 at 5:40 pm (#)
Hi. I quite enjoy your solution - especially given that it is all js. However, the stopping point for me implementing is the fact that the picture hyperlinks do not work - ideally ‘onclick’ performed on the image in focus would fire the link?
As well, any intension to include use of tools like Highslide, Thickbox, etc? I would prefer to give people a magnified image without going to another page that only shows a larger image…..
I have started playing here: http://www.travellingcanadians.com/protoflow/
July 1st, 2008 at 6:26 am (#)
This is a really great bit of javascript. Unfortunately, I can’t use it in its current form.
The deal breaker for me? When going back to the first image, the z-index remains lower than the second image. This creates a real problem with certain images in some configurations where the first image is never brought to the front, though it is moved to the center.
I would definitely use it otherwise.
July 2nd, 2008 at 10:42 am (#)
Bill: I will definitely look at the issue asap.
July 4th, 2008 at 5:18 am (#)
First of all, great script! I really love it.
I just had one question, when i turn off useReflection, all the images are squares! They are reformed to squares while they are all retangles normally.
For example, normally: 350 x 100. But when i turn off useReflection it changes the images to 350×350 (in the space where normally the reflection was!).
What do i do wrong :P?
July 4th, 2008 at 11:25 pm (#)
Thanks, Obaid. I’m working on completing a website for a world-reknowned photographer at the moment and would love to use this on his site, but it’s breaking under certain conditions where the width of the container box gets too narrow. The front-most image is reacting as I explained above…remaining below the next sibling.
I’m pretty decent with the dom and javascript, but really haven’t had the time to hack into this just yet. If I stumble across thr troublesome bit of code, I’ll let you know.
I’ll also gladly let you know the photographer’s name, but not in the public comments box just yet. Email me if you’re interested.
Thanks for all your hard work.
–Bill
July 6th, 2008 at 12:30 am (#)
Hello
I have corrected the bug of the z-index for the first image.
Just replace
if (x < 0)
zIndex++;
else
zIndex–;
with
if (x < (this.options.flex / 2))
zIndex++;
else
zIndex–;
at the end of the moveTo function
The bug is just a rounding error
I’ve completly revamp the moveTo function too.
The animation will now automaticaly fit the size of the container and the size of the images and the stacking of “far” images is a little different now.
You can download my version here :
http://www.euclide.org/protoflow/protoFlow.new.js
Thanks for the script
–
Xavier
July 6th, 2008 at 10:13 pm (#)
EDIT :
In fact, the condition is
if (x < ( - this.options.flex / 2))
zIndex++;
else
zIndex–;
I forget the minus sign
July 7th, 2008 at 5:29 am (#)
Thanks Xavvier, I have updated the script with your updates included in it. Latest build is now available at http://www.deensoft.com/lab/protoflow
cheers
July 7th, 2008 at 9:56 am (#)
Ok
Just a detail, my name is Xavier (just one v)
I need to change my keyboard.
July 9th, 2008 at 6:51 am (#)
“Issue with the width and height of the image is still outstanding”
Hi, i have gently fixed the resizing function : images and their respective canvas ( if reflection is wanted ) are getting smaller when going to the background and bigger when going to the frontground.
I use stylesheet to force css, it’s simple and not really bieutifull, but it may be a clue for a correct use.
My stylesheet :
#protoflow {
width: 250px;
margin-top: 10px;
height: 145px;
padding-right: 26px;
}
#protoflow a {
padding: 0px;
margin: 0px;
// this value is important even seems to be no sense
// ‘a’ won’t get those value ‘height, width’ but it help us a lot
// the default size will be based on the image width then height is auto
height: 30px ;
width: 80px ;
display:block;
}
#protoflow div {
height: 100% !important;
width: 100% !important;
}
#protoflow img {
padding: 0px;
margin: 0px;
height: auto;
width: 100%;
}
#protoflow canvas {
padding: 0px;
margin: 0px;
height: auto !important;
width: 100% !important;
}
I wish after have been little bit stupid using a special tone with Obeid, that it will help you.
July 14th, 2008 at 10:55 am (#)
I believe I dl’d the version released on July 7th, but there’s several issues i’m running into
1. auto play and starting at 1st position is broken. right now I start at 0, and allow it to play and that seems to work, and I modified the code to check if nil, display a permanent caption. but really is not a fix.
2. I see the code working in FF3 on your site, but for some reason on my site, everything is still hidden.. i get no js errors, so just wondering , if this is common occurance, or if there are any other ideas ?
December 31st, 2008 at 10:58 pm (#)
I really like this script and would love to use it in a project or two. Is there any way to code the protoFlow script to use arrows at each end of the scrollbar or in each of the lower corners that when cliked would advance the images by 1 in which ever direction was chosen. I think this would greatly enhance the function of this wonderful little script. Thanks.
January 26th, 2009 at 12:27 am (#)
Hi, thanks for this great script. I’m currently in the first stages of experimenting with it, and I’m stuck here: when I load the webpage, the protoflow object seems to be instanciated right after the images are loaded (Event.observe(window, ‘load’, function() etc). The problem is esthetic: the browser displays the protoflow div first, loads the images in it, (so they are bicely lined up on screen, and only THEN instanciates the protoflow object. That’s how it behaves on your demo page too. I tried replacing “Event.observe(window, ‘load’, function(”) by “$(document).observe(”dom:loaded”, function()” which should normally do better, well indeed it does, (no images displayed before the “stack”), but then I loose the reflexions (I guess the canvas is not resized to accomodate the reflexions early enough).
I’d be grateful for a hint on how to solve this (I’m a js beginner….)
Thanks!
Dirk
May 8th, 2009 at 12:43 pm (#)
Hi everyone! Please let me start by saying that I really enjoy this script! I am very new to JS (been doing it about a week and a half now) and I am getting an error that I cannot seem to find resolution for and I am hoping someone smarter than me can lend me a hand.
I have been using this script on a site I am developing and what seems like ‘all of a sudden’ it quit working. I am getting an error that ‘Control is undefined’ at the line below
“this.slider = new Control.Slider(this.sliderHandle, this.sliderTrack, {
range: $R(0, this.getStackCount() - 1),
sliderValue: this.getCurrentPos(), // won’t work if set to 0 due to a bug(?) in script.aculo.us
onSlide: this.handleSlider.bind(this),
onChange: this.handleSlider.bind(this)
});”
I am theorizing that it has to do with the scriptalicious lib (slider.js) but I don’t know what to do to fix it even if I was right. I did expirament with setting slider: false when initializing the effect, it changed it back to ‘true’ after I tested the result.
Any words of encouragement/advise?! Thanks!!
May 9th, 2009 at 9:06 am (#)
Well, its definitively not the script
Same project moved to new dev environment yeilded expected results….doh!
May 14th, 2009 at 1:38 am (#)
I have a problem: Launching the demo on my local machine does not work, but on http://www.deensoft.com/lab/protoflow/ it works pretty well.
I tried to include it in my project, but i get the same issue:
Images are shown among each other for some seconds, but afterwards they disappear.
Tried the new versions of scriptacolous etc., but this did not help.
Any one a suggestion?
August 21st, 2009 at 9:33 pm (#)
Reflection is not working in chrome, i mean it shows as an extended image no opacity element there. Any suggestions on changing the code to work well with IE7, IE6.
November 16th, 2009 at 8:23 pm (#)
Is it possible to modify the script so that we have an option for looping? So, whether you are going from left to right or right to left, there is no end and its continuous?
July 7th, 2010 at 12:49 am (#)
hi, thanks for a great script.
I have just had one problem so far, while implementing the AutoPlay feature I found that it was not looping to the first image correctly.
—- How it is in your release ——
autoPlay: function(){
if ((this.currIndex + 2) > this.stackCount) {
this.currIndex = 0;
}
this.currIndex = this.currIndex + 1
this.goTo(this.currIndex);
},
————————————-
—- my fix ————————-
autoPlay: function(){
if (this.currIndex == (this.stackCount - 1)) {
this.currIndex = 0;
}else{
this.currIndex = this.currIndex + 1;
}
this.goTo(this.currIndex);
},
————————————-
This now seems to loop through all the images correctly, I’m not sure the IF statement needs to be changed to “(this.currIndex == (this.stackCount - 1)” but the ELSE is very important to ensure that the “currIndex” is set to 0 and not immediately not being incremented by 1.
Thanks Michael
July 7th, 2010 at 6:53 am (#)
Thanks Michael. I will fix the release version as per your submission.
Cheers!