How to position green div under the red one? - javascript

Below is the demo code which fully represent the actual code
I've placed some content on the red div which I want users to see when the page loads. The problem is that I'm using scrollmagic.js animations on this page. Everything was working perfect but when I tried to use smoothscroll, The .setPin fuctions of scrollmagic stopped working. The animations are still working but the red div is being scrolled with the other divs. I want the red div to stay on it's place until the animation don't finish. The smoothscroll pushes the red div along the other divs before the animation completes.
Can you please help me placing green and blue div under the red one while the red div's position is fixed and stays responsive so that everything will work on all screen sizes?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test Code</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
</head>
<style>
.viewport {
overflow: hidden;
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.scroll-container {
position: absolute;
overflow: hidden;
z-index: 10;
display: flex;
justify-content: center;
backface-visibility: hidden;
transform-style: preserve-3d;
}
.div1 {
width: 70%;
height: 70vh;
border: 5px solid red;
position: fixed;
transform: translateX(20%);
}
.div2 {
width: 70%;
height: 70vh;
border: 5px solid green;
transform: translateX(20%);
}
.div3 {
width: 70%;
height: 70vh;
border: 5px solid blue;
transform: translateX(20%);
}
</style>
<body>
<div class="div1"></div>
<div class="viewport">
<div id="scroll-container">
<div class="div2"></div>
<div class="div3"></div>
</div>
</div>
</body>
<script>
var html = document.documentElement;
var body = document.body;
var scroller = {
target: document.querySelector("#scroll-container"),
ease: 0.05, // <= scroll speed
endY: 0,
y: 0,
resizeRequest: 1,
scrollRequest: 0,
};
var requestId = null;
TweenLite.set(scroller.target, {
rotation: 0.01,
force3D: true
});
window.addEventListener("load", onLoad);
function onLoad() {
updateScroller();
window.focus();
window.addEventListener("resize", onResize);
document.addEventListener("scroll", onScroll);
}
function updateScroller() {
var resized = scroller.resizeRequest > 0;
if (resized) {
var height = scroller.target.clientHeight;
body.style.height = height + "px";
scroller.resizeRequest = 0;
}
var scrollY = window.pageYOffset || html.scrollTop || body.scrollTop || 0;
scroller.endY = scrollY;
scroller.y += (scrollY - scroller.y) * scroller.ease;
if (Math.abs(scrollY - scroller.y) < 0.05 || resized) {
scroller.y = scrollY;
scroller.scrollRequest = 0;
}
TweenLite.set(scroller.target, {
y: -scroller.y
});
requestId = scroller.scrollRequest > 0 ? requestAnimationFrame(updateScroller) : null;
}
function onScroll() {
scroller.scrollRequest++;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
function onResize() {
scroller.resizeRequest++;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
</script>
</html>

Use z-index to place the red div above the other divs:
https://www.w3schools.com/cssref/pr_pos_z-index.asp
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test Code</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
</head>
<style>
.viewport {
overflow: hidden;
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.scroll-container {
position: absolute;
overflow: hidden;
z-index: 10;
display: flex;
justify-content: center;
backface-visibility: hidden;
transform-style: preserve-3d;
}
.div1 {
width: 70%;
height: 70vh;
border: 5px solid red;
position: fixed;
transform: translateX(20%);
z-index: 10;
}
.div2 {
width: 70%;
height: 70vh;
border: 5px solid green;
transform: translateX(20%);
}
.div3 {
width: 70%;
height: 70vh;
border: 5px solid blue;
transform: translateX(20%);
}
</style>
<body>
<div class="div1"></div>
<div class="viewport">
<div id="scroll-container">
<div class="div2"></div>
<div class="div3"></div>
</div>
</div>
</body>
<script>
var html = document.documentElement;
var body = document.body;
var scroller = {
target: document.querySelector("#scroll-container"),
ease: 0.05, // <= scroll speed
endY: 0,
y: 0,
resizeRequest: 1,
scrollRequest: 0,
};
var requestId = null;
TweenLite.set(scroller.target, {
rotation: 0.01,
force3D: true
});
window.addEventListener("load", onLoad);
function onLoad() {
updateScroller();
window.focus();
window.addEventListener("resize", onResize);
document.addEventListener("scroll", onScroll);
}
function updateScroller() {
var resized = scroller.resizeRequest > 0;
if (resized) {
var height = scroller.target.clientHeight;
body.style.height = height + "px";
scroller.resizeRequest = 0;
}
var scrollY = window.pageYOffset || html.scrollTop || body.scrollTop || 0;
scroller.endY = scrollY;
scroller.y += (scrollY - scroller.y) * scroller.ease;
if (Math.abs(scrollY - scroller.y) < 0.05 || resized) {
scroller.y = scrollY;
scroller.scrollRequest = 0;
}
TweenLite.set(scroller.target, {
y: -scroller.y
});
requestId = scroller.scrollRequest > 0 ? requestAnimationFrame(updateScroller) : null;
}
function onScroll() {
scroller.scrollRequest++;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
function onResize() {
scroller.resizeRequest++;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
</script>
</html>

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>

disable scrolling untill animation is done

I have a simple animation and I want to disable scrolling on the website
until this animation is done, it should be like a loader basically
UPDATE
thank you so much, but I have an issue with that sorry for not mention because I'm using a fixed position on a container to be fixed to do smooth scrolling, so when I use 'fixed' position for any element it doesn't seem to stick in the same place here is the full code
html
<main id="app">
<div id="scroll-container" class="scroll-container">
<div class="loader">
<div class="loader__block"></div>
</div>
</div>
</main>
CSS
body {
overflow-x: hidden;
overflow-y: scroll;
background: $bg-color;
user-select: none;
font-family: 'Platform Regular';
}
#app {
overflow: hidden;
position: fixed;
height: 100vh;
width: 100vw;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.scroll-container {
position: absolute;
overflow: hidden;
z-index: 10;
display: flex;
justify-content: center;
backface-visibility: hidden;
}
.loader {
width: 100vw;
height: 100vh;
position: absolute;
z-index: 999999;
overflow: hidden;
}
.loader__block {
position: absolute;
width: 0%;
height: 100vh;
background: #111111;
animation: go-left 4s cubic-bezier(.74, .06, .4, .92) forwards;
}
#keyframes go-left {
0% {
left: 0;
width: 0%;
}
50% {
left: 0;
width: 100%;
}
100% {
left: 100%;
width: 0;
}
these containers have a fixed position and overflow hidden because I'm making smooth page transition while scrolling and moving the 'y' position
here is also the js if it's going to help
function smoothScrolling() {
const html = document.documentElement;
const { body } = document;
const scroller = {
target: document.querySelector('#scroll-container'),
ease: 0.06, // <= scroll speed
endY: 0,
y: 0,
resizeRequest: 1,
scrollRequest: 0,
};
let requestId = null;
TweenLite.set(scroller.target, {
rotation: 0.01,
force3D: true,
});
function updateScroller() {
const resized = scroller.resizeRequest > 0;
if (resized) {
const height = scroller.target.clientHeight;
body.style.height = `${height}px`;
scroller.resizeRequest = 0;
}
const scrollY = window.pageYOffset || html.scrollTop || body.scrollTop || 0;
scroller.endY = scrollY;
scroller.y += (scrollY - scroller.y) * scroller.ease;
if (Math.abs(scrollY - scroller.y) < 0.05 || resized) {
scroller.y = scrollY;
scroller.scrollRequest = 0;
}
TweenLite.set(scroller.target, {
y: -scroller.y,
});
requestId = scroller.scrollRequest > 0 ? requestAnimationFrame(updateScroller) : null;
}
function onScroll() {
scroller.scrollRequest += 1;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
function onResize() {
scroller.resizeRequest += 1;
if (!requestId) {
requestId = requestAnimationFrame(updateScroller);
}
}
function onLoad() {
updateScroller();
window.focus();
window.addEventListener('resize', onResize);
document.addEventListener('scroll', onScroll);
}
window.addEventListener('load', onLoad);
}
Use the CSS rule position: fixed; on your div with class loader which makes it to always stay in the same place even if the page is scrolled.
as so:
.loader {
width: 100vw;
height: 100vh;
position: absolute;
z-index: 999999;
overflow: hidden;
position: fixed;
}
.loader__block {
position: absolute;
width: 0%;
height: 100vh;
background: #111111;
animation: go-left 4s cubic-bezier(.74, .06, .4, .92) forwards;
}
#keyframes go-left {
0% {
left: 0;
width: 0%;
}
50% {
left: 0;
width: 100%;
}
100% {
left: 100%;
width: 0;
}
}
<main id="app">
<div id="scroll-container" class="scroll-container">
<div class="loader">
<div class="loader__block"></div>
</div>
</div>

mousedown and touchstart not registering on mobile devices

I have created the following simple image comparison slider - modified from the version on w3schools (I know my mistake to use their code).
This all works fine on a desktop but when I try to use it on a mobile, nothing happens - it doesn't even register the console.log on the mousedown/touchstart (when I press on the slider button with my finger).
I was wondering if anyone could spot anything obvious with why it isn't working on mobile devices
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
// calculate the cursor's x coordinate, relative to the image
return thisEvent.pageX - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
/*set the appearance of the slider:*/
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
transform: translate(-50%, -50%);
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>
Fiddle link for code
Ok have managed to fix this - the touch wasn't registering because of the transform so I changed that and just used negative margin as the button was a fixed size.
I then had to fix the thisEvent.pageX for android - so did a check with isNaN and then set it to e.originalEvent.touches[0].pageX if it was true.
Working version:
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
let xVal = thisEvent.pageX;
if (isNaN(xVal)) {
xVal = e.originalEvent.touches[0].pageX;
}
// calculate the cursor's x coordinate, relative to the image
return xVal - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: -25px 0 0 -25px;
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>

Skrollr image flickers and some images doesnt load in chrome

I am using Skrollr librabry. In the start it works fine,but as I'm scrolling down,I am experiencing flickering and images do not load. The content of my website are just images. Works fine on firefox, but not on Chrome. Could you please help me. I am using approximately 190 images. Is that an issue?
I am using async calls to fetch the data,and every image is being loaded before the skrollr is rendered.
Here's my working example : https://jsfiddle.net/if_true/v1mLhutc/7/
html
<body>
<div id="fakeloader"></div>
<div style="transform: translate3d(0,0,0);"></div>
<div class="DESKScreen">
<div id="info" hidden="hidden">0</div>
<section id="slide">
<div class="bcg"></div>
</section>
</div>
</body>
CSS
*,:before,:after {
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
-webkit-backface-visibility:hidden;
backface-visibility: hidden;
}
#info{
position: fixed;
top: 20px;
left: 20px;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 20px;
z-index: 9999;
}
body {
margin: 0;
width: 100%;
height: 100%;
}
html{
width: 100%;
height: 100%;
}
section {
width: 100%;
max-width: 100%;
height: 100%;
position: fixed;
left: 0;
right: 0;
margin: auto;
}
#slide .bcg {
height: 100%;
width: 100%;
background-size: 100%;
background-position: center top;
background-attachment: fixed;
position: absolute;
transform:translateZ(0)
}
.img{
background-size: cover;
background-repeat: no-repeat;
background-position: center;
display: table;
margin: auto;
max-height: 100vh !important;
height: 100% !important;
}
.item {
width: 100%;
position: absolute;
opacity: 1;
}
`Js`
$(document).ready(function() {
DivImage("sup");
var s = skrollr.init({
render: function(data) {
console.log(data.curTop);
}
});
//Check the screen size.
(function() {
if (screen.width < 768) {
$("#fullpage").fullpage({
//scrollingSpeed: 0,
});
$(".DESKScreen").css("display", "none");
} else if (screen.width > 768) {
$(".MObileScreen").css("display", "none");
}
})();
//Fakeloader for the loadtime
function loader() {
$("#fakeloader").fakeLoader({
timeToHide: 4000,
bgColor: "#e74c3c",
spinner: "spinner2"
});
}
loader();
});
function DivImage(name) {
//console.log(name);
//a counter to set for div id
let counter = 0;
//create the urls based on a nr
var Images = makeUrls();
//first create the div and pass the counter to it
CreateDiv(Images);
}
function makeUrls() {
let base = "images/";
let rest = ".jpg";
let result = [];
for (let i = 0; i < 191; i++) {
let baseNr = 1 + i;
if (baseNr === 2000) {
console.log("base");
} else {
result.push(base + baseNr + rest);
}
}
return result;
}
function CreateDiv(images) {
// debugger;
var from = 0,
to = 0;
let result = [];
for (let i of images) {
var newDiv = $('<div class="img-div"></div>');
newDiv.css({
backgroundImage: `url(${i})`
});
newDiv.attr("data--" + from + "-top", "opacity: 0;");
from += 125;
newDiv.attr("data--" + from + "-top", "opacity: 0;");
from += 125;
newDiv.attr("data--" + from + "-top", "opacity: 1;");
newDiv.attr("data-anchor-target", "#slide");
newDiv.attr("data-skrollr-decks-speed", "300");
$("#slide").append($(newDiv));
}
}

Keep parallax moving for one second on mouseout and stop smoothly

I would like to make a website with mouse parallax effect like in this page http://brightmedia.pl background mouse parallax is so smooth..
I have two questions:
When you mouseover on a container from, let's say, the top left corner, the image jumps. How can I make a smooth animation?
When you mouseout of a container, how can I make the image move a little bit and stop with a smooth animation?
What would code to solve these problems be?
Here is basic code:
$('.container').mousemove( function(e){
var xPos = e.pageX;
var yPos = e.pageY;
$('#par1').css({marginLeft: -xPos/20});
});
.container {
position: relative;
width: 100%;
height: 800px;
background: grey;
overflow: hidden;
margin: 0 auto;
}
.container img {
width: 110%;
height: 100vh;
position: absolute;
}
body{
height: 1000px;
}
h1{
font-size: 60px;
z-index: 10;
position: absolute;
left: 50%;
top: 30%;
transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="css.css">
</head>
<body>
<div class="container" id="container">
<img id="par1" src="https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg" alt="">
<h1>TEXT</h1>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
As I had solved the problem long time ago and I forgot about this post so I decided to update with the answer. Maybe it will be helpful for anyone else.
Problem solved by using GSAP. Below You can see the code that works exactly as I wanted
let wrap = document.getElementById('container');
let request = null;
let mouse = { x: 0, y: 0 };
let cx = window.innerWidth / 2;
let cy = window.innerHeight / 2;
document.querySelector('.container').addEventListener('mousemove', function(event) {
mouse.x = event.pageX;
mouse.y = event.pageY;
cancelAnimationFrame(request);
request = requestAnimationFrame(update);
});
function update() {
dx = mouse.x - cx;
dy = mouse.y - cy;
let tiltx = (dy / cy );
let tilty = - (dx / cx);
TweenMax.to("#container img", 1, {x:-tilty*20, y:-tiltx*20, rotation:0.01, ease:Power2.easeOut});
}
window.addEventListener('resize', function(event){
window.innerWidth / 2;
window.innerHeight / 2;
});
* {
margin:0;
padding:0;
box-sizing:border-box;
}
.container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
}
.container img {
width: 110%;
height: 120vh;
position: absolute;
}
h1 {
z-index:100;
font-size: 6rem;
z-index: 10;
color:#333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<div class="container" id="container">
<img id="par1" src="https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg" alt="">
<h1>GSAP Mouse Parallax</h1>
</div>
You can rely one mouseenter / mouseleave to add animation:
$('.container').mousemove(function(e) {
var xPos = e.pageX;
var yPos = e.pageY;
$('#par1').css({
marginLeft: -xPos / 10
});
});
$('.container').mouseenter(function(e) {
var xPos = e.pageX;
var yPos = e.pageY;
$('#par1').animate({
"marginLeft": -xPos / 10
}, "slow");
});
$('.container').mouseleave(function(e) {
$('#par1').animate({
"marginLeft": "0"
}, "slow");
});
.container {
position: relative;
width: 100%;
height: 800px;
background: grey;
overflow: hidden;
margin: 0 auto;
}
.container img {
width: 110%;
height: 100vh;
position: absolute;
}
body {
height: 1000px;
}
h1 {
font-size: 60px;
z-index: 10;
position: absolute;
left: 50%;
top: 30%;
transform: translate(-50%, -50%);
}
<div class="container" id="container">
<img id="par1" src="https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg" alt="">
<h1>TEXT</h1>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
As Temani said, playing with transition and eventually delay should do the job.
For 1st question: transition seems appropriate, associated with a mousein listener. Or even better, use the $(element).animate() function that allows to set the animation duration. That way, you don't set any value for transition duration.
For 2nd question: listener on mouseout > same process, but shorter animation (for the img shifting as well as the animation duration).
This should also give you some ideas:
https://codepen.io/Aldlevine/pen/Jowke
Based on Teemani below code example:
$('.container').mousemove(function(e) {
var xPos = e.pageX;
var yPos = e.pageY;
$('#par1').css("margin-left", -xPos / 10);
});
$('.container').mouseenter(function(e) {
var xPos = e.pageX;
var yPos = e.pageY;
$('#par1').css("margin-left", -xPos / 10);
});
$('.container').mouseleave(function(e) {
$('#par1').css({"transition": "margin-left 1s ease-in-out", "margin-left": "0"});
setTimeout( function() {
$('#par1').css("transition", "initial");
}, 500);
});
.container {
position: relative;
width: 100%;
height: 800px;
background: grey;
overflow: hidden;
margin: 0 auto;
}
.container img {
width: 110%;
height: 100vh;
position: absolute;
transition: margin-left 0.2s;
/* transition: margin-left 0.2s ease-in-out 0.2s;*/
}
body {
height: 1000px;
}
h1 {
font-size: 60px;
z-index: 10;
position: absolute;
left: 50%;
top: 30%;
transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container" id="container">
<img id="par1" src="https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg" alt="">
<h1>TEXT</h1>
</div>

Categories

Resources