Scrolling Parallax Issues — posY Jumping - javascript

I'm working on a site based on this: http://inner.geek.nz/javascript/parallax/
All's well except I'm getting a jump down (by whatever px is set in calcParallax(xx, x, posY))
on scroll. This number should be where the image ends not where it begins — it should begin scrollTop or 0. Not sure what I'm doing wrong, I've pretty much taken the structure verbatim from the above link without the #cloud object or relevant script.
Here's what I have:
<script type="text/javascript">
function calcParallax(tileheight, speedratio, scrollposition) {
return ((tileheight) - (Math.floor(scrollposition / speedratio) % (tileheight+1)));
}
window.onload = function() {
window.onscroll = function() {
var posX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : window.pageXOffset;
var posY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : window.pageYOffset;
var ground = document.getElementById('ground');
var groundparallax = calcParallax(53, 8, posY);
ground.style.backgroundPosition = "0 " + groundparallax + "px ";
document.getElementById('javascriptcode').onscroll = function() {
var posX = (this.scrollLeft) ? this.scrollLeft : this.pageXOffset;
var j = calcParallax(53, 16, posX);
console.log('scroll js: '+ j);
document.getElementById('javascriptcode').style.backgroundPosition = j + "px 0";
}
}
</script>
Any help would be much appreciated

Use this example instead. It uses a different jQuery that seems more stable and does not jump around like the script from inner geek.
http://www.stevefenton.co.uk/cmsfiles/assets/File/backgroundparallax.html

I put together a demo on something similar while trying to minimize scripting in the scroll event... I've found that it's jumpy in Firefox and Chrome, and oddly smooth as silk in IE.
Even this game website that uses a combination of Mootools and CSS transitions is a bit jumpy.
CSS
/* Tiled background image */
body {
margin: 0;
padding: 0;
/* Use height of header image for top position */
background: #000 url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bgtile.jpg) left 1080px repeat-y;
}
/* Top background image (1920x1080) */
#wrapper {
position: relative;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bg1.jpg) center top repeat-x;
z-index: 100;
}
/* Page Title image */
#header {
height: 350px;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/title.png) center 40px no-repeat;
}
/* Content Block with 55% opacity background image */
.block {
width: 600px;
height: 500px;
margin: 20px auto;
border: #333 1px solid;
padding: 20px;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bg-black-55.png);
}
.block h3 {
font-family: 'Arial Black', Gadget, sans-serif;
font-size: 130%;
}
HTML
<body> <!-- contains repeated background image -->
<div id="wrapper"> <!-- contains top image -->
<div id="header"></div> <!-- contains the page title image -->
<div class="block"> <!-- contains 55% opacity background image -->
<h3>Block 1</h3>
<div class="content">Content 1.</div>
</div>
<div class="block">
<h3>Block 2</h3>
<div class="content">Content 2.</div>
</div>
<div class="block">
<h3>Block 3</h3>
<div class="content">Content 3.</div>
</div>
<div class="block">
<h3>Block 4</h3>
<div class="content">Content 4.</div>
</div>
<div class="block">
<h3>Block 5</h3>
<div class="content">Content 5.</div>
</div>
</div>
</body>
Script
$(document).ready(function(){
// defaults
var st, win = $(window)[0],
body = $('body')[0],
doc = (jQuery.support.boxModel) ? document.documentElement : document.body,
wrap = $('#wrapper')[0],
// Set top background image height here
imgH = 1080; // top image height
// vertical parallax scroll
$(win).scroll(function(){
st = (win.pageYOffset || doc.scrollTop );
if (st < imgH) { wrap.style.backgroundPosition = 'center ' + (st/4) + 'px'; } // limit moving top image only when in view
body.style.backgroundPosition = 'left ' + ( imgH + st/4) + 'px';
});
});

