I would like to create a panel who scroll to top with a fixed content under.
I would like to have this effect : Curtain JS
I don't want to use Curtain JS plugin because I only need the first effect. That the first panel be scrolled and when he disappeared be deleted. In fact that's it's effect be played once.
So I try this : my test
But the content under isn't fixed.
$(document).ready(function () {
var $vertical = $('#vertical');
$(window).scroll(function () {
var s = $(this).scrollTop(),
d = $(document).height(),
c = $(this).height();
scrollPercent = (s / (d - c));
var position = (scrollPercent * ($(document).height() - $vertical.height()));
$vertical.css({
'bottom': position
});
});
});
Can I have some help please ?
Here is a working version: http://jsfiddle.net/1wtaofr2/1/
Js:
$(document).ready(function () {
var $vertical = $('#vertical');
$('body').height($('.test').height() + $vertical.height());
$(window).scroll(function () {
var s = $(this).scrollTop(),
d = $(document).height(),
c = $(this).height();
scrollPercent = (s / (d - c));
var position = (scrollPercent * ($(document).height() - $vertical.height()));
$vertical.css({
"-webkit-transform":"translateY(-"+ position +"px)"
});
if (position > $vertical.height()) {
$('.test').css({
position: 'relative',
'padding-top': $vertical.height()
})
}
if (position < $vertical.height()) {
$('.test').css({
position: 'fixed',
'padding-top': 0
})
}
});
});
Css:
body {
margin-left: 0;
}
#vertical {
position: fixed;
width: 100%;
height: 100%;
background: red;
top: 0;
left: 0;
bottom: 0;
}
.test {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
In case you want to use an external library, maybe you will find scrollr useful.
Related
i want to change the background position on scroll with skrollr.js library , my background image has lots of images ( about 500 images ) and i want to change theme on scrolling , how can i do it ?
i want to do something like this code but with skrollr.js library :
$(function() {
var rotator = $('#rotator');
var container = $(document);
var viewport = $(window);
var images = 72;
var imageHeight = 30000 / images;
var scrollHeight = container.height() - viewport.height() + imageHeight;
var step = images / scrollHeight;
viewport.scroll(function(event) {
var x = -Math.floor(step * viewport.scrollTop()) * imageHeight;
rotator.css('background-position', x + 'px 0');
});
});
body {
height: 2000px;
}
#rotator {
font-size: 416px;
width: 1em;
height: 1em;
position: fixed;
top: 0;
right: 0;
z-index: -1;
background: transparent url(http://www.3sessanta.it/images/polaroid/sprite_polaroid_total.jpg) no-repeat 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rotator"></div>
Example Demo
I have a div1 which animates background position on hover direction of mouse by jquery.
But it's working properly. it's going not right direction and I want it to work on every single mouse hover on the div.
Find jsfiddle
code:
$(function() {
$(".mainCont").hover(function(e) {
// $(this).addClass("hoverOnce");
var edge = closestEdge(e.pageX, e.pageY, $(this).width(), $(this).height());
}, function(){
$(this).removeClass('top right bottom left');
// $(this).removeClass("hoverOnce");
});
});
function closestEdge(x,y,w,h) {
var topEdgeDist = distMetric(x,y,w/2,0);
var bottomEdgeDist = distMetric(x,y,w/2,h);
var leftEdgeDist = distMetric(x,y,0,h/2);
var rightEdgeDist = distMetric(x,y,w,h/2);
var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist);
switch (min) {
case leftEdgeDist:
$(".hoverOnce").addClass("left");
case rightEdgeDist:
$(".hoverOnce").addClass("right");
case topEdgeDist:
$(".hoverOnce").addClass("top");
case bottomEdgeDist:
$(".hoverOnce").addClass("bottom");
}
}
function distMetric(x,y,x2,y2) {
var xDiff = x - x2;
var yDiff = y - y2;
return (xDiff * xDiff) + (yDiff * yDiff);
}
The size of this image that you use in the background is 700x500:
http://thesis2010.micadesign.org/kropp/images/research/bird_icon.png
I think that if you add these settings to .mainCont that this will get you the desired result:
width: 700px;
height: 500px;
position: absolute;
For example:
.mainCont {
width: 700px;
height: 500px;
background: url(http://thesis2010.micadesign.org/kropp/images/research/bird_icon.png) no-repeat center center;
transition: all 0.5s ease-in-out;
margin: 100px auto;
position: absolute;
}
Fiddle
Finally, It got solved.
find fiddle demo
$('.mainCont').hover(function(e){
var dir = determineDirection($(this), {x: e.pageX, y: e.pageY});
$(this).addClass('direction_'+dir);
}, function() {
$(this).removeClass('direction_3 direction_1 direction_2 direction_0');
});
function determineDirection($el, pos){
var w = $el.width(),
h = $el.height(),
x = (pos.x - $el.offset().left - (w/2)) * (w > h ? (h/w) : 1),
y = (pos.y - $el.offset().top - (h/2)) * (h > w ? (w/h) : 1);
return Math.round((((Math.atan2(y,x) * (180/Math.PI)) + 180)) / 90 + 3) % 4;
}
i have a container that is stick to top after a specific point.
but its not enough for me.
i have a footer in the page and when the screen is small the stick part is hiding under the footer.
i want it to stop moving down in the footer top (to stop be fixed to 0 that point but be fixed to minus number that is the substraction between them).
this is my code.
what should i add for that goal?
and when to call it?
on resize?
on ready?
etc.
thanks a lot
window.onscroll = function (event) {
fixDiv();
};
function fixDiv() {
if (getBrowserHeight().width > 1284) {
var $div = $("#Container");
if ($(window).scrollTop() > $div.data("top")) {
$('#Container').css({ 'position': 'fixed', 'top': '0' });
}
else {
$('#Container').css({ 'position': 'static', 'top': 'auto' });
}
}
}
$(document).ready(function () {
$("#Container").data("top", $("#Container").offset().top);
});
This should get you going.
Don't mind to ask for help if somehting isn't clear.
$(document).ready(function() {
$(window).scroll(function() {
var footerEl = $('footer').offset().top;
var footerTop = (footerEl - $(window).scrollTop());
var containerHeight = $('.container').height();
var footerHeight = $('footer').height();
console.log('footer', footerTop);
$('.container').removeClass('sticky');
if (footerTop <= containerHeight) {
$('.container').addClass('sticky');
$('.container').css('bottom', footerHeight);
}
});
});
body {
height: 1000px;
position: relative;
}
.container {
width: 100%;
min-height: 300px;
position: fixed;
top: 0;
background: red;
}
.sticky {
position: absolute;
top: auto;
}
footer {
width: 100%;
min-height: 500px;
position: absolute;
bottom: 0;
background: black;
}
<html>
<body>
<div class="container"></div>
<footer></footer>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</html>
I've tried to make as few changes to your code as possible, but there's better ways to get around this ie. using classes, like in #mhx answer. Full JavaScript below (sorry, had to remove your getBrowserHeight() as it wasn't defined):
window.onscroll = function (event) {
fixDiv();
};
function fixDiv() {
var $div = $("#Container");
var $footer = $("footer");
if ($(window).scrollTop() >= $div.data("top") && $(window).scrollTop() < $footer.data("top") - $div.height()) {
$('#Container').css({ 'position': 'fixed', 'top': '0' });
}
else if ($footer.data("top") > $footer.data("top") - $div.height()) {
$('#Container').css({ 'position': 'absolute', 'top': $footer.data("top") - $div.height() });
}
else {
$('#Container').css({ 'position': 'static', 'top': 'auto' });
}
}
$(document).ready(function () {
$("#Container").data("top", $("#Container").offset().top);
$("footer").data("top", $("footer").offset().top);
});
Besides adding a top data attribute to your footer and defining $footer in the start of fixDiv(),I've added this to your initial if statement, to make sure that the scroll position, does not exceed the top of the footer minus the height of your div.
&& $(window).scrollTop() < $footer.data("top") - $div.height()
... and I've added this else if statement, in case it does exceed the top of the footer minus the height of your div
else if ($footer.data("top") > $footer.data("top") - $div.height()) {
$('#Container').css({ 'position': 'absolute', 'top': $footer.data("top") - $div.height() });
}
Here's a fiddle: http://jsfiddle.net/ds5tptay/
I have a vertically oriented vertical navigation bar, that I would like to make stop at the end of #contact. It will need to resume scrolling again if the user scrolls back up.
What is the best way to achieve this?
javascript being used:
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#nav>div');
var $window = $(window);
var top = $el.parent().position().top;
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 340 - $window.scrollBottom();
var scrollTop = $window.scrollTop()
if (scrollTop < top + 10) {
$el.css({
top: (top - scrollTop) + "px",
bottom: "auto"
});
} else if (visibleFoot > gap) {
$el.css({
top: "auto",
bottom: visibleFoot + "px"
});
} else {
$el.css({
top: 0,
bottom: "auto"
});
}
}).scroll();
});
jsfiddle
I believe this is the code you are looking for:
$(function() {
var $Nav = $('#Nav');
var $window = $(window);
var $contact = $('#contact');
var maxTop = $contact.offset().top + $contact.height() - $Nav.height();
window.navFixed = 1;
$window.bind("scroll resize", function() {
var currentTop = $window.scrollTop();
if (currentTop <= maxTop && window.navFixed == 0) {
$Nav.css({
position: 'fixed',
top: '5%'
});
window.navFixed = 1;
} else if (currentTop > maxTop && window.navFixed == 1) {
$Nav.css({
position: 'absolute',
top: maxTop
});
window.navFixed = 0;
}
}).scroll();
});
The #Nav element contains the CSS you had originally specified: position: fixed; top: (...). When the document is ready, the variable maxTop is calculated based on the #contact element's top and height.
On the scroll and resize event, the variable currentTop is calculated as the current scroll position. If this value is lower than maxTop, then #Nav is set to the original CSS; if the value is higher, new CSS styles are applied: position: absolute; top: maxTop;
window.navFixed is used to prevent the CSS to be constantly updated while scrolling. I'm sure that bit can be improved, however, it demonstrates its purpose.
Check out the JSFiddle for the full HTML..
PS. There's a minor bug in your code, where #Nav refers to the <ul> element, rather than the <nav> element. However, the moving element is the <ul>, when it should be <nav>.
My code is working fine, but Im getting a few problems. The first problem regards to the browsers ability to drag images around, when it happens a "stop signal" appears, and it breaks the code. Sometimes the signal appears (firefox), sometimes not. I dont know why. The second problem regards to the text outside the div. When the user drag the image, the text outside gets selected. Who can I solve it?
If you run the code, you need a 140px width image.
The code:
<div style="position: relative; height: 100px; width: 100px; overflow: hidden;" class="img-profile">
<div id="crop" style="position: absolute; width: 140px; left: -20px; height: 140px; top: 0px; background: url(/image/user/teste.jpg) no-repeat; cursor: move;"></div>
</div>
var x = 0;
var y = 0;
$(document).ready(function () {
$("#crop").mousedown(function () {
var crop = $(this);
$(document).mousemove(function (e) {
var x_movement = 0;
var y_movement = 0;
if (x == e.pageX || x == 0) {
x = e.pageX;
} else {
x_movement = e.pageX - x;
x = e.pageX;
}
if (y == e.pageY || y == 0) {
y = e.pageY;
} else {
y_movement = e.pageY - y;
y = e.pageY;
}
var left = parseFloat(crop.css("left")) + x_movement;
var min_left = 0;
var max_left = -40;
if (left >= min_left) left = min_left;
if (left <= max_left) left = max_left;
crop.css("left", left);
var top = parseFloat(crop.css("top")) + y_movement;
var min_top = 0;
var max_top = (parseFloat(crop.css("height")) - 100) * -1;
if (top >= min_top) top = min_top;
if (top <= max_top) top = max_top;
crop.css("top", top);
});
});
$(document).mouseup(function () {
x = 0;
y = 0;
$(document).unbind("mousemove");
});
});
Just noted that changing the crop div to a input solved both problems.
<input type="button" id="crop" style="position: absolute; width: 140px; left: -20px; height: 140px; top: 0px; background: url(/image/user/teste.jpg) no-repeat; cursor: move; border: 0px;" />