Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery calculate image background-position top position?

Tags:

I set my images centred in CSS:

background-position: center center;

But I want to know its top-position now after it is set to centre, how can I calculate that with jQuery or just plain javaScript?

.parallax3 {
  position: relative;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  background-image: url('https://picsum.photos/g/200/600');
  height: 100%;
}

.tagline {
    font-size: 2.5vw;
    letter-spacing:0.05em;
    padding: 25% 25%;
}

.grid-x {
    border:1px solid red;
}

.cell {
    border: 1px solid blue;
}
<div class="row widescreen">

  <div class="grid-container full">
    <div class="grid-x grid-padding-x align-stretch small-padding-collapse">
      <div class="medium-6 cell">
        <div class="tagline text-center">
          <p>Lorem ipsum dolor sit amet</p>
        </div>
      </div>
      <div class="medium-6 cell parallax-viewport">
        <div class="parallax3">
        </div>
      </div>
    </div>
  </div>

</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.1/css/foundation.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.1/js/foundation.min.js"></script>

Any ideas?

like image 792
Run Avatar asked Dec 30 '17 19:12

Run


1 Answers

As I commented above we need to find the formula, so the idea is to rely on the logic of background-position:center and background-size:cover. So since the image will always be stretched, we have two possibilities :

  1. The top of the image will be the same as the top of div and thus top=0
  2. The height of the image will be longer than the div and the top will be hidden and thus top<0

enter image description here

As you may notice I considered the top position relatively to the top of the div which is the origin for me

Now we need to consider all the different cases on how the image will cover the div and calculate the new height of the image depending on each situation.

Here is a code example:

//am using fixed values because they are known in this case, so this need to also be calculated
var him = 600;
var wim = 200;
var ratio = him / wim;
/*--*/

function get_top() {
  var h = $('.parallax3').height();
  var w = $('.parallax3').width();

  var diffh = h - him;
  var diffw = w - wim;
  if (diffw > 0 && diffh > 0) {
    //the image is smaller than the div so it should get bigger by at least the max difference
    if (diffh > diffw*ratio) {
      //both height will be equal here so top position = 0
      console.log(0);
    } else {
      //height of image will be bigger so top position < 0
      var newH = (wim + diffw) * ratio;
      console.log((h - newH) / 2)
    }
  } else if (diffw > 0) {
    //only the width if div is bigger so the image width will stretch and the height will be bigger and top < 0;
    var newH = (wim + diffw) * ratio;
    console.log((h - newH) / 2)
  } else if (diffh > 0) {
    //only the height is bigger so the image height will stretch and both heights will be equal to div and top = 0
    console.log(0);
  } else {
    // the image is bigger in this case so we do same logic as the start with abs value but we will reduce size so we consider the lowest value
    if (Math.abs(diffh) < Math.abs(diffw)*ratio) {
      //both height will be equal here so top position = 0
      console.log(0);
    } else {
      //height of image will remain bigger so top position < 0
      var newH = (wim + diffw) * ratio;
      console.log((h - newH) / 2)
    }

  }
}

get_top();

$(window).resize(function() {
  get_top()
})
body {
  height: 100vh;
}

.parallax3 {
  position: relative;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  background-image:url('https://picsum.photos/g/200/600');
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax3">
</div>

If we consider contain as value in background-size the image will always be contained inside the div so the two possibilities are:

  1. The top of the image will be the same as the top of the div and thus top=0
  2. The image will be smaller in height and the top of image will be visible and thus top>0

enter image description here

Same thing as the above, we need to consider the different situations and calculate the new height of the image.

Here is a code example:

//am using fixed values because they are known in this case, so this need to also be calculated
var him = 600;
var wim = 200;
var ratio = him / wim;
/*--*/

function get_top() {
  var h = $('.parallax3').height();
  var w = $('.parallax3').width();
  var diffh = h - him;
  var diffw = w - wim;
  if (diffw > 0 && diffh > 0) {
    //the image is smaller than the div so it should get bigger by at least the min difference
    if (diffh < diffw*ratio) {
      //both height will be equal here so top position = 0
      console.log(0);
    } else {
      //height of image will be bigger so top position < 0
      var newH = (wim + diffw) * ratio;
      console.log((h - newH) / 2)
    }
  } else if (diffw > 0) {
    //only the width if div is bigger so the image height need to be reduced and both height will be equal
    console.log(0);

  } else if (diffh > 0) {
    //only the height is bigger so the image width will be reduced 
    var newH = (wim + diffw) * ratio;
    console.log((h - newH) / 2);
  } else {
    // the image is bigger in this case so we do same logic as the start with abs value but we will reduce size so we consider the biggest value
    if (Math.abs(diffh) > Math.abs(diffw)*ratio) {
      //both height will be equal here so top position = 0
      console.log(0);
    } else {
      //height of image will be bigger so top position < 0
      var newH = (wim + diffw) * ratio;
      console.log((h - newH) / 2)
    }

  }
}

get_top();

$(window).resize(function() {
  get_top()
})
body {
  height: 100vh;
}

.parallax3 {
  position: relative;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
  background-image: url('https://picsum.photos/g/200/600');
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax3">
</div>

Both snippet can be optimized to reduce redundancy but I kept them like this to better explain different situations.

like image 110
Temani Afif Avatar answered Nov 15 '22 04:11

Temani Afif