全背景图片鼠标移动覆盖范围

3
我有一个小脚本,可以在鼠标移动时倾斜背景图像。我尝试了三种不同的图像,无论它们的大小如何,当图像移动时都会出现白色间隙。背景图片可以跟随鼠标移动,但是总是显示白色间隙。我已经尝试了各种设置图片的方法,但都没有成功。

$(function() {
  // Init
  var container = document.getElementById("container"),
    inner = document.getElementById("inner");
  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function() {
      return "(" + this.x + ", " + this.y + ")";
    }
  };
  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);
  //-----------------------------------------
  var counter = 0;
  var updateRate = 10;
  var isTimeToUpdate = function() {
    return counter++ % updateRate === 0;
  };
  //-----------------------------------------
  var onMouseEnterHandler = function(event) {
    update(event);
  };
  var onMouseLeaveHandler = function() {
    inner.style = "";
  };
  var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };
  //-----------------------------------------
  var update = function(event) {
    mouse.updatePosition(event);
    updateTransformStyle(
      (mouse.y / inner.offsetHeight / 2).toFixed(2),
      (mouse.x / inner.offsetWidth / 2).toFixed(2)
    );
  };
  var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTransform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };
  //-----------------------------------------
  container.onmouseenter = onMouseEnterHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmousemove = onMouseMoveHandler;
});
body {
  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
  color: #333;
  font-size: 14px;
  line-height: 20px;
}


.container {
  position: relative;
  overflow: hidden;
  -webkit-perspective: 50px;
  perspective: 50px;
}


.inner {
  position: static;
  display: block;
  width: 100%;
  height: 100vh;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
  background-image: url('https://www.planwallpaper.com/static/images/6909249-black-hd-background.jpg');
  background-position: 50% 50%;
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container" class="container">
    <div id="inner" class="inner"></div>
</div>


@Xufox 谢谢你,我实际上是在跟着一个网站的教程。 - Codi
@Xufox,我在谈论类型错误。我正在按照这里的教程进行操作:https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/,但我对JS不是很了解,所以我加上了(),因为它们在教程中出现了。 - Codi
@Xufox,我想要实现的是这种背景效果https://www.videinfra.com/,所有东西都可以工作,但是当移动鼠标时,图像显示了侧面的空隙,图像没有覆盖到所有内容。 - Codi
1
但这不是相同的语法。你用了 $(function(){}),他们用了 (function(){})()。在这种情况下,$(function(){}) 是保证可行的。 - Sebastian Simon
1
问题的一部分是您需要将 margin: 0; 设置为 body,以删除默认边距。另一部分是您可能希望缩放图像,使其比100%的宽度和高度更大。然后,需要以某种方式重新定位 <div> 以使其居中。 - Sebastian Simon
@Xufox,我已经尝试了所有这些方法,甚至使用了一个3000x3000的图像,尝试了我所知道的CSS中的每个属性,但结果都一样。 - Codi
2个回答

1
调整背景图片的大小是无济于事的。这些间隙是由于您的 div.inner 旋转方式造成的。这里有一个简单的图形解释:

enter image description here

可能的解决方案:
  1. 旋转时缩放div。您需要按比例缩放(1 / cos(rotation_angle))。但这不是非常好的方法。它看起来不够好。

  2. 根据最大可能的旋转角度一次性缩放div.inner。不要忘记使用负边距或position: absolute将其移动到所需位置。

这是一个基于您的代码的示例,说明了它是如何工作的。请注意,这不是完整的工作代码,我只修改了宽度和边距。要获得确切的所需效果,您需要自己设置比例和定位。

$(function() {
  // Init
  var container = document.getElementById("container"),
    inner = document.getElementById("inner");
  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function() {
      return "(" + this.x + ", " + this.y + ")";
    }
  };
  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);
  //-----------------------------------------
  var counter = 0;
  var updateRate = 10;
  var isTimeToUpdate = function() {
    return counter++ % updateRate === 0;
  };
  //-----------------------------------------
  var onMouseEnterHandler = function(event) {
    update(event);
  };
  var onMouseLeaveHandler = function() {
    inner.style = "";
  };
  var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };
  //-----------------------------------------
  var update = function(event) {
    mouse.updatePosition(event);
    updateTransformStyle(
      (mouse.y / inner.offsetHeight / 2).toFixed(2),
      (mouse.x / inner.offsetWidth / 2).toFixed(2)
    );
  };
  var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTransform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };
  //-----------------------------------------
  container.onmouseenter = onMouseEnterHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmousemove = onMouseMoveHandler;
});
body {
  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
  color: #333;
  font-size: 14px;
  line-height: 20px;
}


.container {
  position: relative;
  overflow: hidden;
  -webkit-perspective: 50px;
  perspective: 50px;
}


.inner {
  position: static;
  display: block;
  width: 130%; margin-left: -40px;
  height: 100vh;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
  background-image: url('https://www.planwallpaper.com/static/images/6909249-black-hd-background.jpg');
  background-position: 50% 50%;
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container" class="container">
    <div id="inner" class="inner"></div>
</div>


1
您的代码已根据@Xufox的评论进行了更新:

$(function() {
  // Init
  var container = document.getElementById("container"),
    inner = document.getElementById("inner");
  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function() {
      return "(" + this.x + ", " + this.y + ")";
    }
  };
  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);
  //-----------------------------------------
  var counter = 0;
  var updateRate = 10;
  var isTimeToUpdate = function() {
    return counter++ % updateRate === 0;
  };
  //-----------------------------------------
  var onMouseEnterHandler = function(event) {
    update(event);
  };
  var onMouseLeaveHandler = function() {
    inner.style = "";
  };
  var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };
  //-----------------------------------------
  var update = function(event) {
    mouse.updatePosition(event);
    updateTransformStyle(
      (mouse.y / inner.offsetHeight / 2).toFixed(2),
      (mouse.x / inner.offsetWidth / 2).toFixed(2)
    );
  };
  var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTransform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };
  //-----------------------------------------
  container.onmouseenter = onMouseEnterHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmousemove = onMouseMoveHandler;
});
html, body {margin:0 ;padding:0}

body {
  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
  color: #333;
  font-size: 14px;
  line-height: 20px;
}


.container {
  position: relative;
  overflow: hidden;
  -webkit-perspective: 50px;
  perspective: 50px;
}


.inner {
  position: static;
  display: block;

  width: 120vw;
  height: 120vh;
  margin:-10vh 0 0 -10vw;
  transition:.5s;


  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
  background-image: url('https://www.planwallpaper.com/static/images/6909249-black-hd-background.jpg');
  background-position: 50% 50%;
  background-size: cover;
  background-repeat: no-repeat;
  bbackground-attachment: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container" class="container">
    <div id="inner" class="inner"></div>
</div>


谢谢您的帮助,当鼠标移出浏览器时是否可以使其更加平滑? - Codi
@Codi,是的,这是可能的,例如使用 transition 属性。我已经更新了我的回答。 - Kosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接