【问题标题】:CSS3 3D Rotation: How perspective work?CSS3 3D 旋转:透视如何工作?
【发布时间】:2016-10-13 16:56:51
【问题描述】:

在鼠标移动后,我正在开发 3D bloc。我正在更新 CSS 值以创建 3D 效果。 基地看起来像:

document.addEventListener('DOMContentLoaded', function() {
  let mouseMove = function (e) {
    let el = e.currentTarget;
    let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
    let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)

    var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
        "rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
    var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " + 
        parseInt(-((delta_y - 0.5) * 8) + 2) + 
        "px 4px rgba(34, 25, 25, 0.4);"

    el.setAttribute('style', 
                    "transform: " + transform + "; " + 
                    "box-shadow: " + boxShadow);
  }

  let els = document.getElementsByClassName("el")
  let len = els.length
  for(let i=0; i<len; i++) {
    let el = els[i]
    el.addEventListener("mousemove", mouseMove)
  }
}, false);
html, body, #wrapper { 
  height: 100%; 
  margin: 0; 
  padding: 0; 
}
#wrapper {
  background: #a4d24b;
  /*font-family: 'Open Sans', sans-serif; */
  font-weight: 400;
  font-size: 14px;
  display: flex;
  flex-wrap: wrap;
  perspective: 500px;
}
.container {
  position: relative;
  margin: auto;
  width: 20%;
  height: 40%;
  transition: all .25s;
  transform-origin: 50% 50%;
}
.container:hover {
  transform: translateZ(25px);
}
.el {
  height: 100%;
  background: #FFF; color: #000;
  box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
}
.el:not(:hover) {
  transform: rotateY(0deg) rotateX(0deg) !important;
  box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
<div id="wrapper">
  <div class="container">
    <div class="el"></div>
  </div>
</div>

JS 的概念很简单:当鼠标在 bloc 上移动时,我得到了鼠标在 xy 上的位置(以 % 为单位:位置 / bloc 大小) >.

  • 对于 x (0 -> 1) 我将 transform 属性从 rotate: rotateY(-12deg) 移动到 rotate: rotateY(12deg)
  • y (0 -> 1) 从rotate: rotateX(-12deg)rotate: rotateX(12deg) 也是如此
  • 我还移动了 box-shadow(带有 x 和 y)以帮助可视化。

结果看起来不错,但是如果我给这个块添加背景,结果看起来很奇怪。

(与背景相同的代码)

document.addEventListener('DOMContentLoaded', function() {
  let mouseMove = function (e) {
    let el = e.currentTarget;
    let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
    let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)

    var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
        "rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
    var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " + 
        parseInt(-((delta_y - 0.5) * 8) + 2) + 
        "px 4px rgba(34, 25, 25, 0.4);"

    el.setAttribute('style', 
                    "transform: " + transform + "; " + 
                    "box-shadow: " + boxShadow);
  }

  let els = document.getElementsByClassName("el")
  let len = els.length
  for(let i=0; i<len; i++) {
    let el = els[i]
    el.addEventListener("mousemove", mouseMove)
  }
}, false);
html, body, #wrapper { 
  height: 100%; 
  margin: 0; 
  padding: 0; 
}
#wrapper {
  background: #a4d24b;
  /*font-family: 'Open Sans', sans-serif; */
  font-weight: 400;
  font-size: 14px;
  display: flex;
  flex-wrap: wrap;
  perspective: 500px;
}
.container {
  position: relative;
  margin: auto;
  width: 20%;
  height: 40%;
  transition: all .25s;
  transform-origin: 50% 50%;
}
.container:hover {
  transform: translateZ(25px);
}
.el {
  height: 100%;
  background: #FFF url(https://images-na.ssl-images-amazon.com/images/M/MV5BMjQyODg5Njc4N15BMl5BanBnXkFtZTgwMzExMjE3NzE@._V1_SY1000_SX686_AL_.jpg);
  background-size: cover;
  background-position: 50% 50%; 
  color: #000;
  box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
}
.el:not(:hover) {
  transform: rotateY(0deg) rotateX(0deg) !important;
  box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
<div id="wrapper">
  <div class="container">
    <div class="el"></div>
  </div>
</div>

现在,看起来只有顶部在工作,而底部并没有朝着好的方向发展。 (鼠标从左上角移动到右下角时的最佳再现)。

我做错了吗?还是视角问题?


更新 一些浏览器不喜欢下面的 CSS,如果你在上面移动鼠标时白框没有移动,只需将其删除。

.el:not(:hover) { transform: rotateY(0deg) rotateX(0deg) !important; box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important; }

【问题讨论】:

    标签: css 3d rotation transform perspective


    【解决方案1】:

    您需要在转换后的元素的直接父级上应用透视。

    我用透视图解决了:继承

    document.addEventListener('DOMContentLoaded', function() {
      let mouseMove = function (e) {
        let el = e.currentTarget;
        let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
        let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)
    
        var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
            "rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
        var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " + 
            parseInt(-((delta_y - 0.5) * 8) + 2) + 
            "px 4px rgba(34, 25, 25, 0.4);"
    
        el.setAttribute('style', 
                        "transform: " + transform + "; " + 
                        "box-shadow: " + boxShadow);
      }
    
      let els = document.getElementsByClassName("el")
      let len = els.length
      for(let i=0; i<len; i++) {
        let el = els[i]
        el.addEventListener("mousemove", mouseMove)
      }
    }, false);
    html, body, #wrapper { 
      height: 100%; 
      margin: 0; 
      padding: 0; 
    }
    #wrapper {
      background: #a4d24b;
      /*font-family: 'Open Sans', sans-serif; */
      font-weight: 400;
      font-size: 14px;
      display: flex;
      flex-wrap: wrap;
      perspective: 500px;
    }
    .container {
      position: relative;
      margin: auto;
      width: 20%;
      height: 40%;
      transition: all .25s;
      transform-origin: 50% 50%;
      perspective: inherit;
    }
    .container:hover {
      transform: translateZ(25px);
    }
    .el {
      height: 100%;
      background: #FFF url(https://images-na.ssl-images-amazon.com/images/M/MV5BMjQyODg5Njc4N15BMl5BanBnXkFtZTgwMzExMjE3NzE@._V1_SY1000_SX686_AL_.jpg);
      background-size: cover;
      background-position: 50% 50%; 
      color: #000;
      box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
    }
    .el:not(:hover) {
      transform: rotateY(0deg) rotateX(0deg) !important;
      box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
    }
    <div id="wrapper">
      <div class="container">
        <div class="el"></div>
      </div>
    </div>

    【讨论】:

    • 这太棒了!但我不确定。所有父母和祖父母都必须获得相同的perspective 属性才能一起“工作”?
    • 并非如此。您还可以从包装器中删除透视图并将其设置在容器上。我只是想最大限度地保持你的代码
    • 好的好的,我知道了
    猜你喜欢
    • 2013-11-08
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    相关资源
    最近更新 更多