Parallax images issue in firefox - javascript

I'm doing a project with parallaxing 3 images based on the mouse movement.
In Chrome and internet explorer it works fine but my problem is firefox!
The parallax mouse movement effect doesnt work like it should for firefox, how can I solve the problem. firefox makes the effect only work up and down movement like if you scroll automatically with the mouse. The effect should rather be like it moves with the mouse like if the mouse is a camera in 3D space.
$(document).ready(function() {
var movementStrength = 15;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("#logo-image").mousemove(function(e) {
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 25;
var newvalueY = height * pageY * -1 - 50;
$('#logo-image').css("background-position", newvalueX + "px " + newvalueY + "px");
});
});
$(document).ready(function() {
var movementStrength = 10;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("#mos").mousemove(function(e) {
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 25;
var newvalueY = height * pageY * -1 - 50;
$('#mos').css("background-position", newvalueX + "px " + newvalueY + "px");
});
});
$(document).ready(function() {
var movementStrength = 5;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("#bottom-image").mousemove(function(e) {
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 25;
var newvalueY = height * pageY * -1 - 50;
$('#bottom-image').css("background-position", newvalueX + "px " + newvalueY + "px");
});
});
#bottom-image {
background: url('bgpalms.jpg') -25px -50px;
display: block;
position: fixed;
background-repeat: no-repeat;
top: 0;
width: 100%;
z-index: 0;
height: 100%;
background-size: calc(100% + 50px);
}
#logo-image {
background: url('palms_kungen_1.png') -25px -50px;
margin: 0 auto 0 auto;
background-repeat: no-repeat;
top: 0;
width: 50%;
z-index: 0;
height: 100%;
background-size: calc(100% + 50px);
}
#mos {
background: url('mos.png') -25px -50px;
/*margin: 0 auto 0 auto;*/
display: block;
position: fixed;
background-repeat: no-repeat;
top: 0;
width: 100%;
z-index: 0;
height: 100%;
background-size: calc(100% + 50px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="bottom-image">
<div id="mos">
<div id="logo-image"></div>
</div>
</div>

Related

How to switch between transform-origin and scrollbars

I have this code above who switch between CSS transform-origin and scale to CSS width and scrollbars.
I need to make this switch because I am having a pinch to zoom for a DIV wrap I'm using in my website.
I'm using CSS translateX and translateY and Scale for a smoother pinch zoom, but after the zoom take place, I need to return back to width and scrollbar so the user can move across the layout.
I have here an example of how I'm doing the switch and there is a bit margin on top that I can't really set mind my on.
what is the correct way to do so?
var isOrigin = false;
var originX = 500;
var originY = 200;
var scale = 1.5;
var deltaX = 0;
var deltaY = 0;
var from_origin_to_scroll = function () {
if (isOrigin) { from_scroll_to_origin(); return; }
var wrap = $('.containter .wrap');
//reset scroll
const el = document.scrollingElement || document.documentElement;
$('.containter')[0].scrollLeft = 0;
el.scrollTop = 0;
wrap.css({
transformOrigin: originX + "px " + originY + "px",
transform: "translate3d(" + deltaX + "px," + deltaY + "px, 0) " +
"scale3d(" + scale + "," + scale + ", 1) ",
width: 100 + '%'
});
isOrigin = true;
$('.info').html('layout set by origin and scale');
}
var from_scroll_to_origin = function () {
var wrap = $('.containter .wrap');
wrap.css({
transformOrigin: originX + "px " + originY + "px",
transform: "translate3d(" + 0 + "px," + 0 + "px, 0) " +
"scale3d(" + 1 + "," + 1 + ", 1) ",
width: (100 * scale) + '%'
});
$('.containter')[0].scrollLeft = originX * (scale - 1);
const el = document.scrollingElement || document.documentElement;
el.scrollTop = originY * (scale - 1);
isOrigin = false;
$('.info').html('layout set by width and scroll');
}
body {
margin: 0;
padding: 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
width:100vw;
}
.top{
position: fixed;
width: 100%;
background-color: #333;
line-height: 40pt;
text-align: center;
color: #f1f1f1;
font-size: 20pt;
left: 0;
top: 0;
z-index: 10;
}
.top .info{
}
.header_content
{
background-color: #e1e1e1;
line-height:130pt;
}
.containter {
width:100%;
box-sizing: border-box;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.containter .wrap {
display: flex;
flex-direction: column;
width: 100%;
}
.containter .wrap img {
width: 100%;
margin-top: 30pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top">
<div class="info" onclick="from_origin_to_scroll()">click to switch</div>
</div>
<div class="header_content">
this is a header content - needs to be added to overall calculation
</div>
<div class="containter">
<div class="wrap">
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
<img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
</div>
</div>
In your case the possible solution is to detect when the user is trying to zoom, and when just to scroll.
const $container = $(".container");
$container.on('touchstart', function (e) {
if (e.touches.length > 1){
//more than one finger is detected on the screen,
//change mode to transform-origin
from_scroll_to_origin()
}
});
$container.on('touchend', function (e) {
//change mode to scrollbars
from_origin_to_scroll()
});

Background zooms in incorrectly when following mouse movement

I've created a button, when you hover over it a div with a background image enlarges. The background should follow the cursor's movements. Meaning that the background image follows your cursor as you hover over the button.
When I hover over the bottom right part of the button, the image will zoom in to the top left before moving to the cursor's location. Check out the example below to see what I mean. I'd like to make it zoom directly to the cursor's location, any ideas?
var imgZoomIn = 1.2; //% of how much the image will enlarge
function buttonImgResize(x, e){
//Location of the cursor (as percentage of the container's size)
var imgContPosition = x.getBoundingClientRect();
var mousePosX = (e.clientX - imgContPosition.left) / x.offsetWidth;
var mousePosY = (e.clientY - imgContPosition.top) / x.offsetHeight;
//Finding how far to move the image from top and left
var leftImgOverlap = x.offsetWidth * (imgZoomIn - 1) * mousePosX;
var topImgOverlap = x.offsetHeight * (imgZoomIn - 1) * mousePosY;
//implementing changes
x.firstElementChild.style.left = 0 - leftImgOverlap + "px";
x.firstElementChild.style.top = 0 - topImgOverlap + "px";
}
//Reseting values
function buttonImgDownsize(x){
x.firstElementChild.style.left = "0";
x.firstElementChild.style.top = "0";
}
/*Container*/
.showCaseBtn{
overflow: hidden;
position: relative;
width: 500px; height: 300px;
}
/*div with background image*/
.showcaseBtn_Back{
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
background: black no-repeat center center / cover;
transition: 0.4s;
}
.showCaseBtn:hover .showcaseBtn_Back{
height: 120%; width: 120%;
}
<div class="showCaseBtn" onmousemove="buttonImgResize(this, event)" onmouseout="buttonImgDownsize(this)">
<div class="showcaseBtn_Back" style="background-image: url(https://media.contentapi.ea.com/content/dam/need-for-speed/common/2017/10/nfs-payback-jaguar-f-type-2x.jpg.adapt.1920w.jpg);"></div>
</div>
The problem is caused by the css transition. If you remove it, the zooming works but no fancy scaling will happen.
var imgZoomIn = 1.2;
function buttonImgResize(x, e){
var imgContPosition = x.getBoundingClientRect();
var mousePosX = (e.clientX - imgContPosition.left) / imgContPosition.width;
var mousePosY = (e.clientY - imgContPosition.top) / imgContPosition.height;
var leftImgOverlap = imgContPosition.width * (imgZoomIn - 1) * mousePosX;
var topImgOverlap = imgContPosition.height * (imgZoomIn - 1) * mousePosY;
x.firstElementChild.style.left = - leftImgOverlap + "px";
x.firstElementChild.style.top = - topImgOverlap + "px";
}
function buttonImgDownsize(x){
x.firstElementChild.style.left = "0";
x.firstElementChild.style.top = "0";
}
.showCaseBtn{
overflow: hidden;
position: relative;
width: 500px; height: 300px;
}
.showcaseBtn_Back{
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
background: black no-repeat center center / cover;
}
.showCaseBtn:hover .showcaseBtn_Back{
height: 120%; width: 120%;
}
<div class="showCaseBtn" onmousemove="buttonImgResize(this, event)" onmouseout="buttonImgDownsize(this)">
<div class="showcaseBtn_Back" style="background-image: url(https://media.contentapi.ea.com/content/dam/need-for-speed/common/2017/10/nfs-payback-jaguar-f-type-2x.jpg.adapt.1920w.jpg);"></div>
</div>

How can I smoothly move layers from one position to another when the mouse leaves and enter the window?

I am refining a parallax effect trying to create a smooth transition between two positions using where the mouse leaves and enters the window. If you notice the JSFiddle has a 'pop' that I want to replace with the transition. How can I do that?
$(document).ready(function() {
$('#layer-one').mousemove(function(e) {
parallax(e, this, 1);
parallax(e, document.getElementById('layer-two'), 2);
parallax(e, document.getElementById('layer-three'), 3);
});
});
function parallax(e, target, layer) {
var layer_coeff = 10 / layer;
var x = ($(window).width() - target.offsetWidth) / 2 - (e.pageX - ($(window).width() / 2)) / layer_coeff;
var y = ($(window).height() - target.offsetHeight) / 2 - (e.pageY - ($(window).height() / 2)) / layer_coeff;
$(target).offset({
top: y,
left: x
});
};
JSFiddle
Thank you in advance.
Perhaps, you can use GSAP libraries to make that offset effect smoother, this is just a fast example, give it a try:
var initPos = $('#layer-one').position();
$(document).ready(function() {
$('#layer-one').mousemove(function(e) {
parallax(e, this, 1);
parallax(e, document.getElementById('layer-two'), 2);
parallax(e, document.getElementById('layer-three'), 3);
});
});
function parallax(e, target, layer) {
var layer_coeff = 10 / layer;
var x = ($(window).width() - target.offsetWidth) / 2 - (e.pageX - ($(window).width() / 2)) / layer_coeff;
var y = ($(window).height() - target.offsetHeight) / 2 - (e.pageY - ($(window).height() / 2)) / layer_coeff;
/*$(target).offset({
top: y,
left: x
});*/
TweenLite.to($(target), 2, {x:x, y:y});
};
document.onmouseleave = function() {
$("#layer-one").animate({
opacity: 0.4,
left: 10,
}, 'fast');
};
.layer {
padding: 20px;
color: white;
}
#base-layer {
overflow: hidden;
}
#layer-one {
background: red;
}
#layer-two {
background: green;
}
#layer-three {
background: blue;
}
.slider {
margin-left: auto;
margin-right: auto;
overflow: hidden;
padding-top: 200px;
}
.slider img {
width: 80%;
padding-left: 10%;
padding-right: 10%;
height: auto;
margin-left: auto;
margin-right: auto;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenLite.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/easing/EasePack.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/plugins/CSSPlugin.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="base-layer">
<div id="layer-one" class="layer">
Content
<div id="layer-two" class="layer">
Content
<div id="layer-three" class="layer">
Content
<section class="slider">
<img src="http://i.imgur.com/fVWomWz.png">
</section>
</div>
</div>
</div>
</div>

JavaScript: Zooming does works as intended

I suck at math so I cannot figure out what is required to make the zooming work properly. You see, when clicked for the first time, it works as intended (it zooms in to the desired position). But if you try to click more than once it won't zoom in to the desired position.
Here's the code (also provided at http://jsfiddle.net/XVmNU/)
<!DOCTYPE HTML>
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
overflow: hidden;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
(function ($) {
var scale = 1;
$(window).load(function () {
$('img:first').click(function (e) {
scale *= 1.5;
var w = $(this).width(),
h = $(this).height();
var new_w = w * scale,
new_h = h * scale;
var x = e.pageX,
y = e.pageY;
var new_x = Math.round(x / (w / new_w)),
new_y = Math.round(y / (h / new_h));
new_x = (0 - (new_x - x)),
new_y = (0 - (new_y - y));
$(this).animate({
left: new_x,
top: new_y,
width : new_w,
height : new_h
}, 'fast');
});
});
})(jQuery);
</script>
</head>
<body>
<img src="http://www.worldpress.org/images/maps/world_600w.jpg" style="position: absolute; left: 0px; top: 0px;"/>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
overflow: hidden;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
(function ($) {
var scale = 1;
$(window).load(function () {
$('img:first').click(function (e) {
scale *= 1.5;
var w = $(this).width(),
h = $(this).height();
var new_w = w * scale,
new_h = h * scale;
var x = e.pageX,
y = e.pageY;
var new_x=Math.round([x-($(this).position().left)]*(1-scale)+$(this).position().left),
new_y=Math.round([y-($(this).position().top)]*(1-scale)+$(this).position().top);
$(this).animate({
left: new_x,
top: new_y,
width : new_w,
height : new_h
}, 'fast');
});
});
})(jQuery);
</script>
</head>
<body>
<img src="http://www.worldpress.org/images/maps/world_600w.jpg" style="position: absolute; left: 0px; top: 0px;"/>
</body>
</html>
is is something wrong with your method to compute the new_x and new_y.

track mouse position to move images

I have a pretty simple page.
<div id="index">
<img />
</div>
the styling is pretty simple too.
#index {position:relative;}
#index img {position:absolute; bottom:10%; right:10%; width:100%;}
I use % so the image can be resized proportionally if the browser window resizes. Never mind that.
The problem is, I'm trying to emulate the effect on this flash site : http://www.tatogomez.com/ So the image is in the bottom right of the screen. When I move my mouse to top left, the image will slightly move a bit more to the right bottom. When I move my mouse to center, the image will revert back to its original position. So it's kinda like I'm giving a shadow/lighting effect where the mouse is the lighting and the image is the object, except I only need the moving animation.
my code is like this
$(document).ready(function($){
$('#index').mousemove(
function(e){
$(this).children('img').each(
function(){
var totalWidth = $(window).width();
var totalHeight = $(window).height();
var centerX = $(window).width() / 2;
var centerY = $(window).height() / 2;
var mouseX = e.pageX;
var mouseY = e.pageY;
var current_top = $(this).offset().top;
var current_left = $(this).offset().left;
var myX = (centerX-mouseX)/centerX;
var myY = (centerY-mouseY)/centerY;
var cssObj = {
'left': current_left + myX + 'px'
'top': current_top + myY + 'px'
}
$(this).css(cssObj);
}
);
}
);
});
so if I move the mouse in relation to the center of the screen. So basically it's like this:
centerX = 700 (i use resolution 1400);
currentLeft = ~200 (the offset left of my image)
So if my mouse position is at 700-1400, then the myX will be 700(centerX) - 900(mouse position) = -200 / 700 = ~ -0.3. Add it into the css calculation, the left will be current_left(200) + myX(-0.3) px = 197.7px.
then i realizes if i move my mouse from the center to the right (700-1400 range), the image will slightly move to the left, but when I move my mouse from the right to the center, the image still moves to the left! It should move to the right to its original position, but it doesn't because the web doesn't know whether the mouse moves from right to center or from center to right.
Any help?
I toyed with it quickly, it's lacking the looping through images with .each but might help you with the mouse movement calculations. Rather than being hardcoded, the movement divider should probably be based on the z-index, since lower z-index items move more.
In this demo, initial placement is incorrect until you mouse over.
Demo here: http://jquerydoodles.com/stack_question.html
Hope that helps!
CSS:
#index { position: relative; border: 2px solid #ccc; height: 400px; }
#index img { position: absolute; background-color: #fff; border: 1px solid #666; padding: 6px; }
#image1 { z-index: 3; }
#image2 { z-index: 2; width: 150px; left: 200px; }
#image3 { z-index: 1; width: 100px; left: 300px; }
#image4 { z-index: 2; width: 150px; left: -200px; }
#image5 { z-index: 1; width: 100px; left: -300px; }
HTML
<div id="index">
<img src="http://farm6.static.flickr.com/5138/5421580531_424e84d4cf_m.jpg" id="image1" alt="" />
<img src="http://farm6.static.flickr.com/5138/5421580531_424e84d4cf_m.jpg" id="image2" alt="" />
<img src="http://farm6.static.flickr.com/5138/5421580531_424e84d4cf_m.jpg" id="image3" alt="" />
<img src="http://farm6.static.flickr.com/5138/5421580531_424e84d4cf_m.jpg" id="image4" alt="" />
<img src="http://farm6.static.flickr.com/5138/5421580531_424e84d4cf_m.jpg" id="image5" alt="" />
</div>
JQUERY:
$(document).ready(function($){
$("#index").mousemove(function(e){
var mouseX = e.pageX - $('#index').offset().left;
var mouseY = e.pageY - $('#index').offset().top;
var totalX = $('#index').width();
var totalY = $('#index').height();
var centerX = totalX / 2;
var centerY = totalY / 2;
var shiftX = centerX - mouseX;
var shiftY = centerY - mouseY;
var startX = ($('#index').width() / 2) - ($('#image1').width() / 2);
var startY = ($('#index').height() / 2) - ($('#image1').height() / 2);
$('#image1').css('z-index') ;
$('#image1').css({ 'left': startX + (shiftX/10) + 'px', 'top': startY + (shiftY/10) + 'px' });
$('#image2').css({ 'left': startX + 220 + (shiftX/8) + 'px', 'top': startY + 50 + (shiftY/8) + 'px' });
$('#image3').css({ 'left': startX + 370 + (shiftX/6) + 'px', 'top': startY + 60 + (shiftY/6) + 'px' });
$('#image4').css({ 'left': startX - 100 + (shiftX/8) + 'px', 'top': startY + 50 + (shiftY/8) + 'px' });
$('#image5').css({ 'left': startX - 150 + (shiftX/6) + 'px', 'top': startY + 60 + (shiftY/6) + 'px' });
});
});

Categories

Resources