Moving element horizontally on scroll - javascript

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>

Related

Vertical Scroll Indicator

Trying to create a Scroll Indicator, which would not be horizontal, but vertical. The problem is that when I try to start scrolling the bar that indicated the position isn't scaling...
HTML
<div id="scrollbar">
<div id="bar">
</div>
<div>
CSS
#scrollbar
{
width: 1%;
height: 100%;
padding: 0;
margin: 0 0 0 auto;
right: 0;
top: 0;
position: fixed;
visibility: visible;
background-color: transparent;
}
#scrollbar #bar
{
width: inherit;
height: 0%;
background-color: #ccc;
}
JS
var bar = document.getElementById("bar");
window.onscroll = function () { scrollIndicator() };
window.onload = function () { scrollIndicator() };
function scrollIndicator()
{
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var scrolled = 100;
if(height > 0)
{
scrolled = (winScroll / height) * 100;
}
bar.style.height = scrolled + "%";
}
I absolutely cannot find the problem...
your web page doesn't have enough content for it to scroll, hence scroll event isn't firing.
You need to fix the html, #scrollbar is missing a closing div tag and add enough content on the webpage so that it scrolls.
You also need to change the width of #bar from inherit to 100%.
var bar = document.getElementById("bar");
window.onscroll = function() {
scrollIndicator()
};
function scrollIndicator() {
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var scrolled = 100;
if (height > 0) {
scrolled = (winScroll / height) * 100;
}
bar.style.height = scrolled + "%";
}
#scrollbar {
width: 1%;
height: 100%;
padding: 0;
margin: 0 0 0 auto;
right: 0;
top: 0;
position: fixed;
background-color: transparent;
}
#scrollbar #bar {
width: 100%;
height: 0%;
background-color: blue;
}
.section {
height: 100vh;
}
.section:nth-child(even) {
background: green;
}
.section:nth-child(odd) {
background: red;
}
<div id="scrollbar">
<div id="bar"></div>
</div>
<div class="section"></div>
<div class="section"></div>
<div class="section"></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>

Filling window Background

I'm trying to put a picture on my background and my idea is that image fills the entire window, no matter what size it is.
I'm using html, css and script below:
// Funcao adaptImage()
// Parametros: targetimg
function adaptImage(targetimg) {
var wheight = $(window).height();
var wwidth = $(window).width();
targetimg.removeAttr("width")
.removeAttr("height")
.css({ width: "", height: "" });
var imgwidth = targetimg.width();
var imgheight = targetimg.height();
var destwidth = wwidth;
var destheight = wheight;
if(imgheight < wheight) {
destwidth = (imgwidth * wheight)/imgheight;
$('#fundo img').height(destheight);
$('#fundo img').width(destwidth);
}
destheight = $('#fundo img').height();
var posy = (destheight/2 - wheight/2);
var posx = (destwidth/2 - wwidth/2);
if(posy > 0) {
posy *= -1;
}
if(posx > 0) {
posx *= -1;
}
$('#fundo').css({'top': posy + 'px', 'left': posx + 'px'});
}
$(window).resize(function() {
adaptImage($('#fundo img'));
});
$(window).load(function() {
$(window).resize();
});
#fundo-externo {
overflow: hidden;
width: 100%;
height: 100%;
position: relative;
}
#fundo {
position: fixed;
width: 100%;
height: 100%;
}
#fundo img {
width: 100%;
position: absolute;
}
#site {
position: absolute;
top: 40px;
left: 50%;
width: 560px;
padding: 20px;
margin-left: -300px;
background: #FFF;
background: rgba(255,255,255,0.8);
}
<body>
<div id="fundo-externo">
<div id="fundo">
<img src="http://placehold.it/1920x1080" alt="" />
</div>
</div>
</body>
My problem is in some devices, the background does not fill completely , it appears a white list below.
Any ideas would help Many thanks
Use this setting for your background image
.for_background_img {
background-size: cover;
background-size: 100%;
background-repeat: no-repeat;
height: 100%;
}
don't use an <img> tag, but use the image as background image for your body:
body {
background: url('http://placehold.it/1920x1080') no-repeat;
background-position: fixed;
background-size:cover;
}

Stop DIV from crossing specified position

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/

Categories

Resources