CSS3 3D 旋转:透视如何工作?
CSS3 3D Rotation: How perspective work?
我正在处理鼠标在其上移动后的 3D 块。我正在更新 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上移动时,我得到了鼠标在x和y.
- 对于 x (0 -> 1) 我将
transform
属性 从 rotate: rotateY(-12deg)
移动到 rotate: rotateY(12deg)
- 对于 y (0 -> 1) 从
rotate: rotateX(-12deg)
到 rotate: rotateX(12deg)
同样的事情
- 我还移动了框阴影(带有 x 和 y)以帮助可视化。
结果看起来不错,但是如果我给这个 bloc 添加背景,结果看起来很奇怪。
(后台代码相同)
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;
}
您需要将透视应用于转换元素的直接父级。
我用透视法解决了:inherit
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>
我正在处理鼠标在其上移动后的 3D 块。我正在更新 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上移动时,我得到了鼠标在x和y.
- 对于 x (0 -> 1) 我将
transform
属性 从rotate: rotateY(-12deg)
移动到rotate: rotateY(12deg)
- 对于 y (0 -> 1) 从
rotate: rotateX(-12deg)
到rotate: rotateX(12deg)
同样的事情
- 我还移动了框阴影(带有 x 和 y)以帮助可视化。
结果看起来不错,但是如果我给这个 bloc 添加背景,结果看起来很奇怪。
(后台代码相同)
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;
}
您需要将透视应用于转换元素的直接父级。
我用透视法解决了:inherit
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>