Stop DIV from crossing specified position - javascript

I need to stop #first and #second div from crossing the green line. The example will explain you everything.
http://jsfiddle.net/3QdJt/1/
It works good when I'm scrolling UP but when I go down DIVs are jumping.
HTML
<div id="first"></div>
<div id="second"></div>
<div id="donotcross"></div>
CSS
#donotcross {
position: relative;
width 500px;
height: 5px;
top: 487px;
background: green;
}
#first {
position: fixed;
width: 50px;
height: 50px;
background: red;
right: 20px;
bottom: 50%;
margin-bottom: 50px;
}
#second {
position: fixed;
width: 50px;
height: 50px;
background: yellow;
right: 20px;
bottom: 50%;
margin-bottom: -50px;
}
jQuery
$(window).scroll(function () {
windowPos = $(this).scrollTop();
asd = $('#first').offset().top;
tauto = 500 - windowPos;
if(asd <= 500) {
$('#first').css('top', tauto);
$('#second').css('top', 600 - windowPos);
}
if (asd > 500 ){
$('#first').css('top', 'auto');
$('#second').css('top', 'auto');
}
});

You need to check the windowPos variable instead of checking asd > 500. The jumping is caused by you moving the boxes to be over 500. So to avoid the jumping you might want to do this
$(window).scroll(function () {
windowPos = $(this).scrollTop();
asd = $('#first').offset().top;
tauto = 500 - windowPos;
if(asd <= 500) {
$('#first').css('top', tauto);
$('#second').css('top', 600 - windowPos);
}
if (windowPos > 500 ){
$('#first').css('top', 'auto');
$('#second').css('top', 'auto');
}
});
Edited:
To achive sticky effect, I manually calculated the boxes position instead of using top:auto
$(window).scroll(function () {
var center = $(window).height() / 2;
//the 50 is the the #first and #second offset diff divide by 2
var firstBoxTop = center - 50;
var secondBoxTop = center + 50;
var windowPos = $(this).scrollTop();
if((windowPos + firstBoxTop) < 500) {
firstBoxTop = 500 - windowPos;
}
if((windowPos + secondBoxTop) < 600) {
secondBoxTop = 600 - windowPos;
}
$('#first').css('top', firstBoxTop);
$('#second').css('top', secondBoxTop);
});

It's much effective if you put everything inside one wrapper div.
<div id="wrapper">
<div id="first"></div>
<div id="second"></div>
</div>
<div id="donotcross"></div>
CSS
body {
height: 2000px;
}
#donotcross {
position: relative;
width 500px;
height: 5px;
top: 487px;
background: green;
}
#wrapper {
position: fixed;
width: 70px;
height: 130px;
background: gray;
right: 20px;
text-align: center;
top: 50%;
}
#first {
background: red;
width: 50px;
height: 50px;
margin: 10px auto;
}
#second {
background: yellow;
width: 50px;
height: 50px;
margin: 0 auto;
}
This script will work with any height and top values of #wrapper (might be dynamic), and with any height and position of #donotcross (also might be dynamic).
var start_p = $('#wrapper').offset().top - $('#wrapper').height()/2;
$('#wrapper').css('top', $('#donotcross').offset().top + $('#donotcross').height());
$(window).scroll(function () {
var windowPos = $(this).scrollTop();
var dnc = $('#donotcross').offset().top + $('#donotcross').height() - windowPos;
if (start_p >= dnc) $('#wrapper').css('top', start_p);
else $('#wrapper').css('top', dnc);
});
http://jsfiddle.net/3QdJt/3/

Related

Moving element horizontally on scroll

