Maximum scale in the middle instead of the end

In the next snippet, I try to achieve an effect where div, which appears in the middle of the visible scroll section, is in full scale scale(1);, and the other div scale is reduced to scale(0);as we approach the edges.

I drew a debug in the middle where the full scale should appear.

var viewport = {
  x: $("#scroll").scrollLeft(),
  width: $("#scroll").width(),
}

$("#scroll").scroll(function() {
  viewport.x = $("#scroll").scrollLeft();
  recalculateScale();
});

recalculateScale();

function recalculateScale() {
  $("#example > div").each(function() {
    let middleOfThis = ($(this).position().left + ($(this).width() * 0.5)); // calculate from the middle of each div
    let scale = Math.sin(middleOfThis / $("content").width());

    $(this).css('transform', 'scale(' + scale + ')');
  });
}
content {
  position: relative;
  display: block;
  width: 500px;
  height: 100px;
}

content::after {
  content: '';
  position: absolute;
  display: block;
  width: 20%;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}

#scroll {
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  border: 1px solid #000;
}

#example {
  display: block;
  width: 200%;
  height: 100%;
  font-size: 0;
  overflow: none;
}

#example>div {
  display: inline-block;
  width: 10%;
  height: 100%;
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<content>
  <div id="scroll">
    <section id="example">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </section>
  </div>
</content>
Run codeHide result

Currently, the scale is spreading from left to right #example. I know that I need to determine the sizes of the viewports in the equation before being evaluated Math.sin, I just can't get it right.


Note. there is no arrow function because I need to target IE11.

+4
1

:

  • .position().left , .width() . , . .getBoundingClientRect().width:

  • , , . 0 1, 0,5, π/2. π, .

:

var viewport = {
  x: $("#scroll").scrollLeft(),
  width: $("#scroll").width(),
}

$("#scroll").scroll(function() {
  viewport.x = $("#scroll").scrollLeft();
  recalculateScale();
});

recalculateScale();

function recalculateScale() {
  $("#example > div").each(function() {
    // 1. Use different way to read the width: this will give the rendered width 
    // after scaling, just like the left position will be the actually rendered 
    // position after scaling:
    let middleOfThis = $(this).position().left 
                     + this.getBoundingClientRect().width * 0.5; 
    // 2. Convert fraction to a number of radians:
    let scale = Math.sin(middleOfThis / $("content").width() * Math.PI);

    $(this).css('transform', 'scale(' + scale + ')');
  });
}
content {
  position: relative;
  display: block;
  width: 500px;
  height: 100px;
}

content::after {
  content: '';
  position: absolute;
  display: block;
  width: 20%;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}

#scroll {
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  border: 1px solid #000;
}

#example {
  display: block;
  width: 200%;
  height: 100%;
  font-size: 0;
  overflow: none;
}

#example>div {
  display: inline-block;
  width: 10%;
  height: 100%;
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<content>
  <div id="scroll">
    <section id="example">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </section>
  </div>
</content>
Hide result

NB: - . , , , .

+1

Source: https://habr.com/ru/post/1679938/


All Articles