E
exiquio
My company recently had a client that required similar functionality
to the CMotion 2 image gallery hosted at this URL:
http://www.dynamicdrive.com/dynamicindex4/cmotiongallery2.htm. This
kind of stuff seems to be done in flash a lot and this was the only
example of this functionality I could find after a few hours of
search. I am really grateful to the author for this contribution. I
did find the code a bit difficult to read and hard to integrate into
our project so I rewrote the functionality with MooTools and I am
posting it just in case someone is ever searching for such. I don't
think the code is perfect but it works. Imagine small blocks of
profile images and names with anchors in place of the O'reilly books.
I hope this helps somebody in the future. Feel free to tell me what
sucks about it. I am eager to learn most of the time.
Code:
window.addEvent('domready', function(){
var SomeNameSpace = function(){
var REST_AREA_HEIGHT = 7;
var MAX_SPEED = 10;
var TOP_PROTECTION = -6;
var scroll_speed = 0;
var move_state = '';
var actual_height = '';
var motion_container = $('motion_container');
var motion_container_height =
motion_container.getStyle('height').toInt();
var team_side_bar = $('team_side_bar');
var actual_height = team_side_bar.offsetHeight;
/* Private methods */
function getPositionOffset(item, offset_type){
if(offset_type == 'left'){
var total_offset = item.offsetLeft;
}else{
var total_offset = item.offsetTop;
}
var parent_element = item.offsetParent;
while(parent_element != null){
if(total_offset == 'left'){
total_offset += parent_element.offsetLeft;
}else{
total_offset += parent_element.offsetTop;
}
parent_element = parent_element.offsetParent;
}
return total_offset;
}
var main_obj_offset = getPositionOffset(motion_container, 'top');
return{
endOfGalleryAlert: function(target_id){
/* Shows context appropriate message when user scrolls over
profile limits */
var target =$(target_id);
target.setOpacity(1);
(function(){
target.setOpacity(0);
}).delay(1500);
},
scrollUp: function(){
move_state = 'up';
if(team_side_bar.getStyle('top').toInt() >
(motion_container_height - actual_height)){
team_side_bar.setStyle('top',
(team_side_bar.getStyle('top').toInt() - scroll_speed) + 'px');
}else{
SomeNameSpace.endOfGalleryAlert('scroll_alert_bottom');
}
uptime = setTimeout(SomeNameSpace.scrollUp, 10);
},
scrollDown: function(){
move_state = 'down';
if(team_side_bar.getStyle('top').toInt() < TOP_PROTECTION){
team_side_bar.setStyle('top',
(team_side_bar.getStyle('top').toInt() + scroll_speed) + 'px');
}else{
SomeNameSpace.endOfGalleryAlert('scroll_alert_top');
}
downtime = setTimeout(SomeNameSpace.scrollDown, 10);
},
handleMotion: function(event){
var page_x = window.getScrollLeft();
var page_y = window.getScrollTop();
var event = new Event(event);
var cursor_y = event.client.y;
cursor_y -= main_obj_offset - page_y;
var top_bound = (motion_container_height / 2 ) - REST_AREA_HEIGHT;
var bottom_bound = (motion_container_height / 2) +
REST_AREA_HEIGHT;
if(cursor_y > bottom_bound){
scroll_speed = (cursor_y - bottom_bound) /
((motion_container_height - REST_AREA_HEIGHT) / 2) * MAX_SPEED;
if(window.downtime){
clearTimeout(window.downtime);
}
if(move_state != 'up'){
SomeNameSpace.scrollUp();
}
}else if(cursor_y < top_bound){
scroll_speed = (top_bound - cursor_y) / ((motion_container_height
- REST_AREA_HEIGHT) / 2) * MAX_SPEED;
if(window.uptime){
clearTimeout(window.uptime);
}
if(move_state != 'down'){
SomeNameSpace.scrollDown();
}
}else{
scroll_speed = 0;
}
},
killMotion: function(event){
if(window.downtime){
clearTimeout(downtime);
}
if(window.uptime){
clearTimeout(uptime);
}
move_state = ''
},
init: function(){
motion_container.addEvent('mousemove', function(event){
SomeNameSpace.handleMotion(event);
});
motion_container.addEvent('mouseleave', function(event){
SomeNameSpace.killMotion(event);
});
motion_container.addEvent('mousedown', function(event){
SomeNameSpace.killMotion(event);
});
}
}
}();
// Call init()
SomeNameSpace.init();
});
to the CMotion 2 image gallery hosted at this URL:
http://www.dynamicdrive.com/dynamicindex4/cmotiongallery2.htm. This
kind of stuff seems to be done in flash a lot and this was the only
example of this functionality I could find after a few hours of
search. I am really grateful to the author for this contribution. I
did find the code a bit difficult to read and hard to integrate into
our project so I rewrote the functionality with MooTools and I am
posting it just in case someone is ever searching for such. I don't
think the code is perfect but it works. Imagine small blocks of
profile images and names with anchors in place of the O'reilly books.
I hope this helps somebody in the future. Feel free to tell me what
sucks about it. I am eager to learn most of the time.
Code:
window.addEvent('domready', function(){
var SomeNameSpace = function(){
var REST_AREA_HEIGHT = 7;
var MAX_SPEED = 10;
var TOP_PROTECTION = -6;
var scroll_speed = 0;
var move_state = '';
var actual_height = '';
var motion_container = $('motion_container');
var motion_container_height =
motion_container.getStyle('height').toInt();
var team_side_bar = $('team_side_bar');
var actual_height = team_side_bar.offsetHeight;
/* Private methods */
function getPositionOffset(item, offset_type){
if(offset_type == 'left'){
var total_offset = item.offsetLeft;
}else{
var total_offset = item.offsetTop;
}
var parent_element = item.offsetParent;
while(parent_element != null){
if(total_offset == 'left'){
total_offset += parent_element.offsetLeft;
}else{
total_offset += parent_element.offsetTop;
}
parent_element = parent_element.offsetParent;
}
return total_offset;
}
var main_obj_offset = getPositionOffset(motion_container, 'top');
return{
endOfGalleryAlert: function(target_id){
/* Shows context appropriate message when user scrolls over
profile limits */
var target =$(target_id);
target.setOpacity(1);
(function(){
target.setOpacity(0);
}).delay(1500);
},
scrollUp: function(){
move_state = 'up';
if(team_side_bar.getStyle('top').toInt() >
(motion_container_height - actual_height)){
team_side_bar.setStyle('top',
(team_side_bar.getStyle('top').toInt() - scroll_speed) + 'px');
}else{
SomeNameSpace.endOfGalleryAlert('scroll_alert_bottom');
}
uptime = setTimeout(SomeNameSpace.scrollUp, 10);
},
scrollDown: function(){
move_state = 'down';
if(team_side_bar.getStyle('top').toInt() < TOP_PROTECTION){
team_side_bar.setStyle('top',
(team_side_bar.getStyle('top').toInt() + scroll_speed) + 'px');
}else{
SomeNameSpace.endOfGalleryAlert('scroll_alert_top');
}
downtime = setTimeout(SomeNameSpace.scrollDown, 10);
},
handleMotion: function(event){
var page_x = window.getScrollLeft();
var page_y = window.getScrollTop();
var event = new Event(event);
var cursor_y = event.client.y;
cursor_y -= main_obj_offset - page_y;
var top_bound = (motion_container_height / 2 ) - REST_AREA_HEIGHT;
var bottom_bound = (motion_container_height / 2) +
REST_AREA_HEIGHT;
if(cursor_y > bottom_bound){
scroll_speed = (cursor_y - bottom_bound) /
((motion_container_height - REST_AREA_HEIGHT) / 2) * MAX_SPEED;
if(window.downtime){
clearTimeout(window.downtime);
}
if(move_state != 'up'){
SomeNameSpace.scrollUp();
}
}else if(cursor_y < top_bound){
scroll_speed = (top_bound - cursor_y) / ((motion_container_height
- REST_AREA_HEIGHT) / 2) * MAX_SPEED;
if(window.uptime){
clearTimeout(window.uptime);
}
if(move_state != 'down'){
SomeNameSpace.scrollDown();
}
}else{
scroll_speed = 0;
}
},
killMotion: function(event){
if(window.downtime){
clearTimeout(downtime);
}
if(window.uptime){
clearTimeout(uptime);
}
move_state = ''
},
init: function(){
motion_container.addEvent('mousemove', function(event){
SomeNameSpace.handleMotion(event);
});
motion_container.addEvent('mouseleave', function(event){
SomeNameSpace.killMotion(event);
});
motion_container.addEvent('mousedown', function(event){
SomeNameSpace.killMotion(event);
});
}
}
}();
// Call init()
SomeNameSpace.init();
});