Trying to scroll an element horizontally right off the screen as the page scrolls down. I'd also like to be able to scroll back up and have the element be in the original position.
I'm having trouble getting the speed and reverse scroll to work just right. Any ideas what I can do?
$(document).ready(function () {
var $horizontal = $('.horizontal');
var startPosition = $horizontal.position();
var speed = 14;
var lastScrollTop = 0;
i=0
$(window).scroll(function () {
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
i++;
} else {
// upscroll code
i--;
}
lastScrollTop = st;
newPos = startPosition.left+(i*speed)
$horizontal.css({
'left': newPos
});
});
});
.container {
min-height: 50000px;
width: 100%;
overflow: hidden;
}
.horizontal {
position: fixed;
width: 50px;
background: url(http://www.pngpix.com/wp-content/uploads/2016/06/PNGPIX-COM-Renault-Megane-RS-Trophy-White-Car-PNG-Image.png) no-repeat center center;
background-size: cover;
width: 500px;
height: 200px;
left: 50%;
top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="horizontal">
</div>
</div>
Simply add the start position to current scrollTop
Edited to include speed
$(document).ready(function () {
var $horizontal = $('.horizontal');
var startPosition = $horizontal.position().left;
var speed = 14;
$(window).scroll(function () {
var st = $(this).scrollTop();
var newPos = (st * (speed/100)) + startPosition;
$horizontal.css({
'left': newPos
});
});
});
.container {
min-height: 50000px;
width: 100%;
overflow: hidden;
}
.horizontal {
position: fixed;
width: 50px;
background: url(http://www.pngpix.com/wp-content/uploads/2016/06/PNGPIX-COM-Renault-Megane-RS-Trophy-White-Car-PNG-Image.png) no-repeat center center;
background-size: cover;
width: 500px;
height: 200px;
left: 50%;
top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="horizontal">
</div>
</div>

Cover image position relative to text

I am trying to set a text to overlap an image but the position should stay same on all screen sizes.
Example:
Here is an example of what I have tried demo
.c-txt-on-img{
position: relative;
}
.c-txt-on-img .txt{
font-size: 30px;
font-weight: bold;
font-family: arial, sans-serif;
max-width: 200px;
position: absolute;
top: 80px;
left: 158px;
}
.c-txt-on-img .img {
width: 100vw;
height: 100vh;
background-size: cover;
background-position: center center;
}
<div class="c-txt-on-img">
<div class="txt">Tony where are you !!!!</div>
<div class="img" style="background-image: url(http://theprojectstagingserver.com/stackoverflow/txt-on-img/comic.jpg)"></div>
</div>
It works on a specific screen-size only, I can fix this on different sizes using different media queries but that will take too much time!
There are 2 main challenges:
1) Align the image and text to always stay on the same spot.
2) Aligning will leave extra uneven space on top/bottom & left/right side of the image so we need to increase image size enough that it covers the whole screen.
For first part we can define same top left position to text and image, then give a negative translate percentage to image so that top left origin of image is the same spot where the text bubble is.
Next we can calculate the space on right/left/top/bottom of image & increase its width till no negative space is left.
Below is a GIF image to explain this better:
Here is the DEMO
var viewportOffset = [],
winWidth,
winHeight,
inLoop = false,
resizeTimeout;
$(function(){
init();
});
$(window).resize(function(){
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function(){
init();
}, 500);
});
function init() {
winWidth = $(window).width();
winHeight = $(window).height();
inLoop = false;
coverImage();
}
function coverImage() {
$('.js-cover-img').each(function (i) {
viewportOffset[i] = getViewportOffset($(this));
if(!inLoop){
$(this).width('auto');
$(this).height('auto');
}
var imgWidth = $(this).width();
var imgHeight = $(this).height();
viewportOffset[i].right = winWidth - imgWidth- (viewportOffset[i].left);
viewportOffset[i].bot = winHeight - imgHeight- (viewportOffset[i].top);
if(viewportOffset[i].top < 0){
var vertViewportOffest = viewportOffset[i].bot;
}else if(viewportOffset[i].bot <= 0){
var vertViewportOffest = viewportOffset[i].top;
}else{
var vertViewportOffest = viewportOffset[i].top + viewportOffset[i].bot;
}
if(viewportOffset[i].right < 0){
var horViewportOffest = viewportOffset[i].left;
}else if(viewportOffset[i].left < 0){
var horViewportOffest = viewportOffset[i].right;
}else{
var horViewportOffest = viewportOffset[i].left + viewportOffset[i].right;
}
if(horViewportOffest > 0 || vertViewportOffest > 0){
$(this).width(imgWidth + 20);
inLoop = true;
coverImage();
return false;
}
});
}
/* Get's the viewport position */
function getViewportOffset($e) {
var $window = $(window),
scrollLeft = $window.scrollLeft(),
scrollTop = $window.scrollTop(),
offset = $e.offset();
return {
left: offset.left - scrollLeft,
top: offset.top - scrollTop
};
}
body, html{
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
.c-txt-on-img {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.c-txt-on-img .txt {
font-size: 30px;
font-weight: bold;
font-family: arial, sans-serif;
max-width: 200px;
position: absolute;
top: 30%;
left: 30%;
z-index: 2;
transform: translate(-50%, -50%);
text-align: center;
}
.c-txt-on-img .img {
transform: translate(-28.5%, -23%);
z-index: 1;
position: absolute;
top: 30%;
left: 30%;
min-width: 870px;
}
.c-txt-on-img img{
display:block;
width: 100%;
}
<script
src="https://code.jquery.com/jquery-1.12.2.min.js"
integrity="sha256-lZFHibXzMHo3GGeehn1hudTAP3Sc0uKXBXAzHX1sjtk="
crossorigin="anonymous"></script>
<div class="c-txt-on-img">
<div class="txt">Tony where are you !!!!</div>
<div class="img js-cover-img">
<img src="http://theprojectstagingserver.com/stackoverflow/txt-on-img/comic.jpg">
</div>
</div>

animate to right on scroll down and animate back to the left on scroll up

I'm trying to do an animation on page scroll where selected element will animate from left to right on scroll down and if back to top then animate the selected element from right to left (default position), here's what I tried
$(document).ready(function() {
$(window).scroll(function() {
var wS = $(this).scrollTop();
if (wS <= 10) {
$("#test-box").animate({
'left': 100
}, 500);
}
if (wS > 11) {
$("#test-box").animate({
'left': $('#main-container').width() - 100
}, 500);
}
});
});
#main-container {
width: 100%;
overflow: auto;
height: 500px;
}
#test-box {
background: red;
color: #ffffff;
padding: 15px;
font-size: 18px;
position: fixed;
left: 100;
top: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main-container">
<div id="test-box">test</div>
</div>
As you can see, on scroll down, the test box moves as I instruct but when scroll up, it does not go to the left as default, any ideas, help please?
You can add a global variable to control the animation. See the working snippet below please, where I've commented parts of the code that I added:
$(document).ready(function() {
var animated = false; //added variable to control the animation
$(window).scroll(function() {
var wS = $(this).scrollTop();
if (animated && wS <= 10) {
$("#test-box").animate({
'left': 100
}, 500);
animated = false; //animation ended
}
if (!animated && wS > 11) {
$("#test-box").animate({
'left': $('#main-container').width() - 100
}, 500);
animated = true; //it was animated
}
});
});
#main-container {
width: 100%;
overflow: auto;
height: 500px;
}
#test-box {
background: red;
color: #ffffff;
padding: 15px;
font-size: 18px;
position: fixed;
left: 100px;
top: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main-container">
<div id="test-box">test</div>
</div>
This should work, it also uses css for the animation.
$(document).ready(function() {
var box = document.querySelector('#test-box');
var stateClass = '-right';
window.addEventListener('scroll', function(event) {
box.classList.toggle(stateClass, document.body.scrollTop > 10);
});
});
#main-container {
width: 100%;
overflow: auto;
height: 2000px;
}
#test-box {
background: red;
color: #ffffff;
padding: 15px;
font-size: 18px;
position: fixed;
left: 100px;
top: 10;
transition: .5s linear;
}
#test-box.-right {
left: 100%;
transform: translateX(-100%) translateX(-100px)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main-container">
<div id="test-box">test</div>
</div>

