Curved image path when scrolling page - javascript

I'm trying to create a rollercoaster ride for a project and need the rollercoaster to follow a path.
You can see my illustration on rollercoaster
I need the red box to follow the rollercoaster road in the background? The red box illustreres the image I'm going to use. Is this possible? I'm trying using this code...
<script type="text/javascript">
$(window).on('scroll', function(e) {
var scrollTop = $(window).scrollTop();
//var windowHeight = $(window).height();
var windowHeight = $('.road2').height();
//var S = scrollTop + Math.floor(windowHeight / 2);
var S = $(this).scrollTop(); // scrolled distance
var t = 0 + (S/windowHeight);
//var T = 0 + (S/36); // value for Top
//var L = 300 + Math.abs(Math.sin(S/400)*460); // value for Left
//
//$(".rollerImage").css({top: T+'%', left: L+'px'}); //set CSS
var canvas_X=400;
var canvas_Y=400;
// Increment Parameterization
t += 0.05;
// Width of Car
var car_X=150;
// Hieght of Car
var car_Y=50;
// Point A
var a_X=0;
var a_Y=0;
// Point B
var b_X=canvas_X-car_X; //Place point B at the end
var b_Y=0;
// Center of Semi Circle
var c_X=(b_X-a_X)/2;
var c_Y=(a_Y-a_Y)/2;
// Calculate X and Y point on trajectory
var x = a_X + t * (b_X- a_X);
var y = Math.sqrt(Math.pow((b_X - a_X),2)/4 + Math.pow((x-c_X),2));
$(".rollerImage").css({top: x+'px', left: y+'px'}); //set CSS
});
</script>
Hope someone can help with this type of path animation. Maybe it is possible to define the path in a array of coordinates?
I've tried using joel scrollpath, but can't "bind" an image to the path :(
//Graahf

I've tried to get it working with the jQuery Scrollpath using your html and css files plus the code from the demo site.
Check if this is OK for you: http://jsfiddle.net/Skr4R/6/embedded/result/
You can also check the sources of the fiddle: http://jsfiddle.net/Skr4R/6/
Important for this, is that the entire wrapper moves and rotates, that is why in my solution the train-image is outside of the wrapper, like this:
<div class="rollerCoasters">
<img src="" style="background:red; height:100px; width:50px; position:absolute; top:380px; left:50%; z-index:200; margin-left:-25px">
</div>
<div class="wrapper">
<div class="road1"><img src="base64-encoded-img" width="1434" height="539"/></div>
</div>
Hope this gets you started. It might not be the best solution, if you want the train to move, and not it's surroundings.

i am trying to achieve the same process and this has helped me along, the way forward about roating the train/object with the track could you not rotate the background(track to make the train look like it is following the track)

Related

Jquery change position fixed to static based on viewport between two div

Im new to jquery.
I want to create a fixed bottom banner, and when i scroll down.. that banner will stop at the end of selected div that i want (in this case between "container-content-top" and "container-content-bottom" with smooth transition (not jumping like i did).
i already create using jquery,
<script>
$(document).ready(function(){
var topOfrel = $("#banner1").offset().top;
var topOffooter = $("#container-content-bottom").offset().top - $("#banner1").height() - $("#header-nav").height() - 120;
$(window).scroll(function(){
var y = $(window).scrollTop();
if (topOffooter > y) {
jQuery("#banner1").css("position", "fixed");
} else {
jQuery("#banner1").css("position", "static");
}
});
})
</script>
But it seems the banner will move into the position that i want (between 2 div) after certain px scroll. I already working on this for 3 days :(.
I want the banner will not fixed and change to static to the position i want with smooth transition after i scroll and responsive too.
here's my full code : http://jsbin.com/IDonagi/1/edit?html,css,output
anyone have better solution ?
Thx before guys :)
You want to trigger the switch when bottom border of browser window crosses the top position of #container-content-bottom. The correct code to determine them would be:
// topOffooter is the top offset of content after the banner.
// Have to add banner height here because its initial position is fixed,
// and therefore not counted when determining position of #container-content-bottom.
var topOffooter = $("#container-content-bottom").offset().top + $("#banner1").outerHeight();
...
// y is top offset of current bottom border of browser window
var y = $(window).scrollTop() + $(window).height();
Thanks for Leo,This is my solution for this problem,
<script>
$(document).ready(function() {
var topOfrel = $("#banner1").offset().top;
var topOffooter = $("#container-content-bottom").offset().top + $("#banner1").outerHeight();
$(window).scroll(function() {
var y = $(window).scrollTop() + $(window).height();
if (topOffooter > y) {
jQuery("#banner1").css("position", "fixed");
} else {
jQuery("#banner1").css("position", "static");
}
});
})
</script>
and for mobile device ready i simply adda this to head :
<meta name="viewport" content="user-scalable=no, width=device-width,initial-scale = 1.0,maximum-scale = 1.0" />
hope this help someone if needed :)

Change margin-top as user scrolls

I am trying to get a div to scroll up at the same amount of pixels as the user scrolls down the page. For example, in Google Chrome when using the mouse wheel, it scrolls down in about 20px intervals. But when you scroll down using the handle, the scrolling amount varies.
Here is my code so far:
var scrollCtr = 50;
$(window).scroll(function(){
scrollCtr = scrollCtr - 20;
$('div.nexus-files').css('margin-top', scrollCtr + 'px');
});
There are a few problems with this:
The user scrolling varies
It needs to subtract from margin-top if scrolling down and add to margin-top if scrolling up
Here is an example:
http://www.enflick.com/
Thanks for the help
You're doing it the wrong way, what you are trying to do should be done using position: fixed on div.nexus-files
div.nexus-files{position: fixed; top: 0;}
but anyway - if you still want to know what you can do with the scroll event - you better get to scrollTop of the document and set the margin-top to the same value
window.onscroll = function(event){
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);
document.getElementById('nexus-files_id').style.marginTop = top+'px';
}
I'm using pure Javascript instead of jQuery because of the overhead that might be crucial when the browser need to calculate stuff in a very short amount of time (during the scrolling). [this can be done even more efficient by storing reference to the element and the doc... but you know..)
I used id based selector to get the specific element instead of class based
AND I SAY AGAIN - this is not how you should do what you were trying to do
Why not using the actual scroll offset as reference or position ?
// or whatever offset you need
var scrollOffset = document.body.scrollTop + 20;
// jQuery
var scrollOffset = $("body").scrollTop() + 20;
Finally Got it
Here is the code I used to accomplish the task.
Most of the code is from http://enflick.com and I modified it to work with my individual situation.
jQuery(window).load(function(){
initParallax();
});
// parallax init
function initParallax(){
var win = jQuery(window);
var wrapper = jQuery('#wrapper');
var bg1 = wrapper.find('.nexus-files');
var koeff = 0.55;
if (bg1.length) {
function refreshPosition(){
var scrolled = win.scrollTop();
var maxOffsetY1 = 450;
var offsetY1 = scrolled * koeff;
var offsetY2 = scrolled * koeff - (maxOffsetY1 * koeff - offsetY1);
if (offsetY1 <= maxOffsetY1 * koeff - offsetY1) {
bg1.css("margin-top", +-offsetY1+"px");
//alert(+-offsetY1+"px");
}
}
refreshPosition();
win.bind('resize scroll', refreshPosition);
}
}