Change your 53 to the exact height of each element.
The only thing I can't figure out about this script is it jumps slightly vertically when I change it to a scroll left function.
var element = document.getElementById('element');
var elementparallax = calcParallax(7000, .5, posX);
element.style.backgroundPosition = " 0" + elementparallax + "px";
};
P.S. You can change the vertical scroll to horizontal by changing posY to posX and in = "0_" + elementparalax to = "_0"

Related

Move element by certain amount while scrolling

I want to move the white box to the right by 50% while scrolling until it reaches the red section. The distance to the red section is 1000px in the example.
The code below moves the box to the right as I scroll down, and I'm just using a random number 10 to slow down the movement but I can't get my head around to make it move evenly for every scroll event until the box reaches the red section and move 50% to the right.
var xPos = 0;
function getXPos(target, windowPos) {
var amount = windowPos - target;
xPos = amount / 10;
return xPos;
}
$(window).scroll(function() {
var windowPos = $(window).scrollTop();
var sectionOne = $('section.one').offset().top;
var sectionTwo = $('section.two').offset().top;
var box = $('.box');
if (windowPos > sectionOne && windowPos < sectionTwo) {
box.css({
"transform": 'translateX(' + getXPos(sectionOne, windowPos) + '%)'
});
}
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
There is also another issue with scroll that if I scroll too fast, the box won't move as much.
Here is the fiddle for demonstration.
https://jsfiddle.net/sungsoonz/0Lspo2d9/
So I used the logic of making a progress bar for whole page but for your section with class "one". So when you scroll the section 100% of it's height the "left" css property on the div with class "box" becomes at value of "100%". But as I understood we need to stop moving when we reach section with class "two" with div with class "box". So {left: 100%} will become when we have scrolled whole section with class "box" minus the visible height of div with class "box". Then it is easily calculated to move only for 50% of width of section with class "one" (-width of div with class "box" width / 2 to center it). Hope I described my solution clearly (xd). Hope it helps
The code:
one = document.querySelector(".one")
two = document.querySelector(".two")
box = document.querySelector(".box")
$(window).on('scroll', function (){
if (window.scrollY >= (one.scrollHeight - box.offsetHeight)) {
$('.box').css('left', `calc(50% - ${(box.offsetWidth / 2)}px`);
return
}
$scrolledFrom = $(document).scrollTop();
$documentHeight = $(document).height() - ($(".two").height() + box.offsetHeight);
$leftOffset = ($scrolledFrom / $documentHeight) * 100;
$('.box').css('left', `calc(${($leftOffset / 2)}% - ${(box.offsetWidth / 2)}px`);
console.log ()
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
left: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

How to use Hammer.js for swiping?

So i've got hammer.js swipe to work on my div. the swipe region looks like this
https://imgur.com/ncW4nDB
so basically, i want the orange area to be able to swipe left/right and when it reaches the end (on both sides), it halts swiping.
the script and etc :
var containerDiv = document.getElementById('list-container');
var listDiv = document.getElementById('train-line-list');
// Create a manager to manager the element
var manager = new Hammer.Manager(listDiv);
// Create a recognizer
var Swipe = new Hammer.Swipe();
// Add the recognizer to the manager
manager.add(Swipe);
// Declare global variables to swiped correct distance
var deltaX = 0;
var deltaY = 0;
// Subscribe to a desired event
manager.on('swipe', function(e) {
deltaX = deltaX + e.deltaX;
var direction = e.offsetDirection;
var translate3d = 'translate3d(' + deltaX + 'px, 0, 0)';
if (direction === 4 || direction === 2) {
e.target.innerText = deltaX;
e.target.style.transform = translate3d;
}
});
<div id="list-container">
<div id="train-line-list">
<img id="" src="">
<img id="" src="">
</div>
#list-container{
z-index: 10;
position:fixed;
top:60%;
left:0;
width:100%;
height:40%;
}
#train-line-list{
width: 95%;
height: 95%;
top: 2%;
margin: 0 auto;
position: relative;
}
like i said, the swiping sort of works but the images disappear. why does this happen and how can i fix it? Also, the swiping is not very "reactive" in a way, like its slow. not natural. is there an alternative? or a better way to implement? Also, just realized, the images can be swiped as well ?? how do i "lock" the images. i just want the container of the images to be swiped.
Here is a working example
<html>
<head>
<style>
#box {
background-color: red;
height: 100px;
width: 100px;
margin-right: 10px;
}
#collection {
display: flex;
flex-direction: horizontal;
}
#container {
display: flex;
background-color: aqua;
padding: 50px 0px 50px 0px;
overflow: scroll;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
</head>
<body>
<div id="container">
<div id="collection">
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
<div id="box"></div>
</div>
</div>
<script>
var container = document.getElementById("container");
var content = document.getElementById("collection");
var hammer = new Hammer(container);
var initialX = 0;
var deltaX = 0;
var offset = initialX + deltaX;
hammer.on("panleft panright", function(ev) {
deltaX = ev.deltaX;
offset = initialX + deltaX;
container.scroll(-offset, 0);
});
Hammer.on(container, "mouseup", function(e) {
initialX = offset;
});
</script>
</body>
</html>
You could replace the squares with your images.

