You need:
mootools 1.2+ and
ImageScrOOler.js (in that order).
"compile" your mootools with the assets plugin for mootools-more.
The scrolling div that will hold the data is above, id="scr".
Creating an instance is easy:
var mc, sdata = []; // this should contain the JSON, look at Data control example
window.addEvents({
domready: function() {
// setup the class instance, mc is in global scope due to beforeunload...
mc = new ImageScrOOler(sdata, {
imagePath: "http://www.webtogs.co.uk/brands75/",
imageHeight: 85,
targetElement: $("scr"),
clickEvent: function(obj) {
window.location.href = "http://www.webtogs.co.uk" + escape(obj.url);
},
showProgress: false
});
}
});
You can also control the class externally, doing things such as:
Move or stop the scroller
mc.stop();
mc.move();
mc.options.carousel='true'; (works when moving to right, wraps same images without changing direction)
Change scroller direction, for eg. can use arrow buttons with mouseover or click events
mc.moveDirection = 'right';
mc.moveDirection = 'left';
mc.turn(); (ideally, use this method instead)
Change step
mc.options.moveSteps = 1; - default (slow)
mc.options.moveSteps = 4; - 4px at a time
mc.options.moveSteps = 10; - 10px at a time
Change delay between frames
(needs mc.move() to apply after)
mc.options.moveDelay = 16;mc.move(); - default, 16ms before each frame move
mc.options.moveDelay = 8;mc.move(); - 8ms
mc.options.moveDelay = 32;mc.move(); - 32ms
mc.options.moveDelay = 64;mc.move(); - 64ms
Data control - get new images
newData();
var newData = function(){
this.stop();
// load a new set of images and replace existing ones
this.data = [
{image: '100.jpg', url: '/Lifeventure/', title: 'Lifeventure'},
{image: '106.jpg', url: '/Littlelife_/', title: 'Littlelife '},
{image: '8.jpg', url: '/Lowe_Alpine/', title: 'Lowe Alpine'},
{image: '16.jpg', url: '/Maglite/', title: 'Maglite'},
{image: '108.jpg', url: '/Mammut/', title: 'Mammut'},
{image: '96.jpg', url: '/Marmot/', title: 'Marmot'},
{image: '30.jpg', url: '/Meindl/', title: 'Meindl'},
{image: '68.jpg', url: '/Merrell/', title: 'Merrell'}
];
this.loadAssets();
this.move();
}.bind(mc);
Get end-of-line events (or add your own)
mc.addEvent("complete", function(direction) {
console.log("hello from events, we just moved all the way to the " + direction);
});
Custom click event with a lightBox
if your JSON has additional properties, like obj.largerImage, you can do something like this:
...,
clickEvent: function(obj) {
if (obj.largerImage.length > 0) {
new largerBox(obj.largerImage, {options:values}); // this is pseudo code :)
}
else {
window.location.href = escape(obj.url);
}
},
...
For all this and more, view the raw class here:
/js/ImageScrOOler.js
// class: ImageScrOOler
// version: 1.62
// dependencies: mootools 1.2.x
// tested on: FireFox 3, IE7, Safari 4 (beta), Opera 9.60
// last updated: 10/09/2009 15:57:01
// url: http://fragged.org/
// author: dimitar chrostoff
// authorised use: modify and use as you deem fit. any link back appreciated :)
var ImageScrOOler = new Class({
Implements: [Options, Events],
moveDirection: "right",
moveOffset: 0,
options: {
// set defaults here
targetElement: $empty, // you NEED the target element to be an object
imagePath: "", // prefix images with this
imageSpacing: 10, // margin between scrolling images
imageOpacity: .8,
clickEvent: function(clickObj) {
window.location.href = escape(clickObj.url);
}, // this can open a url or call
moveDelay: 16, // animation delay between frames, in ms
moveSteps: 1, // move by number of pixels
imageHeight: 70, // default image height
showProgress: true, // show a 'status' like layer
defaultMessage: 'Click on the images below',
showMessage: ' Show me items from ',
imageClass: 'cur', // css class to apply to each image, for example, with cursor: pointer
EOL: 1000, // delay after eaching END-OF-LINE in ms
carousel: !true // if true, it just recycles images and no EOL is reached, works left to right.
},
initialize: function(data, options) {
// data needs to be an array of JSON like this:
// var data = [
// {image: 'Blowfish.gif', url: '/Blowfish', title: 'Blowfish'},
// {image: 'Bronx.gif', url: '/Bronx', title: 'Bronx'} ...
// ];
this.setOptions(options);
if ($type(this.options.targetElement) != "element")
return false;
if(!data.length)
return false;
this.data = data;
this.options.targetElement.empty();
// setup our elements
if (this.options.showProgress) // progress / mouseover status element, style #moostats via css
this.stats = new Element("span", {id: 'moostats', html: "Initialising..."}).inject(this.options.targetElement);
// containing titles layer
this.container = new Element("div", {
styles: {
overflow: "hidden",
height: this.options.imageHeight,
visibility: "hidden",
width: this.options.targetElement.getSize().x,
float: "left"
}
}).inject(this.options.targetElement);
this.subcontainer = new Element("div", {
styles: {
overflow: "hidden",
height: this.options.imageHeight,
visibility: "hidden",
width: this.options.targetElement.getSize().x,
"white-space": "nowrap"
}
}).inject(this.container);
// load images and start moving.
this.loadAssets();
// prepare containers and make visible
this.container.setStyles({
visibility: "visible",
opacity: 0.1
}).fade(0,1);
this.subcontainer.addEvents({
mouseleave: function() {
this.move();
}.bind(this),
mouseenter: function() {
this.stop();
}.bind(this)
}).setStyle("visibility", "visible");
if (this.options.showProgress)
this.stats.set("html", this.options.defaultMessage);
// get going!
this.stop(); // clear up reload issues
this.subcontainer.scrollTo(0,0);
this.move();
},
loadAssets: function() {
// injects images into our containers.
var _this = this; // can't bind this for the images onload so save a ref.
this.subcontainer.empty();
// loop array
this.data.each(function(el, i) {
new Asset.image(_this.options.imagePath + el.image, {
title: el.title,
"class": "mOOimage",
onload: function() {
if (i < _this.data.length)
this.setStyle("margin-right", _this.options.imageSpacing);
// add css settings to images here or change / force height.
this.set({
styles: {
height: _this.options.imageHeight
},
opacity: _this.options.imageOpacity
}).addClass(_this.options.imageClass).inject(_this.subcontainer);
_this.addImageEvents(this);
}
});
if (_this.options.showProgress) {
// output how many loaded
if (i < _this.data.length)
_this.stats.set("html", i + ' loaded...');
}
}); // each
this.subcontainer.scrollTo(0,0);
},
addImageEvents: function(img) {
return img.set({
events: {
click: function() {
if (this.options.clickEvent != null) {
// collect some garbage
this.stop();
img.removeEvents();
this.options.clickEvent.run(el);
}
}.bind(this),
mouseenter: function() {
if (this.options.showProgress && img.get("title") != null)
this.stats.set("html", " " + img.get("title") + "");
img.set("opacity", 1);
}.bind(this),
mouseleave: function() {
if (this.options.showProgress)
this.stats.set("html", this.options.defaultMessage);
img.set("opacity", this.options.imageOpacity);
}.bind(this)
}
});
},
getSize: function() {
// based on mootools 1.11 getSize, gets the subcontainer size and scroll data
this.subSize = {
'scroll': {'x': this.subcontainer.scrollLeft, 'y': this.subcontainer.scrollTop},
'size': {'x': this.subcontainer.offsetWidth, 'y': this.subcontainer.offsetHeight},
'scrollSize': {'x': this.subcontainer.scrollWidth, 'y': this.subcontainer.scrollHeight}
};
},
frame: function() {
// move one frame in whatever direction and handle stop/turn around.
if (this.moveDirection == "right") {
this.getSize();
this.subcontainer.scrollTo(this.subSize.scroll.x+this.options.moveSteps, 0); // number of pixels
// carousel -- works left to right only.
if (this.options.carousel) {
var first = this.subcontainer.getElements("img.mOOimage")[0];
if (first) {
var firstWidth = first.getStyle("width").toInt() + this.options.imageSpacing;
if (this.subSize.scroll.x >= firstWidth + this.moveOffset) {
this.moveOffset += firstWidth;
this.addImageEvents(first.clone()).inject(this.subcontainer); // moves to end.
first.removeEvents().removeClass("mOOimage").setOpacity(0.1);
}
}
return false;
}
this.getSize();
if (this.subSize.size.x + this.subSize.scroll.x >= this.subSize.scrollSize.x && this.subSize.scroll.x > 0) {
// reached end of data to right, go left
this.stop();
this.fireEvent("complete", this.moveDirection);
this.moveDirection = "left";
(function() {
this.move();
}).delay(this.options.EOL, this); // pause at end of line to allow seeing last item
}
}
else {
this.getSize();
// C.log(this.subSize.scroll.x, this.options.moveSteps, this.subSize.scroll.x - this.options.moveSteps);
this.subcontainer.scrollTo(this.subSize.scroll.x-this.options.moveSteps, 0); // move nn pixels
this.getSize();
if (this.subSize.scroll.x <= 0) {
// reached left end of data to left, turn around...
this.stop();
this.fireEvent("complete", this.moveDirection);
this.moveDirection = "right";
(function() {
this.move();
}).delay(this.options.EOL, this); // pause at end of line to allow seeing last item
};
}
},
move: function() {
// drives moving
this.stop();
this.moveTimer = (function() {
this.frame();
}).periodical(this.options.moveDelay, this);
},
stop: function() {
// stop moving.
$clear(this.moveTimer);
},
turn: function() {
// swap direction
this.moveDirection = (this.moveDirection == "right") ? "left" : "right";
this.subcontainer.getElements("img").filter(function(el) {
return !el.hasClass("mOOimage"); // remove ghost images
}).dispose();
}
}); // end ImageScrOOler class