javascript (but not jQuery please) fixed position on x-axis but not y?

I've looked everywhere and so far have not found a non-jQuery js to handle this. I would like to avoid using a library for just this one simple task.
I would like to fix three navigation divs ("#header", "#tabs" and "#footer") to viewport left (or alternatively, to the x position of a div "#helper" with "position: fixed; left: 0; top: 0;") -- but not fix y. They can not be vertically fixed.
I've created a working js that forces the divs to reposition based on scrolling, but it's not smooth in the real page (too many dynamic and graphic elements) - I'd like it to either animate smoothly, or mimic fixed-left and not appear to reposition at all.
Anyone who can give pointers or a quick script, or review and modify the script I have made? I've noticed people tend to ask why an obvious solution is not used instead of answering the question... I will be glad to answer, but would prefer help with the actual problem.
Here is a jsFiddle with the problem: http://jsfiddle.net/BMZvt/6/
Thank you for any help!
Smooth animation example:
var box = document.getElementById('box');
var moveTo = function(obj, target) {
// start position
// you should obtain it from obj.style
var cpos = {
x: 0,
y: 0
}
var iv = setInterval(function(){
cpos.x += (target.x - cpos.x) * 0.3; // 0.3 is speed
cpos.y += (target.y - cpos.y) * 0.3; // 0.3 is speed
obj.style.left = Math.floor(cpos.x) + 'px';
obj.style.top = Math.floor(cpos.y) + 'px';
var dist = Math.abs(cpos.y - target.y); // distance (x+y) from destination
dist += Math.abs(cpos.x - target.x); // < 1 = object reached the destination
if(dist < 1) { // here we are checking is box get to the destination
clearInterval(iv);
}
}, 30); // this is also the speed
}
box.onclick = function(){
moveTo(box, {x: 90, y: 75}); // fire this function to move box to specified point
}
Demonstration: http://jsfiddle.net/Qwqf6/5/
Your script is your job, but this is a quick start how to solve animation problem
You can also do some fancy stuff with speed for example use sin(x) to set the speed
Demonstration #2 http://jsfiddle.net/Qwqf6/6/ (very smooth)
Full script here https://gist.github.com/3419179
I don't think there's a straight way to do this...
But here's a way.
First, You need to be able to detect the direction of the scrolling when window.onscroll event happens. You would do this by comparing the current page offsets with the newly acquired page offsets whenever the scroll event happens. (http://stackoverflow.com/questions/1222915/can-one-use-window-onscroll-method-to-include-detection-of-scroll-direction)
Now suppose you know the direction of the scroll, you want to change the styling for the divs depending on the direction of the scroll.
Let FixAtX be the value of the x coordinate that you want to fix your divs at.
Let OriginalY be the y coordinate of the divs.
Also whenever scrolling happens, despite of the direction, you want to remember the pageoffset X and Y. Let's call them OldX and OldY
If scrolling vertically:
Set position value for divs' style to be absolute.
Set top value for divs' style to be OriginalY
Set left value for divs' style to be OldX + FixAtX
If scrolling horizontally:
Set position value for divs' style to be fixed.
set top value for divs' style to be OriginalY - OldY (<- this may be different depending on how the browser computes pageOffset value,)
Set Left value for divs' style to be FixAtX
I think this should work...
Since you are just using browser's rendering for positioning, it should be very smooth!
hope I understood the question correctly.
This is for people who view this post - I wound up going with the solution I initially put together in the jsFiddle that used a simple javascript to mimic fixed x.
The javascript in the first answer was hefty and wound up buggy, and the second answer sounded good but did not work in practice. So, I'm recommending the javascript from the jsFiddle (below) as the best answer to fixed x and fluid y without a javascript library. It's not perfect and has a minimal delay but is the best answer I've found.
function fixLeft() {
function getScrollX() {
var x = 0, y = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
x = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft) ) {
x = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft) ) {
x = document.documentElement.scrollLeft;
}
return [x];
}
var x = getScrollX();
var x = x[0];
// have to get and add horizontal scroll position px
document.getElementById('header').style.left = x + "px";
document.getElementById('tabs').style.left = x + "px";
document.getElementById('footer').style.left = x + "px";
}
window.onscroll = fixLeft;