How to simulate rays emerging from an image/div to another image/div using HTML and CSS

I want to build a page to show a blown-up version of an image.
I have the smaller image and the bigger image built out. I am not sure how to build the in between portion that looks like rays coming out of the smaller image.
HTML
<div class="flex">
<div class="exp" tabindex="0">
<img class="image" src="http://via.placeholder.com/50x50">
</div>
<div class="big-image">
<img class="image" src="http://via.placeholder.com/350x550">
</div>
</div>
CSS
.exp {
margin: 5px;
width: 100px;
height: 100px;
background-color: #ded3c0;
border-radius: 100%;
line-height: 80px;
align-items: center;
display: flex;
justify-content: center;
}
.exp .image {
width: 50px;
height: 50px;
}
.big-image {
border: 1px solid #000;
padding: 20px;
border-radius: 19px;
}
.flex {
display: flex;
align-items: center;
justify-content: space-around;
}
Any pointers on how to do this is helpful.
Here is jsfiddle https://jsfiddle.net/npkeq7ut/
If you need only lines you can achieve this with JS and skew transform:
let topLine = document.getElementById('top-line');
let bottomLine = document.getElementById('bottom-line');
function updateLines()
{
let b = document.getElementById('b').getBoundingClientRect();
let a = document.getElementById('a').getBoundingClientRect();
let left = a.right;
let width = b.left - a.right;
let tHeight = a.top - b.top;
let tTop = tHeight / 2 + b.top;
let tAngle = Math.atan(tHeight / width) * 180 / Math.PI;
let bHeight = b.bottom - a.bottom;
let bTop = bHeight / 2 + a.bottom - bottomLine.offsetHeight;
let bAngle = Math.atan(bHeight / width) * 180 / Math.PI;
topLine.style.top = tTop + "px";
topLine.style.left = left + "px";
topLine.style.width = width + "px";
topLine.style.transform = "skewY("+(-tAngle)+"deg)";
bottomLine.style.top = bTop + "px";
bottomLine.style.left = left + "px";
bottomLine.style.width = width + "px";
bottomLine.style.transform = "skewY("+(bAngle)+"deg)";
}
updateLines();
Fiddle: https://jsfiddle.net/JacobDesight/f40yeuqe/2/
#EDIT
If you want trapeze with background then here is example using canvas: https://jsfiddle.net/JacobDesight/f40yeuqe/3/
This could be a starting point for you.
Code by thecodeplayer.
http://thecodeplayer.com/walkthrough/magnifying-glass-for-images-using-jquery-and-css3
$(document).ready(function() {
var native_width = 0;
var native_height = 0;
//Now the mousemove function
$(".magnify").mousemove(function(e) {
//When the user hovers on the image, the script will first calculate
//the native dimensions if they don't exist. Only after the native dimensions
//are available, the script will show the zoomed version.
if (!native_width && !native_height) {
//This will create a new image object with the same image as that in .small
//We cannot directly get the dimensions from .small because of the
//width specified to 200px in the html. To get the actual dimensions we have
//created this image object.
var image_object = new Image();
image_object.src = $(".small").attr("src");
//This code is wrapped in the .load function which is important.
//width and height of the object would return 0 if accessed before
//the image gets loaded.
native_width = image_object.width;
native_height = image_object.height;
} else {
//x/y coordinates of the mouse
//This is the position of .magnify with respect to the document.
var magnify_offset = $(this).offset();
//We will deduct the positions of .magnify from the mouse positions with
//respect to the document to get the mouse positions with respect to the
//container(.magnify)
var mx = e.pageX - magnify_offset.left;
var my = e.pageY - magnify_offset.top;
//Finally the code to fade out the glass if the mouse is outside the container
if (mx < $(this).width() && my < $(this).height() && mx > 0 && my > 0) {
$(".large").fadeIn(100);
} else {
$(".large").fadeOut(100);
}
if ($(".large").is(":visible")) {
//The background position of .large will be changed according to the position
//of the mouse over the .small image. So we will get the ratio of the pixel
//under the mouse pointer with respect to the image and use that to position the
//large image inside the magnifying glass
var rx = Math.round(mx / $(".small").width() * native_width - $(".large").width() / 2) * -1;
var ry = Math.round(my / $(".small").height() * native_height - $(".large").height() / 2) * -1;
var bgp = rx + "px " + ry + "px";
//Time to move the magnifying glass with the mouse
var px = mx - $(".large").width() / 2;
var py = my - $(".large").height() / 2;
//Now the glass moves with the mouse
//The logic is to deduct half of the glass's width and height from the
//mouse coordinates to place it with its center at the mouse coordinates
//If you hover on the image now, you should see the magnifying glass in action
$(".large").css({
left: px,
top: py,
backgroundPosition: bgp
});
}
}
})
})
/*Some CSS*/
* {
margin: 0;
padding: 0;
}
.magnify {
width: 200px;
margin: 50px auto;
position: relative;
}
/*Lets create the magnifying glass*/
.large {
width: 175px;
height: 175px;
position: absolute;
border-radius: 100%;
/*Multiple box shadows to achieve the glass effect*/
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
/*Lets load up the large image first*/
background: url('http://thecodeplayer.com/uploads/media/iphone.jpg') no-repeat;
/*hide the glass by default*/
display: none;
}
/*To solve overlap bug at the edges during magnification*/
.small {
display: block;
}
<!-- Lets make a simple image magnifier -->
<div class="magnify">
<!-- This is the magnifying glass which will contain the original/large version -->
<div class="large"></div>
<!-- This is the small image -->
<img class="small" src="http://thecodeplayer.com/uploads/media/iphone.jpg" width="200"/>
</div>
<!-- Lets load up prefixfree to handle CSS3 vendor prefixes -->
<script src="http://thecodeplayer.com/uploads/js/prefixfree.js" type="text/javascript"></script>
<!-- You can download it from http://leaverou.github.com/prefixfree/ -->
<!-- Time for jquery action -->
<script src="http://thecodeplayer.com/uploads/js/jquery-1.7.1.min.js" type="text/javascript"></script>

