如何使用背景位置和百分比值制作可拖动的背景图像?

Arkellys

我正在尝试使用background-position和百分比值制作一个简单的可拖动背景到目前为止,我设法使拖动起作用了,但是似乎找不到正确的计算方法来使图像以相同的速度跟随光标(如果有意义)。

这是一个简单的示例(仅使用x轴):

const container = document.querySelector('div');
const containerSize = container.getBoundingClientRect();

let imagePosition = { x: 50, y: 50 };
let cursorPosBefore = { x: 0, y: 0 };
let imagePosBefore = null;
let imagePosAfter = imagePosition;

container.addEventListener('mousedown', function(event) {
  cursorPosBefore = { x: event.clientX, y: event.clientY };
  imagePosBefore = imagePosAfter; // Get current image position
});

container.addEventListener('mousemove', function(event) {
  if (event.buttons === 0) return;

  let newXPos = imagePosBefore.x + ((cursorPosBefore.x - event.clientX) * 100 / containerSize.width);
  newXPos = (newXPos < 0) ? 0 : (newXPos > 100) ? 100 : newXPos; // Stop at the end of the image
  
  imagePosAfter = { x: newXPos, y: imagePosition.y }; // Save position
  container.style.backgroundPosition = `${newXPos}% ${imagePosition.y}%`;
});
div {
  width: 400px;
  height: 400px;
  background-position: 50% 50%;
  background-size: cover;
  background-repeat: no-repeat;
  background-image: url('https://i.stack.imgur.com/5yqL8.png');
  cursor: move;
  border: 2px solid transparent;
}

div:active {
  border-color: red;
}
<div></div>

如果单击背景上的白色十字之一并移动鼠标,则十字应始终保留在光标下方,直到到达图像末尾或容器末尾。

这可能只是一个数学问题,但由于百分比如何与我有些困惑background-position任何想法?

莫里斯·尼诺

我不知道公式的精确度,但是您也必须包括CSS背景的大小。

如果背景大小是容器divs大小的100%,则公式有效。您可能需要知道缩放级别(可以根据与div大小相关的大小来计算)。

这是您具有缩放级别时的公式:

container.addEventListener('mousemove', function(event) {
    event.preventDefault();

    const zoomAffector = (currentZoomLevel - 100) / 100; // 100% zoom = image as big as container
    if (zoomAffector <= 0) return; // Cant drag a image that is zoomed out

    let newXPos = imagePosBefore.x + ((imagePosBefore.x - event.pageX) / zoomAffector * 100;);
    newXPos = (newXPos < 0) ? 0 : (newXPos > 100) ? 100 : newXPos;
  
    imagePosAfter = { x: newXPos, y: imagePosition.y };
    container.style.backgroundPosition = `${newXPos}% ${imagePosition.y}%`;
});

要获取css背景图片的大小,请检查以下问题:使用JavaScript获取CSS背景图片的大小?

这是我对您的问题的尝试,使用来自链接问题的答案之一来获取图像宽度(为完成y轴,它也完成了):

const container = document.querySelector('div');
const containerSize = container.getBoundingClientRect();

let imagePosition = { x: 50, y: 50 };
let cursorPosBefore = { x: 0, y: 0 };
let imagePosBefore = null;
let imagePosAfter = imagePosition;


var actualImage = new Image();
actualImage.src = $('#img').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
actualImage.onload = function() {
    const zoomX = this.width / containerSize.width - 1;
    const zoomY = this.height / containerSize.height - 1;
    
    container.addEventListener('mousedown', function(event) {
      cursorPosBefore = { x: event.clientX, y: event.clientY };
      imagePosBefore = imagePosAfter; // Get current image position
    });

    container.addEventListener('mousemove', function(event) {
        event.preventDefault();

        if (event.buttons === 0) return;

        let newXPos = imagePosBefore.x + ((cursorPosBefore.x - event.clientX) / containerSize.width * 100 / zoomX);
        newXPos = (newXPos < 0) ? 0 : (newXPos > 100) ? 100 : newXPos;
        let newYPos = imagePosBefore.y + ((cursorPosBefore.y - event.clientY) / containerSize.height * 100 / zoomY);
        newYPos = (newYPos < 0) ? 0 : (newYPos > 100) ? 100 : newYPos;

        imagePosAfter = { x: newXPos, y: newYPos };
        container.style.backgroundPosition = `${newXPos}% ${newYPos}%`;
    });
}
#img {
  width: 400px;
  height: 200px;
  background-position: 50% 50%;
  background-image: url('https://i.stack.imgur.com/5yqL8.png');
  cursor: move;
  border: 2px solid transparent;
}

