Changing the position of a fixed image with scrollposition - javascript

For my own portfolio I have an one-page website. To make it more personal i've created a low poly version of my head which is the fixed image.
But how do i change its position depending on which section is currently being viewed?
Example: When somebody is visiting the website and click on "About" the page would scroll down and the image would animate to the left so there will be more space for the content I want to display.
The CSS of the image:
img.imgPerson{
position: fixed;
z-index:2;
top: 48%;
left: 50%;
margin-top: -242px;
margin-left: -175px;
}
What I've tried with Javascript already:
$(window).scrollTop() > 450 {
$('.imgPerson').animate({
"left": '350px'
}, 300);
}

Working fiddle.
You should use if keyword and you've to wrap your code by scroll event :
var animate_right = true;
var animate_left = true;
$(window).on('scroll', function(){
if( $(window).scrollTop() > 450 ){
if(animate_right){
animate_right=false;
animate_left=true;
$('.imgPerson').animate({"left": '550px'}, 300);
}
}else{
if($('.imgPerson').css('left')=='550px'){
animate_left=false;
animate_right=true;
$('.imgPerson').animate({"left": '250px'}, 300);
}
}
})
Hope this helps.
var animate_right = true;
var animate_left = true;
$(window).on('scroll', function(){
if( $(window).scrollTop() > 450 ){
if(animate_right){
animate_right=false;
animate_left=true;
$('.imgPerson').animate({"left": '550px'}, 300);
}
}else{
if($('.imgPerson').css('left')=='550px'){
animate_left=false;
animate_right=true;
$('.imgPerson').animate({"left": '250px'}, 300);
}
}
})
body{
height: 1000px;
}
img.imgPerson{
position: fixed;
z-index:2;
top: 48%;
left: 50%;
margin-top: -242px;
margin-left: -175px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src='http://android-foundry.com/wp-content/uploads/signup2-img.png' class='imgPerson'/>

Related

Header disappearing on scroll

I'm trying to make my header disappear when scrolling down and only re-appear when scrolling up. I can't get it to work:
http://jsfiddle.net/mxj562qt/
Any ideas where I'm going wrong?
HTML:
<div id="header" class="custom-header">
This is your menu.
</div>
<main>
This is your body.
</main>
<footer>
This is your footer.
</footer>
Javascript:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $("#header").outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$("#header").addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
It would appear that the CSS class doesn't get added but I'm not sure why. Am I referencing the Div in the wrong way?
So, I can see that the issue stems from this bit of code ...
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
In my tests, the doc height was always > than the st + window height.
I did this ...
// Scroll Up
console.log('doc height: ', $(document).height());
console.log('st+window height: ', st + $(window).height());
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
// results from scrolling up + down
// doc height: 2058
// st+window height: 313
// doc height: 2058
// st+window height: 280
// doc height: 2058
// st+window height 1614
// doc height: 2058
// st+window height: 1580
Changing the aforementioned JS to this seems to get you where you need to be.
$("#header").removeClass('nav-up');
Then your CSS needed some work ...
I noticed that your top element wasn't applying due to the CSS selector priority.
.nav-up {
top: -50px !important;
}
The result: scrolling down, the nav bar hides, scrolling up, the navbar shows.
I forked your code below;
http://jsfiddle.net/itsbjk/aw6qb2mr/16/
The problem here is with your CSS. You have specified position:fixed; in your code and that bit of CSS overrides all the JS you are writing. Fixed will force your header to be visible no matter what you are doing. Instead, you could try this in your CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: absolute;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
The absolute property should make it disappear on scrolling. And also, your referencing of the <div> tag isn't wrong!

jQuery animate works different in IE

I have a script that displays fixed element on the bottom-right corner of the screen. This element must appear from bottom to top, as it does in Chrome and Firefox, but in IE it goes from top to bottom..
CSS:
.questionnaire {
position: fixed;
right: 25px;
z-index: 150;
display: none;
}
and JS:
(function($) {
$(document).ready(function() {
var cookie = $.cookie('smth');
resizeContent();
if (cookie == 'que') {
$('.questionnaire').css('display', 'block').animate({ top: collapsed }, 2000);
$('.questionnaire span').addClass('collapsed');
} else {
$.cookie('smth', 'que', { path: '/', expires: 1000*60*20 });
$('.questionnaire').css('display', 'block').animate({ top: expanded }, 2000);
$('.questionnaire span').removeClass('collapsed');
}
});
function resizeContent() {
windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
expanded = windowHeight - $('.questionnaire').height() + 'px';
collapsed = windowHeight - $('.questionnaire').height() + 238 + 'px';
}
})(jQuery);
Thanks in advance for any help!
Actually you do not need to do your animation in jQuery. You can limit your code to add remove class. CSS is more optimal way, no inline code and grater performance.
$("#col").click(function() {
$('.questionnaire').removeClass('expanded');
});
$("#ex").click(function() {
$('.questionnaire').addClass('expanded');
});
.questionnaire {
position: fixed;
background-color: red;
right: 25px;
bottom: 0px;
height: 0px;
z-index: -150; /* remove minus */
display: block;
width: 500px;
transition: height 2s;
-webkit-transition: height 2s;
}
.expanded {
height: 230px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="col">Collapse</button>
<button type="button" id="ex">Expand</button>
<div class="questionnaire"></div>
Since this element is fixed there is no need to set it's display to none. This works the same on any browser that support transition.

jitter when using jquery to alter background-position

Here's the jsfiddle.
It's the interface to cropping an image. As you can see the selection div takes the same background image and positions it to the negative of the top and left attributes of the selection div. In theory this should give a perfect overlap, but there's a jitter as you move the selection div around, and I can't seem to figure out what is causing it.
html
<div id="main">
<div id="selection"></div>
</div>
css
#main {
width: 600px;
height: 450px;
position: relative;
background: url("http://cdn-2.historyguy.com/celebrity_history/Scarlett_Johansson.jpg");
background-size: contain;
}
#selection {
width: 100px;
height: 100px;
position: absolute;
background: url("http://cdn-2.historyguy.com/celebrity_history/Scarlett_Johansson.jpg");
border: 1px dotted white;
background-size: 600px 450px;
}
jquery
$(document).ready(function () {
var move = false;
var offset = [];
var selection = null;
$("#selection").mousedown(function (e) {
move = true;
selection = $(this);
offset = [e.pageX - selection.offset().left, e.pageY - selection.offset().top];
});
$("#selection").mousemove(function (e) {
if (move == true) {
selection.css("left", e.pageX - offset[0]);
selection.css("top", e.pageY - offset[1]);
selection.css("background-position", (((-selection.position().left) - 1) + "px " + ((-selection.position().top ) - 1) + "px"));
}
});
$("#selection").mouseup(function (e) {
move = false;
});
})
It would appear that there is a value of 5 offset that needs to be added to ensure seamlessness
DEMO http://jsfiddle.net/nzx0fcp5/2/
offset = [e.pageX - selection.offset().left + 5, e.pageY - selection.offset().top + 5];
So, while experimenting I discovered that this was only a problem at certain sizes of the image. At the original size it is no problem, neither at half nor a quarter of this size. It wasn't simply a matter of keeping the image in proportion not having the image square or using even pixel sizes. I'm assuming this had something to do with partial pixel sizes, but I'm not sure, and I couldn't see any way to work around this, at least none that seemed worth the effort.
So while checking out the code of other croppers I took a look at POF's image cropper, they seem to have got round the problem by not using the background-position property at all (I'm not sure if it's plugin or they coded it themselves). They just set the image down and then used a transparent selection div with 4 divs stuck to each edge for the shading. So there's no pixel crunching on the fly at all. I like the simplicity and lightweight nature of this design and knocked up a version myself in jsfiddle to see if I could get it to work well.
new jitter free jsfiddle with no pixel crunching
I liked the solution for the preview box as well.
html
<body>
<div id="main">
<img src="http://flavorwire.files.wordpress.com/2012/01/scarlett_johansson.jpg" />
<div id="upperShade" class="shade" > </div>
<div id="leftShade" class="shade" > </div>
<div id="selection"></div>
<div id="rightShade" class="shade"></div>
<div id="lowerShade" class="shade" ></div>
</div>
</body>
css
#main {
position:relative;
width: 450px;
height: 600px;
}
#selection {
width: 148px;
height: 148px;
position: absolute;
border: 1px dotted white;
top: 0px;
left: 0px;
z-index: 1;
}
.shade {
background-color: black;
opacity: 0.5;
position: absolute;
}
#upperShade {
top: 0px;
left: 0px;
width: 600px;
}
#leftShade {
left: 0px;
top: 0px;
height: 150px;
width: auto;
}
#rightShade {
left: 150px;
top: 0px;
height: 150px;
width: 450px;
}
#lowerShade {
left:0px;
top: 150px;
width: 600px;
height: 300px;
}
jquery
$(document).ready(function () {
var move = false;
var offset = [];
var selection = null;
$("#selection").mousedown(function (e) {
move = true;
selection = $(this);
offset = [e.pageX - selection.offset().left, e.pageY - selection.offset().top];
});
$("#selection").mousemove(function (e) {
if (move == true) {
selection.css("left", e.pageX - offset[0]);
selection.css("top", e.pageY - offset[1]);
setShade();
}
});
function setShade() {
$("#upperShade").css("height", selection.position().top);
$("#lowerShade").css("height", 600 - (selection.position().top + 150));
$("#lowerShade").css("top", selection.position().top + 150);
$("#leftShade").css("top", selection.position().top);
$("#leftShade").css("width", selection.position().left);
$("#rightShade").css("top", selection.position().top);
$("#rightShade").css("left", selection.position().left + 150);
$("#rightShade").css("width", 450 - selection.position().left);
}
$("#selection").mouseup(function (e) {
move = false;
});
});

