I'm trying to make a gallery webpage where the gallery images become the background, and then scroll based on the position of the mouse.
The problem I am having is that my images are different sizes and ratios. here is what I have been using:
function makeScrollable(){
$(document).bind('mousemove',function(e){
var hiddenY = $(document).height() - $(window).height();
var hiddenX = $(document).width() - $(window).width();
var top = (e.pageY/$(window).height())*hiddenY;
var left = (e.pageX/$(window).width())*hiddenX;
$(document).scrollTop(top);
$(document).scrollLeft(left);
});
}
This seems to work fine for shorter images, but with taller images, the mouse only moves when the mouse is towards the top of the screen.
This also seems to work for horizontal scrolling, but if the browser window is too thin it doesn't work at all. I don't see this being a problem in actual use, but I'd like to find a way to address it just in case.
So, I guess the question is, is there a way to create a mouse-position based smooth scrolling background regardless of the height or width of the background images. The goal is that when the mouse if 50% of the way down the browser window, the image will be showing 50% of what was hidden.
Thanks in advance -Patrick Reynolds
here is the main html and javascript:
<body>
<div id="fp_gallery" class="fp_gallery">
<img src="images/1.jpg" alt="" class="fp_preview" style="display:none;"/>
<div class="fp_overlay"></div>
<div id="fp_loading" class="fp_loading"></div>
<div id="fp_next" class="fp_next"></div>
<div id="fp_prev" class="fp_prev"></div>
<div id="outer_container">
<div id="thumbScroller">
<div class="container">
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/G1Thmb.jpg" alt="images/Kingfisher/G1.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A1.1Thmb.jpg" alt="images/Kingfisher/A1.1.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A1.2Thmb.jpg" alt="images/Kingfisher/A1.2.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A1.3Thmb.jpg" alt="images/Kingfisher/A1.3.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A2.1Thmb.jpg" alt="images/Kingfisher/A2.1.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A2.2Thmb.jpg" alt="images/Kingfisher/A2.2.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A2.6Thmb.jpg" alt="images/Kingfisher/A2.6.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A5.1Thmb.jpg" alt="images/Kingfisher/A5.1.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A6.7Thmb.jpg" alt="images/Kingfisher/A6.7.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/Kingfisher/Thumbs/A8.1Thmb.jpg" alt="images/Kingfisher/A8.1.jpg" class="thumb" /></a></div>
</div>
<div class="content">
<div><a href="#"><img src="images/2.jpg" alt="images/2.jpg" class="thumb" /></a></div>
</div>
</div>
</div>
</div>
<div id="fp_thumbtoggle" class="fp_thumbtoggle">View Thumbs</div>
</div>
<div id="g_content" class="g_content">
<h1><a href="../V4.1/index.html">Back</a></h1>
<div id="g_menu" class="g_menu">
<ul>
<li>
<h3 class="AboutToggle"><a href="#">About</a></h3>
<div class="g_subitemAbout">
<span class="g_closeAbout"></span>
<h2>About</h2>
<ul>
<li>KINGFISHER ELEMENTARY SCHOOL REMODEL<span><p>L.W.P.B. Architecture - Summer Internship 2010</p></span></li>
<li>I worked on this project during my summer 2010 summer internship at L.W.P.B Architecture</li>
</ul>
</div>
<h4 class="PortfolioToggle"><a href="#">Portfolio</a></h4>
<div class="g_subitem">
<span class="g_close"></span>
<h2>Portfolio</h2>
<ul>
<li>These projects represent the majority of my schoolwork and professional experience, and are ordered starting with the most recent.</li>
<li><a href="Seattle.html">Seattle Civic Center</a></li>
<li><a href="Capitol.html">Capitol Hill Transit-Oriented Development</a></li>
<li><a href="Kingfisher.html">Kingfisher Elementary School Remodel (L.W.P.B.)</a></li>
<li><a href="Bricktown.html">Bricktown Internation Dance Studio</a></li>
<li><a href="Bosconero.html">Bosconero Multi-Use Facility</a></li>
<li><a href="OKC.html">O.K.C. Wellness Center</a></li>
<li><a href="Prarie">Prarie National Park Visitor's Center</a></li>
<li><a href="Woodward">Woodward Park Public Library</a></li>
<li><a href="Other">Other Projects</a></li>
</ul>
</div>
</li>
</ul>
</div> <!--End g_menu-->
<script type="text/javascript">
$(document).ready(function()
{
$(".g_subitemAbout").hide();
$("h3.AboutToggle").click(function()
{
$(this).toggleClass("active").next().slideToggle("slow");
return false;
});
$(".g_closeAbout").click(function()
{
$("h3.AboutToggle").toggleClass("active").next().slideToggle("slow");
return false;
});
$(".g_subitem").hide();
$("h4.PortfolioToggle").click(function()
{
$(this).toggleClass("active").next().slideToggle("slow");
return false;
});
$(".g_close").click(function()
{
$("h4.PortfolioToggle").toggleClass("active").next().slideToggle("slow");
return false;
});
});
</script>
</div> <!--End g_content--> <!--Coding for Portfolio and About menus-->
<!-- The JavaScript (Gallery) -->
<script type="text/javascript">
$(function() {
//current thumb's index being viewed
var current = -1;
//cache some elements
var $btn_thumbs = $('#fp_thumbtoggle');
var $loader = $('#fp_loading');
var $btn_next = $('#fp_next');
var $btn_prev = $('#fp_prev');
var $thumbScroller = $('#thumbScroller');
//total number of thumbs
var nmb_thumbs = $thumbScroller.find('.content').length;
//preload thumbs
var cnt_thumbs = 0;
for(var i=0;i<nmb_thumbs;++i){
var $thumb = $thumbScroller.find('.content:nth-child('+parseInt(i+1)+')');
$('<img/>').load(function(){
++cnt_thumbs;
if(cnt_thumbs == nmb_thumbs)
//display the thumbs on the bottom of the page
showThumbs(2000);
}).attr('src',$thumb.find('img').attr('src'));
}
//make the document scrollable
//when the the mouse is moved up/down
//the user will be able to see the full image
makeScrollable();
//clicking on a thumb...
$thumbScroller.find('.content').bind('click',function(e){
var $content= $(this);
var $elem = $content.find('img');
//keep track of the current clicked thumb
//it will be used for the navigation arrows
current = $content.index()+1;
//get the positions of the clicked thumb
var pos_left = $elem.offset().left;
var pos_top = $elem.offset().top;
//clone the thumb and place
//the clone on the top of it
var $clone = $elem.clone()
.addClass('clone')
.css({
'position':'fixed',
'left': pos_left + 'px',
'top': pos_top + 'px'
}).insertAfter($('BODY'));
var windowW = $(window).width();
var windowH = $(window).height();
//animate the clone to the center of the page
$clone.stop()
.animate({
'left': windowW/2 + 'px',
'top': windowH/2 + 'px',
'margin-left' :-$clone.width()/2 -5 + 'px',
'margin-top': -$clone.height()/2 -5 + 'px'
},500,
function(){
var $theClone = $(this);
var ratio = $clone.width()/120;
var final_w = 400*ratio;
$loader.show();
//expand the clone when large image is loaded
$('<img class="fp_preview"/>').load(function()
{
var $newimg = $(this);
var $currImage = $('#fp_gallery').children('img:first');
if($(this).width() > $(this).height())
{
jQuery('#fp_preview').css({height: "100%", width: ""});
}
else if($(this).width() < $(this).height())
{
jQuery('#fp_preview').css({height: "", width: "100%"});
}
/*if($newimg.width() > $newimage.height())
{
jQuery('#fp_preview').css({height: "100%", width: ""});
}
else
{
jQuery('#fp_preview').css({height: "", width: "100%"});
}*/
$newimg.insertBefore($currImage);
$loader.hide();
//expand clone
$theClone.animate
(
{
'opacity' : 0,
'top' : windowH/2 + 'px',
'left' : windowW/2 + 'px',
'margin-top' : '-200px',
'margin-left' : -final_w/2 + 'px',
'width' : final_w + 'px',
'height' : '400px'
},1000,function()
{$(this).remove();
}
);
//now we have two large images on the page
//fadeOut the old one so that the new one gets shown
$currImage.fadeOut(2000,function(
){
$(this).remove();
});
//show the navigation arrows
showNav();
}).attr('src',$elem.attr('alt'));
});
//hide the thumbs container
hideThumbs();
e.preventDefault();
});
//clicking on the "show thumbs"
//displays the thumbs container and hides
//the navigation arrows
$btn_thumbs.bind('click',function(){
showThumbs(500);
hideNav();
});
function hideThumbs(){
$('#outer_container').stop().animate({'bottom':'-160px'},500);
showThumbsBtn();
}
function showThumbs(speed){
$('#outer_container').stop().animate({'bottom':'0px'},speed);
hideThumbsBtn();
}
function hideThumbsBtn(){
$btn_thumbs.stop().animate({'bottom':'-50px'},500);
}
function showThumbsBtn(){
$btn_thumbs.stop().animate({'bottom':'0px'},500);
}
function hideNav(){
$btn_next.stop().animate({'right':'-50px'},500);
$btn_prev.stop().animate({'left':'-50px'},500);
}
function showNav(){
$btn_next.stop().animate({'right':'0px'},500);
$btn_prev.stop().animate({'left':'0px'},500);
}
//events for navigating through the set of images
$btn_next.bind('click',showNext);
$btn_prev.bind('click',showPrev);
//the aim is to load the new image,
//place it before the old one and fadeOut the old one
//we use the current variable to keep track which
//image comes next / before
function showNext(){
++current;
var $e_next = $thumbScroller.find('.content:nth-child('+current+')');
if($e_next.length == 0){
current = 1;
$e_next = $thumbScroller.find('.content:nth-child('+current+')');
}
$loader.show();
$('<img class="fp_preview"/>').load(function(){
var $newimg = $(this);
var $currImage = $('#fp_gallery').children('img:first');
$newimg.insertBefore($currImage);
$loader.hide();
$currImage.fadeOut(2000,function(){$(this).remove();});
}).attr('src',$e_next.find('img').attr('alt'));
}
function showPrev(){
--current;
var $e_next = $thumbScroller.find('.content:nth-child('+current+')');
if($e_next.length == 0){
current = nmb_thumbs;
$e_next = $thumbScroller.find('.content:nth-child('+current+')');
}
$loader.show();
$('<img class="fp_preview"/>').load(function(){
var $newimg = $(this);
var $currImage = $('#fp_gallery').children('img:first');
$newimg.insertBefore($currImage);
$loader.hide();
$currImage.fadeOut(2000,function(){$(this).remove();});
}).attr('src',$e_next.find('img').attr('alt'));
}
function makeScrollable(){
$(document).bind('mousemove',function(e){
var hiddenY = $(document).height() - $(window).height();
var hiddenX = $(document).width() - $(window).width();
var top = (e.pageY/$(window).height())*hiddenY;
var left = (e.pageX/$(window).width())*hiddenX;
$(document).scrollTop(top);
$(document).scrollLeft(left);
});
}
});
</script>
</body>
I think I've found a solution that works.... at least it's working so far. The problem is showing up when the hidden portion of the image is larger than the available window area.
This seems to be working.
function makeScrollable(){
$(document).bind('mousemove',function(e){
var hiddenY = $(document).height() - $(window).height();
var hiddenX = $(document).width() - $(window).width();
var top = (e.pageY/$(window).height())*hiddenY/1.3;
var left = (e.pageX/$(window).width())*hiddenX/1.3;
if(hiddenX>=$(window).width()){
var left = (e.pageX - $(document).scrollLeft() / 2);
}
if(hiddenY>=$(window).height()){
var top = (e.pageY - $(document).scrollTop() / 2);
}
$(document).scrollTop(top);
$(document).scrollLeft(left);
});
}
If anyone sees something in this that would make it work better, I would greatly appreciate the input.