#img:active {
  border-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="img"></div>

或更多清理:

const container = document.querySelector('div');
const containerSize = container.getBoundingClientRect();

let imagePosition = { x: 50, y: 50 };
let cursorPosBefore = { x: 0, y: 0 };
let imagePosBefore = null;
let imagePosAfter = imagePosition;

// Helpers
const minMax = (pos) => (pos < 0) ? 0 : (pos > 100) ? 100 : pos;
const setNewCenter = (x, y) => {
  imagePosAfter = { x: x, y: y }; 
  container.style.backgroundPosition = `${x}% ${y}%`;
};

const getImageZoom = () => {
  return new Promise((resolve, reject) => {
    let actualImage = new Image();
    actualImage.src = $('#img').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
    actualImage.onload = function() {
      resolve({
        x: zoomX = this.width / containerSize.width - 1,
        y: zoomY = this.height / containerSize.height - 1
      });
    }
  });
}
    
const addEventListeners = (zoomLevels) => {container.addEventListener('mousedown', function(event) {
      cursorPosBefore = { x: event.clientX, y: event.clientY };
      imagePosBefore = imagePosAfter; // Get current image position
    });

    container.addEventListener('mousemove', function(event) {
        event.preventDefault();

        if (event.buttons === 0) return;

        let newXPos = imagePosBefore.x + ((cursorPosBefore.x - event.clientX) / containerSize.width * 100 / zoomLevels.x);
        let newYPos = imagePosBefore.y + ((cursorPosBefore.y - event.clientY) / containerSize.height * 100 / zoomLevels.y);

        setNewCenter(minMax(newXPos), minMax(newYPos));
    });
};

getImageZoom().then(zoom => addEventListeners(zoom));
    
#img {
  width: 400px;
  height: 200px;
  background-position: 50% 50%;
  background-image: url('https://i.stack.imgur.com/5yqL8.png');
  cursor: move;
  border: 2px solid transparent;
}

#img:active {
  border-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="img"></div>

或回答您的后续问题:

const container = document.querySelector("div");
const containerSize = container.getBoundingClientRect();

let imagePosition = { x: 50, y: 50 };
let cursorPosBefore = { x: 0, y: 0 };
let imagePosBefore = null;
let imagePosAfter = imagePosition;

// Helpers
const minMax = (pos) => (pos < 0 ? 0 : pos > 100 ? 100 : pos);
const setNewCenter = (x, y) => {
  imagePosAfter = { x: x, y: y };
  container.style.backgroundPosition = `${x}% ${y}%`;
};