jQuery Variable Height

I'm trying to have an image gallery where a caption is vertically centered inside of a slideshow, here's the code I'm working with
$(window).load(function() {
var imageHeight = $('.flexslider .slides li img').height();
var captionTop = imageHeight - $('.title-cap').height();
var captionTop = captionTop/2;
$('.title-cap').css('top',captionTop + 'px');
var captionTopOne = imageHeight - $('.sub-cap-one').height();
var captionTopOne = captionTopOne/2;
$('.sub-cap-one').css('top',captionTopOne + 'px');
var captionTopTwo = imageHeight - $('.sub-cap-two').height();
var captionTopTwo = captionTopTwo/2;
$('.sub-cap-two').css('top',captionTopTwo + 'px');
var captionTopThr = imageHeight - $('.sub-cap-three').height();
var captionTopThr = captionTopThr/2;
$('.sub-cap-three').css('top',captionTopThr + 'px');
});
The caption is positioned absolutely, and I'm using top to do the centering...
So my thought process is, get the height of the base slideshow image to keep it responsive, minus the height of the current caption, and divide that by two ending with the top value.
The first instance is working, with "title-cap", but the next three are not. They all return the same wrong value. All caption classes have the same attributes, just different for assignment.
Also, what would I need to add in order for the values to dynamically change with the browser window size in real time.
Edit: Alright, did a little research and figured out the load/resize part.
This is what I have now
function setContent(){
[Added all of the above minus the onload part in here]
}
$(window).load(function() {
setContent();
});
$(window).resize(function() {
setContent();
});
Now just not sure why the sub-cap's aren't loading properly. Any ideas?
I've had similar problem when trying to get the size of hidden elements. I found this nice jQuery actual plugin. It might be what you need.