How to change color of text when entering fixed div using jQuery

I have a div with a background color that is fixed in the browser.
Scrolling through the site, I want the text color to change from black to white when it meets this overlay, then back to black again as it leaves it. This isn't really possible in css yet, so how can I set this in jQuery?
I'm using the ScrollTo plugin (http://flesler.blogspot.com/2007/10/jqueryscrollto.html) for my scrolling.
fiddle (css and html):
http://jsfiddle.net/L76NP/
html:
<body>
<div id="wrapper">
<div class="section">Section 1</div>
<div class="section">Section 2</div>
<div class="section">Section 3</div>
<div class="section">Section 4</div>
</div>
<div id="overlay"></div></body>
css:
body {color: #000000}
#wrapper { margin-left: auto;
margin-right: auto}
.section {
height: 300px;
width: 400px;
margin: 0 auto;
padding: 15px;}
#redbox {
background-color: #FF0000;
position: fixed;
top:100px;
bottom: 200px;
left: 0;
right: 0;
z-index: -100;}
Try this out:
http://jsfiddle.net/ALcm6/3/
Basically checking if the section fits within the box, and if so it's changing the text color. You can alter this for your specific needs.
$(window).scroll(function () {
var redbox = $("#redbox");
var redBoxTop = redbox.position().top;
var redBoxBottom = redBoxTop + redbox.outerHeight();
$(".section").each(function () {
var section = $(this);
var sectionTop = section.position().top - $(window).scrollTop() + 15;
var sectionBottom = section.position().top - $(window).scrollTop() + section.height();
if ((sectionTop >= redBoxTop && sectionTop <= redBoxBottom) || (sectionTop <= redBoxTop && sectionBottom >= redBoxBottom) || (sectionBottom >= redBoxTop && sectionBottom <= redBoxBottom)) {
section.css("color", "white");
} else {
section.css("color", "black");
}
});
});
$('#redbox').css('background-color','rgb(255,255,255)');//it's css controller
this is scroll event:
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
$('#redbox').css('background-color','rgb(255,255,255)');
} else {
$('#redbox').css('background-color','rgb(0,0,0)');
}
});
http://jsfiddle.net/LQ9QP/
it's a sample code And You can customize it.

