以百分比计算可拖动图像在 div 高度上的顶部偏移位置

Calculate top offsset position of draggable Image on div height in percentage

我正在尝试计算我的图像在固定高度的容器内可拖动的顶部偏移量。因此,我可以获得以百分比而非像素为单位的值,并使用该值根据容器的高度设置 CSS 图像在容器“.container”中的顶部定位。

<div class="container">
    <img src="" alt="" class="image">
</div>
<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>
<style>
    .container{
        position: relative;
        width:  960px;
        height: 300px;
        overflow: hidden;
    }
    .image{
        top: 0;
        width: 100%;
        min-height: 100%;
        min-width: 100%;
    }
</style>

// Js

$(document).ready(function () {
    let $container = $('.container');
    let $image     = $('.image');
    let $conWidth  = $($container).width();
    let $conHeight = $($container).height();
    let $imgWidth  = $image.width();
    let $imgHeight = $image.height();

    $image.draggable({ 
        disabled: false,
        scroll: false,
        axis: 'x, y',
        cursor : 'move',
        drag: (e, ui)=>{
            if(ui.position.top >= 0) ui.position.top = 0;

            if(ui.position.top <= $conHeight - $imgHeight)
                ui.position.top = $conHeight - $imgHeight;

            if(ui.position.left >= 0) ui.position.left = 0;

            if(ui.position.left <= $conWidth - $imgWidth)
                ui.position.left = $conWidth - $imgWidth;
        },
        stop: (e, ui)=>{
            let $offsetHeight = ui.position.top;     
            let $offsetWidth = ui.position.left;
            let realImageHeight = ($conWidth * $conHeight / $imgWidth) - $imgHeight;
            let $top = ($realImageHeight * $offsetHeight / 100 * -1)/100;
            console.log($top) // $top value in percent to be used as top positioning CSS
        }
    });
});

考虑以下因素。

$(() => {
  var $image = $('.image');
  var $conHeight = $($container).height();

  function percentFormat(dec) {
    return Math.round(dec * 100) + "%";
  }

  $image.draggable({
    disabled: false,
    scroll: false,
    axis: 'x, y',
    cursor: 'move',
    start: (e, ui) => {
      console.log(percentFormat($image.position().top / $conHeight));
    },
    drag: (e, ui) => {
      console.log(percentFormat(ui.position.top / $conHeight));
    },
    stop: (e, ui) => {
      console.log(percentFormat(ui.position.top / $conHeight));
    }
  });
});
.container {
  position: relative;
  width: 960px;
  height: 300px;
  overflow: hidden;
}

.image {
  top: 0;
  width: 100%;
  min-height: 100%;
  min-width: 100%;
}
<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>

<div class="container">
  <img src="" alt="" class="image">
</div>

如果您需要计算 top 的百分比,则算法为:position.top / container.height。示例:120 / 300 = 0.4。我们知道有一个介于 0 和 1 之间的值。要使其成为介于 0 和 100 之间的百分比,我们可以将小数值乘以 100。(120 / 300) * 100 = 40。这个例子非常干净,但您可能会得到类似 (85 / 300) * 100 = 28.3333333333 的结果,这并不是一个很好的百分比。我用 Round 来清理它,使最终值 28%.

使用新示例更新

$(() => {
  var $container = $('.container');
  var $image = $('.image');
  var $conHeight = $container.height();
  var $conWidth = $container.width();
  var $imgHeight = $image.height();
  var $imgWidth = $image.width();
  var containmentArr = [
    0 - $conWidth,
    // X1 = Left Containerment Border
    ($conHeight + $container.position().top) - $imgHeight,
    // Y1 = Top Containerment Border
    $container.position().left,
    // X2 = Right Containment Border
    $container.position().top
    // Y2 = Bottom Containment Border
  ];
  console.log(containmentArr);

  function percentFormat(dec) {
    return Math.round(dec * 100) + "%";
  }

  $image.draggable({
    disabled: false,
    scroll: false,
    cursor: 'move',
    containment: containmentArr,
    drag: (e, ui) => {
      $('.counter-result > span:eq(0)').html(percentFormat(ui.position.left, $conWidth));
      $('.counter-result > span:eq(1)').html(percentFormat(ui.position.top, $conHeight));
    }
  });
});
body {
  margin: 0;
  padding: 0;
}

.counter-result {
  background: green;
  padding: 5px 20px;
  margin-bottom: 3px;
  color: #fff;
}

.container {
  margin: 0 auto;
  overflow: hidden;
  height: 150px;
  max-height: 150px;
  position: relative;
  width: 960px;
  max-width: 960px;
  background: #ddd;
}

.image {
  position: absolute;
  top: 0;
  left: 0;
  cursor: move;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>
<div class="counter-result">X: <span>0%</span>, Y: <span>0%</span></div>
<div class="container">
  <img src="https://www.jahazi.co.tz/wp-content/uploads/2021/08/BEEF-SANDWICHES-1920x2560.jpg" alt="" class="image">
</div>

请看:https://api.jqueryui.com/draggable/#option-containment

示例

$(() => {
        let $container = $('.container');
        let $image     = $('.image');
        let $conWidth  = $($container).width();
        let $conHeight = $($container).height();
        let $imgWidth  = $image.width();
        let $imgHeight = $image.height();

        function percentFormat(dec) {
            return Math.round(dec * 100) + "%";
        }

        $image.draggable({ 
            disabled: false,
            scroll: false,
            axis: 'x, y',
            cursor : 'move',
            start: (e, ui) =>{
                //console.log(percentFormat($image.position().top / $conHeight));
               let $percent = percentFormat($image.position().top / $conHeight);
               $('.counter-result').html($percent);
            },
            drag: (e, ui) =>{
                if(ui.position.top >= 0) ui.position.top = 0;

                if(ui.position.top <= $conHeight - $imgHeight)
                    ui.position.top = $conHeight - $imgHeight;

                if(ui.position.left >= 0) ui.position.left = 0;

                if(ui.position.left <= $conWidth - $imgWidth)
                    ui.position.left = $conWidth - $imgWidth;

                let $percent  = ui.position.top / $conHeight;
                //console.log(percentFormat($percent));
                //$('.counter-result').html($percent);
            },
            stop: (e, ui) =>{

            }
        });
    });
body
{
    margin: 0;
    padding: 0;
}
.counter-result
{
   background: green;
   padding:5px 20px;
   margin-bottom: 3px;
   color: #fff;
}
.container 
{
    margin: 0 auto;
    overflow: hidden;
    height: 150px;
    position: relative;
    max-width: 960px;
    background: #ddd;
}

.image
{
    position: absolute;
    top: 0;
    object-fit: cover;
    width: 100%;
    min-height: 100%;
    min-width: 100%;
    cursor: move;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>
<div class="counter-result">0</div>
<div class="container">
  <img src="https://www.jahazi.co.tz/wp-content/uploads/2021/08/BEEF-SANDWICHES-1920x2560.jpg" alt="" class="image">
</div>