CSS: Child div overlapping parent

I have something vaguely like the following:
<div id="body">
surrounding text
<div id="pane" style="overflow: auto; height: 500px; width: 500px;">
lots and lots of text here
<span id="some_bit">tooltip appears below-right of here</span>
</div>
more surrounding text (should be overlapped by tooltip)
</div>
and:
<div id="tooltip" style="width: 100px; height: 100px;">Whee</div>
What I want to do is insert the tooltip such that it is positioned above the pane it's in. If it's attached to an element that's next to the pane boundary (like above), then it should be visible above the pane, and above the text surrounding the pane.
It should NOT a) extend the pane, such that you have to scroll down to see the tooltip (like in http://saizai.com/css_overlap.png), or b) be cut off, so you can't see all of the tooltip.
I'm inserting this with JS, so I can add a wrapper position:relative div or the like if needed, calculate offsets and make it position:absolute, etc. I would prefer to not assume anything about the pane's position property - the tooltip should be insertable with minimal assumptions of possible page layout. (This is just one example case.)
It's for a prototype tooltip library I'm writing that will be open source.
ETA: http://jsfiddle.net/vCb2y/5/ behaves visually like I want (if you keep re-hovering the trigger text), but would require me to update the position of the tooltip on all DOM changes and scrolling behavior. I would rather the tooltip be positioned with pure CSS/HTML so that it has the same visual behavior (i.e. it overlaps all other elements) but stays in its position relative to the target under DOM changes, scrolling, etc.
ETA 2: http://tjkdesign.com/articles/z-index/teach_yourself_how_elements_stack.asp (keep defaults except set cyan div 'a' to position:relative; imagine 'A' is the pane and 'a' the tooltip) seems to more closely behave as I want, but I've not been able to get it to work elsewhere. Note that if you make 'A' overflow: auto, it breaks the overlapping behavior of 'a'.
I can't think of a pure HTML/CSS solution for this.
The overflow declaration is the issue here. If the tooltip is in #pane:
you establish a positioning context within #pane, then the tooltip shows next to #some_bit (regardless of scrolling, etc.) but it gets cut-off.
you do not establish a positioning context, then the tooltip is not clipped but it has no clue where #some_bit is on the page.
I'm afraid you'll need JS to monitor where #some_bit is on the page and position the tooltip accordingly. You'd also need to kill that tooltip as soon as #some_bit is outside of the viewing area (not an issue if the trigger is mouseover).
Actually, if the trigger is mouseover then you may want to use the cursor coordinates to position the tooltip (versus calculating the position of #some_bit).
I would just put the tooltip outside of the #pane div and position it absolutely using JavaScript since you're using JS anyway.
I don't use Prototype so I don't know how it's done in Prototype, but in jQuery, you'd use $(element).position() to get the element position. If you have to do it manually, it's a little more complicated.
And you'll probably want to add a little extra logic to prevent the tooltip from extending outside of the document.
Edit: CSS used
#tooltip {
z-index: 9999;
display: none;
position: absolute;
}
JS used
Note: in jQuery, but it should be easy to change it to Prototype syntax.
$('#some_bit').hover(function() {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
// hovered element
var offset = $(this).offset();
var top = offset.top + docViewTop;
var left = offset.left;
var width = $(this).width();
var height = $(this).height();
var right = left + width;
var bottom = top + height;
// pane
var poffset = $('#pane').offset();
var ptop = poffset.top + docViewTop;
var pleft = poffset.left;
var pwidth = $('#pane').width();
var pheight = $('#pane').height();
var pright = pleft + pwidth;
var pbottom = ptop + pheight;
// tooltip
var ttop = bottom;
var tleft = right;
var twidth = $('#tooltip').width();
var theight = $('#tooltip').height();
var tright = tleft + twidth;
var tbottom = ttop + theight;
if (tright > pright)
tleft = pright - twidth;
if (tbottom > pbottom)
ttop = pbottom - theight;
if (tbottom > docViewBottom)
ttop = docViewBottom - theight;
$('#tooltip').offset({top: ttop, left: tleft});
$('#tooltip').css('display', 'block');
}, function() {
$('#tooltip').hide();
});
Edit: See it here.

Categories