1

Consider two container elements side by side, both of them are longer than the width of the viewport and the viewport is scrollable horizontally. Both of them contain an element inside that I want to keep in the center of visible portion of the containing div. Here is the markup:

<body>
    <div class="wrapper">
        <div class="container" id="container1">
            <div class="element" id="element1"></div>
        </div>
        <div class="container" id="container2">
            <div class="element" id="element2"></div>
        </div>
    </div>
</body>

and here is the css:

body {
    overflow-x: auto;
}
.wrapper {
    width: 400%;
}
.container {
    width: 50%;
    border: 1px solid #ccc;
    height: 50px;
    float: left;
}

I am very sorry I find it very difficult to describe what I need since English is not my native language but I would like to describe it with an image and an animation:

[The effect I want to achieve in steps2 [The effect I want to achieve in animated gif form]1

G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
user3356048
  • 87
  • 1
  • 2
  • 9
  • 1
    Welcome to SO. Your English is very good, but you need to show your attempt (markup). Please see the help pages. – isherwood Apr 26 '16 at 20:59
  • Did you tried any code? – Riot Zeast Captain Apr 26 '16 at 21:26
  • its difficult to understand what you want exactly an horizontal animation or scroll ? – Erick Boileau Apr 26 '16 at 21:27
  • I think using mouse event and position of the container, with some mathematical operations we can assign a margin-left/left to the element inside of the container by limiting the margin or left value, which should not exceed some value. Note: Its an Idea only, but I think it will work. – Riot Zeast Captain Apr 26 '16 at 21:31
  • I have added the markup and the poor css code (which is only to give the basic idea) I want div.element to stay in the center of the viewport as long as its parent (div.container) is visible at all. But when the visible portion of div.container is less than the width of viewport, then I want the element centered in this visible portion. It is really hard to explain, I am sorry again :( – user3356048 Apr 26 '16 at 21:34

3 Answers3

2

Here is what you want.

Gift: check out the prettier meoww version.

$(".parallax").on("scroll", function() {
    var scrollValue = $(this).scrollLeft();
    var parallaxWidth = $(this).width();

    $(".box").each(function() {
        var container = $(this).parent();
        var containerWidth = $(container).width();
        var isLeftBox = $(container).is("#left");
        var ratioParallax = parallaxWidth/containerWidth;
        var ratioScroll = scrollValue/containerWidth;

        var move = 50*ratioParallax;

        if (isLeftBox) {
            move += ratioScroll*100;

            if (ratioScroll > 1/3)
                move -= (ratioScroll-1/3)*50;
        } else {
            move += (ratioScroll-1)*100;

            if (ratioScroll < 1)
                move -= (ratioScroll-1)*50;
        }

        $(this).css("left", move+"%");
    });
});

$(".parallax").trigger("scroll");
div.parallax {
    height:200px;
    width:400px;
    overflow-x:scroll;
    overflow-y:visible;
}
div.parent-container {
    height:100%;
    width:300%;
}
div.container {
    width:50%;
    height:100%;
    float:left;
    overflow:hidden;
}
body div.container#left {
    background-color:red;
}
body div.container#right {
    background-color:blue;
}
div.box {
    height:50px;
    width:50px;
    margin-top:-25px;
    margin-left:-25px;
    background-color:yellow;
    position:relative;
    top:50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax">
    <div class="parent-container">
        <div id="left" class="container">
            <div class="box"></div>
        </div>
        <div id="right" class="container">
            <div class="box"></div>
        </div>
    </div>
</div>
Jules Lamur
  • 2,078
  • 1
  • 15
  • 25
0

The concept you're describing is called parallax and can be a bit involved to accomplish exactly right. Here's an example: http://stephband.info/jparallax/

Have you tried any solutions yet?

johnniebenson
  • 540
  • 3
  • 9
0

I have made a simple version with JavaScript. I don't if it works on every browser. I know for sure that it works on Safari and Firefox. It's very laggy, but it's possible fix that.

var pageWidth;
var marginLeft1;
var marginLeft2 = margin;
var box1 = document.getElementById('box11');
var box2 = document.getElementById('box22');
var boxWidth = 200;
var largeBoxWidth = 2459;
var margin = 50;

function scrollY(Yscroll) {
 pageWidth = window.innerWidth;
 
 if(Yscroll + pageWidth < largeBoxWidth) {
  marginLeft1 = (pageWidth - boxWidth) / 2 + Yscroll;
 } else if(largeBoxWidth - Yscroll > 2*margin + boxWidth) {
  marginLeft1 = (pageWidth -  (Yscroll + pageWidth - largeBoxWidth)) / 2 + Yscroll - 0.5 * boxWidth;
 }
 
 if(Yscroll + pageWidth - largeBoxWidth < 2*margin + boxWidth) {
  marginLeft2 = margin;
 } else if(Yscroll + pageWidth <= largeBoxWidth) {
  marginLeft2 = (Yscroll + pageWidth - largeBoxWidth) / 2 - 0.5 * boxWidth;
 } else if(2*largeBoxWidth - Yscroll > pageWidth) {
  marginLeft2 = (Yscroll - largeBoxWidth) + 0.5*pageWidth - 0.5 * boxWidth;
 } else if(2*largeBoxWidth - Yscroll > 2*margin + boxWidth) {
  marginLeft2 = (Yscroll - largeBoxWidth) + (2*largeBoxWidth - Yscroll) / 2 - 0.5 * boxWidth;
 }
 
 
 if(Yscroll + pageWidth - largeBoxWidth > 2*margin + boxWidth && Yscroll - largeBoxWidth < 0) {
  marginLeft2 = (Yscroll + pageWidth - largeBoxWidth) / 2 - 0.5*boxWidth;
 }
 
 box2.style.marginLeft = marginLeft2 + 'px';
 box1.style.marginLeft = marginLeft1 + 'px';
}

scrollY(document.body.scrollLeft);
body {
 margin:0;
 padding:0;
}

#wrap {
 height:200px;
 width:6148px;
}

#box1 {
 width:40%;
 height:100px;
 background-color:#FFDDDD;
 padding:50px 0;
 display:inline-block;
}

#box11 {
 width:200px;
 height:100px;
 background-color:#FF0000;
}


#box2 {
 width:40%;
 height:100px;
 background-color:#DDFFDD;
 padding:50px 0;
 display:inline-block;
 margin-left:-4px;
}

#box22 {
 width:200px;
 height:100px;
 background-color:#00FF00;
}
<body onscroll='scrollY(document.body.scrollLeft)'>
  <div id='wrap'>
    <div id='box1'>
      <div id='box11'></div>   
    </div>
  
    <div id='box2'>
      <div id='box22'></div>
    </div>
  </div>
</body>
user3722860
  • 189
  • 1
  • 3
  • 11