jQuery scrolling DIV: stop scrolling when DIV reaches footer

I have a #sidebar (which starts below my #header div) and a #footer (around 120px off the bottom of the page).
I'm trying to make the sidebar scroll with the content of the page. The code below does this semi-successfully:
/* profile sidebar */
#sidebar>div{ width: 300px; margin-top: 10px; }
#sidebar.fixed>div{position:fixed;top:0;}
#sidebar.fixed_bottom>div{position:fixed;bottom:172px;}
jQuery(function ($) {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var el = $('#sidebar'),
pos = el.position().top;
$(window).scroll(function() {
if ($(this).scrollTop() >= pos) {
if ( $(this).scrollBottom() <= 172 ) {
el.removeClass('fixed');
el.addClass('fixed_bottom');
} else {
el.removeClass('fixed_bottom');
el.addClass('fixed');
}
} else {
el.removeClass('fixed');
}
});
});
The problem is, on smaller resolutions, this makes the sidebar "jump" once you reach a certain position on the page. It stops it from overlapping the footer (which is the problem if you remove the fixed_bottom class) but doesn't look good.
What I'd like to do is this: user scrolls to the bottom of the page, the sidebar scrolls along with the content until it reaches say 20px above the top of my footer, at which point it stays there until the user scrolls back up.
Thanks in advance,
I believe this should do what you want.
http://jsfiddle.net/FDv2J/3/
#sidebar>div{ width: 100px; margin-top: 10px; position:fixed; left: 0; top: 0;}
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#sidebar>div');
var $window = $(window);
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 172 - $window.scrollBottom();
var scrollTop = $window.scrollTop()
if(scrollTop < 172 + 10){
$el.css({
top: (172 - scrollTop) + "px",
bottom: "auto"
});
}else if (visibleFoot > gap) {
$el.css({
top: "auto",
bottom: visibleFoot + "px"
});
} else {
$el.css({
top: 0,
bottom: "auto"
});
}
});
});
I tried to break things up and name variables in such a way that it would be understandable. Let me know if there's anything you're unsure of. Notice that I added resize as well as scroll since it matters if the window changes size.
EDIT: Modified version using similar technique to the original to find the upper bound:
http://jsfiddle.net/FDv2J/4/
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#sidebar>div');
var $window = $(window);
var top = $el.parent().position().top;
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 172 - $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();
});
body{
margin: 0;
}
#sidebar>div {
width: 100px;
height: 300px;
margin-top: 10px;
background-color: blue;
position: fixed;
}
#stuff {
height: 1000px;
width: 300px;
background-image: url("http://placekitten.com/100/100")
}
#footer,
#header {
height: 172px;
width: 300px;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sidebar">
<div class="fixed">sidebar</div>
</div>
<div id="stuff">
</div>
<div id="footer">
</div>