Hide Sticky Div Once Scrolling Past Next Parent Div

I'm trying to hide a "sticky" div once it scrolls past the next parent div. I've currently successfully have it so it appears after scrolling "y > 100" but I'm having a lot of trouble getting the "Sticky Note" to disappear after scrolling past #break.
Example below.
http://codepen.io/anon/pen/BojKBx
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 100) {
$('.bottomMenu').fadeIn();
} else {
$('.bottomMenu').fadeOut();
}
});
.bottomMenu {
display: none;
position: fixed;
bottom: 0;
width: 50%;
height: 60px;
border-bottom: 1px solid #000;
z-index: 1;
margin: 0 auto;
left: 50%;
margin-left: -500px;
text-align: center;
}
#header {
font-size: 50px;
text-align: center;
height: 60px;
width: 100%;
background-color: red;
}
#container {
height: 2500px;
}
#break {
text-align: center;
font-size: 30px;
margin-bottom: 300px;
width: 100%;
background-color: yellow;
}
#footer {
height: 60px;
background-color: red;
width: 100%;
bottom: 0;
}
<div id="header">Home</div>
<div class="bottomMenu">
<h2>Sticky Note</h2>
</div>
<div id="container"></div>
<div id="break">Should Not Be Seen After This Point</div>
<div id="footer"></div>
You can get Y position of a div (its vertical offset starting from the top of the page), and then add condition to show sticky note only when you're below the required "Y" coordinate, and above the required div. Example:
http://codepen.io/anon/pen/EVPKyP
Javascript code:
$(document).scroll(function () {
var bodyRect = document.body.getBoundingClientRect(),
elemRect = document.getElementById("break").getBoundingClientRect(),
offset = elemRect.top - bodyRect.top - window.innerHeight;
var y = $(this).scrollTop();
if (y > 100 && y < offset) {
$('.bottomMenu').fadeIn();
} else {
$('.bottomMenu').fadeOut();
}
});
Sources:
Retrieve the position (X,Y) of an HTML element
screen width vs visible portion

Why my div floated in the right side, doesn't start from top?

I have this floating elements but the right element it start some pixels down then the left. Any idea how to fix this?
here is my code that I am using for this and please have a look on JSFiddle to see how it works https://jsfiddle.net/eoopvgmc/1/
CSS:
container{
width: 1472px;
margin: 0 auto;
}
.main_content {
background: blue;
float: left;
height: 1500px;
width: 500px;
}
.top_banner{
background: orange;
float: left;
height: 250px;
width: 500px;
}
.left-zone {
background: yellow;
float: left;
top: 0px;
width: 224px;
height: 284px;
}
.right-zone {
background: red;
float: left;
top: 0px;
width: 224px;
height: 284px;
}
JS:
(function($) {
var element = $('.left-zone'),
originalY = element.offset().top;
var topMargin = 0;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < originalY ? 0 : scrollTop - originalY + topMargin
});
});
})(jQuery);
(function($) {
var element = $('.right-zone'),
originalY = element.offset().top;
var topMargin = 0;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < originalY ? 0 : scrollTop - originalY + topMargin
});
});
})(jQuery);

Categories

Resources