const getImageZoom = () => {
  return new Promise((resolve, reject) => {
    let actualImage = new Image();

    actualImage.src = $("#img")
      .css("background-image")
      .replace(/"/g, "")
      .replace(/url\(|\)$/gi, "");
    actualImage.onload = function () {
      const imgW = this.width,
        imgH = this.height,
        conW = containerSize.width,
        conH = containerSize.height,
        ratioW = imgW / conW,
        ratioH = imgH / conH;

      // Stretched to Height
      if (ratioH < ratioW) {
        resolve({
          x: imgW / (conW * ratioH) - 1,
          y: imgH / (conH * ratioH) - 1,
        });
      } else {
        // Stretched to Width
        resolve({
          x: imgW / (conW * ratioW) - 1,
          y: imgH / (conH * ratioW) - 1,
        });
      }
    };
  });
};

const addEventListeners = (zoomLevels) => {
  container.addEventListener("mousedown", function (event) {
    cursorPosBefore = { x: event.clientX, y: event.clientY };
    imagePosBefore = imagePosAfter; // Get current image position
  });

  container.addEventListener("mousemove", function (event) {
    event.preventDefault();

    if (event.buttons === 0) return;

    let newXPos =
      imagePosBefore.x +
      (((cursorPosBefore.x - event.clientX) / containerSize.width) * 100) /
        zoomLevels.x;
    let newYPos =
      imagePosBefore.y +
      (((cursorPosBefore.y - event.clientY) / containerSize.height) * 100) /
        zoomLevels.y;

    setNewCenter(minMax(newXPos), minMax(newYPos));
  });
};

getImageZoom().then((zoom) => addEventListeners(zoom));
#img {
  width: 400px;
  height: 200px;
  background-size: cover;
  background-position: 50% 50%;
  background-image: url('https://i.stack.imgur.com/5yqL8.png');
  cursor: move;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="img"></div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

背景位置负百分比值

来自分类Dev

如何使用百分比而不是像素将背景图像设置为伪元素?

来自分类Dev

如何使用纯CSS将基于百分比的定位应用于背景图像精灵?

来自分类Dev

框阴影左侧位置,使用百分比值

来自分类Dev

jQuery IF无法使用位置相对+百分比值

来自分类Dev

如何在Matlab中使用百分比值制作混淆矩阵图

来自分类Dev

来自背景图像颜色百分比的状态栏样式(iOS)

来自分类Dev

Firefox的背景位置百分比不起作用

来自分类Dev

混合背景位置(以像素和百分比为单位)

来自分类Dev

如何在列表视图中制作一行取决于百分比值

来自分类Dev

如何测量背景上有色区域的百分比?图像J?

来自分类Dev

CSS计算背景百分比如何工作?

来自分类Dev

基于 css 百分比的背景

来自分类Dev

highcharter 名义值和百分比值

来自分类Dev

两张背景图像,一个背景图像的百分比大小,另一个背景图像覆盖了剩下的内容?

来自分类Dev

尝试使用 flexbox 和百分比制作网格

来自分类Dev

如何更改jQuery easyPiechart的百分比值

来自分类Dev

使用约束布局设置百分比值

来自分类Dev

使用Hive找出百分比值

来自分类Dev

使用if语句比较2个百分比值

来自分类Dev

如何选择和更改此代码中的百分比值?

来自分类Dev

在AngularJS中使用ng样式和百分比值设置HTML元素宽度

来自分类Dev

使用jquery表排序器在单列中排序整数和百分比值

来自分类Dev

使用jquery表排序器在单列中排序整数和百分比值

来自分类Dev

使用绝对值和百分比值 + 标签绘制分组条形图

来自分类Dev

如何正确使用bc将百分比值转换为浮点格式?

来自分类Dev

ampampchart中的百分比值

来自分类Dev

百分比值的计算

来自分类Dev

如何设置背景图像进行缩放和拖动?

Related 相关文章

  1. 1

    背景位置负百分比值

  2. 2

    如何使用百分比而不是像素将背景图像设置为伪元素?

  3. 3

    如何使用纯CSS将基于百分比的定位应用于背景图像精灵?

  4. 4

    框阴影左侧位置,使用百分比值

  5. 5

    jQuery IF无法使用位置相对+百分比值

  6. 6

    如何在Matlab中使用百分比值制作混淆矩阵图

  7. 7

    来自背景图像颜色百分比的状态栏样式(iOS)

  8. 8

    Firefox的背景位置百分比不起作用

  9. 9

    混合背景位置(以像素和百分比为单位)

  10. 10

    如何在列表视图中制作一行取决于百分比值

  11. 11

    如何测量背景上有色区域的百分比?图像J?

  12. 12

    CSS计算背景百分比如何工作?

  13. 13

    基于 css 百分比的背景

  14. 14

    highcharter 名义值和百分比值

  15. 15

    两张背景图像,一个背景图像的百分比大小,另一个背景图像覆盖了剩下的内容?

  16. 16

    尝试使用 flexbox 和百分比制作网格

  17. 17

    如何更改jQuery easyPiechart的百分比值

  18. 18

    使用约束布局设置百分比值

  19. 19

    使用Hive找出百分比值

  20. 20

    使用if语句比较2个百分比值

  21. 21

    如何选择和更改此代码中的百分比值?

  22. 22

    在AngularJS中使用ng样式和百分比值设置HTML元素宽度

  23. 23

    使用jquery表排序器在单列中排序整数和百分比值

  24. 24

    使用jquery表排序器在单列中排序整数和百分比值

  25. 25

    使用绝对值和百分比值 + 标签绘制分组条形图

  26. 26

    如何正确使用bc将百分比值转换为浮点格式?

  27. 27

    ampampchart中的百分比值

  28. 28

    百分比值的计算

  29. 29

    如何设置背景图像进行缩放和拖动?

热门标签

归档