Stretched background stopped working

I am working on an experimental art site that involves a grid of images each scaled to the size of the viewport. The background for the page body should be one stretched image and it was working at one point but has stopped functioning. The background color shows and the image simply doesn't. However if the background-size CSS is turned off in Chrome inspector it shows up at it's own size positioned top and left...
I am guessing that having body contain a box which amounts to 5 viewports wide and 5 viewports tall is messing with what the body element's size is? Though allowing bg image to repeat didn't make it show up...
I resolved this by grabbing the screen width and height in the JavaScript and then setting background-size to those values like so:
$('body,html').css('background-size',the_width + 'px ' + the_height+'px');
But my question remains- why did the background-size:100% 100% stop working?
The page HTML looks like this only with 25 total divs and images.
<body>
<div id="box">
<div class="full" id="full_10">
<img src="home_tiles/10.jpg" width="800" height="600" title="10">
</div>
<div class="full" id="full_11">
<img src="home_tiles/11.jpg" width="800" height="600" title="11">
</div>
</div>
</body>
The CSS looks like this
* { padding: 0; margin: 0; }
html, body {
overflow:hidden;
background-color: #FF0000;
background-size: 100% 100%;
background-image:url(home_tiles/edge.jpg);
background-repeat:no-repeat;
}
img { display: block; }
#box {
position:absolute;
}
.full {
float:left;
}
The JavaScript sizing the images is
$(function() {
$('.full').hide();
var win = $(window),
fullscreen = $('.full'),
image = fullscreen.find('img'),
imageWidth = image.width(),
imageHeight = image.height(),
imageRatio = imageWidth / imageHeight;
var the_width;
var the_height;
var left_limit;
var right_limit;
function resizeImage() {
var winWidth = win.width(),
winHeight = win.height(),
winRatio = winWidth / winHeight;
if(winRatio > imageRatio) {
the_width = winWidth;
the_height = Math.round(winWidth / imageRatio);
} else {
the_width = Math.round(winHeight * imageRatio);
the_height = winHeight;
}
left_limit = the_width * -2;
right_limit = the_width * 2;
image.css({
width: the_width,
height: the_height
});
$('#box').css({
width: the_width * 5,
height: the_height * 5,
top: the_height * -2,
left: the_width * -2
});
}
win.bind({
load: function() {
resizeImage();
$('.full').show('slow');
},
resize: function() {
resizeImage();
}
});

Categories