Slide Element Up Into Page?

I was wondering how I could slide up a banner at the bottom of my page that is hidden.
For instance:
Page loads
3 seconds later, the banner slides up from bottom of page
I want to be able to do this without any scrollbars appearing (no change in page height) and without revealing the banner prior to it sliding up.
I looked at slideUp() and slideToggle(), but I couldn't find a way to make it work to my liking :-/
Here's what I originally tried:
$(document).ready(function() {
$('.serverad').delay(3000).slideToggle('slow', function() {
// Animation complete.
});
});
And the CSS was visiblity: hidden;
use a position:fixed on the banner ad, and animate the bottom attribute to 0
have the initial bottom attribute be the a negative of its height.
<style>
.serverad
{
height:60px;
position:fixed;
left:0px;
bottom:-60px;
}
</style>
<script>
$(document).ready(function() {
$('.serverad').delay(3000).animate({bottom:"0px"},600);
});
</script>
I think you may want something along these lines:
HTML:
<body>
<div class="serveraddcontainer">
<div class="serveradd"></div>
</div>
</body>
CSS:
body{
overflow: hidden;
}
.serveraddcontainer{
width: 100%;
height: 80px;
position: absolute;
bottom: -80px;
}
.serveradd{
width: 400px;
height: 80px;
background-color: red;
margin: auto;
}
Javascript:
setTimeout(function(){
$('.serveraddcontainer').animate({'bottom': '0'});
}, 3000);
Example JSFiddle Here
Animate the height property instead of top:
In you CSS:
.serverad {
...
height: 0;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
visiblity: visible;
overflow: hidden;
...
}
And in your JS, change the animation code to:
$(document).ready(function() {
$('.serverad').delay(3000).animate({height: '30px'}, 'slow', function() {
// Animation complete.
});
});
Here's one approach:
var stepDurations = 3000;
var reveal = window.setTimeout(
function(){
$('#banner').animate(
{
'height' : '30px'
}, stepDurations,
function(){
$(this).animate(
{
'bottom' : $(window).height() - $(this).height()
}, stepDurations);
});
},stepDurations);
JS Fiddle demo.
Turned the above into a function:
function slideReveal(target, height, stepDuration, revealName){
if (!target) {
return false;
}
else {
var height = height || '30px',
stepDuration = stepDuration || 2000,
revealName = revealName || 'reveal';
revealName = window.setTimeout(
function(){
$(target).animate(
{
'height' : height
}, stepDuration,
function(){
$(this).animate(
{
'bottom' : $(window).height() - $(this).height()
}, stepDuration);
});
},stepDuration);
}
};
// call with:
slideReveal($('#banner'), '3em', 100, 'revelation');
JS Fiddle demo.

Categories

Resources