我正在使用 CSS3 3d 变换处理一个打开的立方体,它在 Chrome、Firefox 和 Opera 中运行良好。但是,在 Safari 中,由于某种原因,立方体正在移动到一个奇怪的地方。
let isExpanded = false;
let cube = document.querySelector(".cube");
document.querySelector("#toggle").onclick = function(e) {
e.preventDefault();
document.querySelector("#toggle").disabled = true;
toggle();
}
function toggle() {
if (!isExpanded) {
isExpanded = true;
// Pause Rotation
document.querySelector(".cube").classList.add("pause");
// Open Cube
open();
} else {
isExpanded = false;
close();
}
}
function close() {
// Close the cube
cube.classList.remove("open");
cube.style.bottom = "0";
// Rotate to the start position and restart animation
setTimeout(function() {
cube.classList.remove("origin-bottom");
}, 1000); // >= side transform's transition time
setTimeout(function() {
cube.style.animation = "spin 15s infinite linear";
cube.style.webkitAnimation = "spin 15s infinite linear";
document.querySelector("#toggle").disabled = false;
}, 1200);
}
function open() {
// Set transform value to current position & Disable Animation
prop = window.getComputedStyle(cube, null).getPropertyValue("transform");
cube.style.transform = prop;
cube.style.webkitTransform = prop;
cube.style.MozTransform = prop;
cube.style.msTransform = prop;
cube.style.OTransform = prop;
cube.style.animation = "none";
cube.style.webkitAnimation = "none";
// Rotate the cube to its initial position & Remove pause
setTimeout(function() {
cube.classList.remove("pause");
cube.classList.add("origin-bottom");
cube.style.transform = "rotateX(-20deg) rotateY(42deg)";
cube.style.webkitTransform = "rotateX(-20deg) rotateY(42deg)";
cube.style.MozTransform = "rotateX(-20deg) rotateY(42deg)";
cube.style.msTransform = "rotateX(-20deg) rotateY(42deg)";
cube.style.OTransform = "rotateX(-20deg) rotateY(42deg)";
}, 50);
// Open the cube
setTimeout(function() {
cube.classList.add("open");
document.querySelector("#toggle").disabled = false;
}, 1000); // >= side transform's transition time
}
body {background: #333;}
.cube-wrapper {
margin: auto;
width: 200px;
height: 200px;
top: 0;
bottom: 0;
right: 0;
left: 0;
position: absolute;
-webkit-perspective: 600px;
perspective: 600px;
perspective-origin: 50% 50%;
}
.cube-wrapper .cube {
width: 200px;
height: 200px;
position: relative;
bottom: 0;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
backface-visibility: visible;
transition: all 1s ease-in-out;
animation: spin 15s infinite linear;
}
.cube-wrapper .cube .side {
transition: transform 1s ease-in-out, background 0.5s ease-in-out, opacity 0.5s ease-in-out;
outline: 1px solid rgba(250, 250, 250, 0.3);
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
transform-origin: 50% 50%;
-webkit-transform-origin: 50% 50%;
}
.cube-wrapper .cube .right {
transform: rotateX(0deg) rotateY(90deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .left {
transform: rotateX(0deg) rotateY(270deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .top {
transform: rotateX(90deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .bottom {
transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .front {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .behind {
transform: rotateX(0deg) rotateY(180deg) rotateZ(0deg) translateZ(100px);
}
/* pause */
.preserve3d .cube-wrapper .cube.pause, .preserve3d .cube-wrapper .cube:hover {
-webkit-animation-play-state: paused !important;
animation-play-state: paused !important;
}
/* open */
.preserve3d .cube-wrapper .cube.open .right {
transform: rotateY(90deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .left {
transform: rotateY(-90deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .front {
transform: rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .behind {
transform: rotateY(180deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .right {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .left {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .top {
opacity: 0;
pointer-events: none;
}
.preserve3d .cube-wrapper .cube.origin-bottom .front {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .behind {
transform-origin: bottom !important;
}
/* animation */
@keyframes spin {
from {
transform: rotateX(-20deg) rotateY(42deg);
}
to {
transform: rotateX(340deg) rotateY(382deg);
}
}
<button id="toggle">toggle</button>
<div class="preserve3d">
<div class="cube-wrapper">
<div class="cube">
<div class="side right">Right
</div>
<div class="side left">Left
</div>
<div class="side top">Top
</div>
<div class="side bottom">Bottom
</div>
<div class="side front">Front
</div>
<div class="side behind">Behind
</div>
</div>
</div>
</div>
虽然它被移动到一个奇怪的位置,但检查员说它在一个正确的地方。使用 getComputedStyle
也给出了正确的值,所以我不知道如何调试这个问题。
我搜索并发现Safari在rotateY方面存在一些问题并尝试了给定的解决方案,给出了z-index值,但没有用。
这是代码的缩短版本:https : //jsfiddle.net/7mxghcq9/
提前谢谢你:)
对不起,我不能确定会发生什么,也不能确定 Safari 的行为是否完全错误......
无论如何,一个可行的解决方案是将cube.style.animation = 'none';
第一个超时时间移到内部,然后在删除其暂停状态之前触发回流。
function open() {
// Set transform value to current position
prop = window.getComputedStyle(cube, null).getPropertyValue("transform");
cube.style.transform = prop;
cube.style.webkitTransform = prop;
cube.style.MozTransform = prop;
cube.style.msTransform = prop;
cube.style.OTransform = prop;
// Disable Animation & Rotate the cube to its initial position & Remove pause
setTimeout(function() {
cube.style.animation = "none";
cube.offsetWidth; // force a reflow
cube.classList.remove("pause");
cube.classList.add("origin-bottom");
cube.style.transform = "rotateX(-20deg) rotateY(42deg)";
}, 50);
// Open the cube
setTimeout(function() {
cube.classList.add("open");
document.querySelector("#toggle").disabled = false;
}, 1000); // >= side transform's transition time
}
let isExpanded = false;
let cube = document.querySelector(".cube");
document.querySelector("#toggle").onclick = function(e) {
e.preventDefault();
document.querySelector("#toggle").disabled = true;
toggle();
}
function toggle() {
if (!isExpanded) {
isExpanded = true;
// Pause Rotation
document.querySelector(".cube").classList.add("pause");
// Open Cube
open();
} else {
isExpanded = false;
close();
}
}
function close() {
// Close the cube
cube.classList.remove("open");
cube.style.bottom = "0";
// Rotate to the start position and restart animation
setTimeout(function() {
cube.classList.remove("origin-bottom");
}, 1000); // >= side transform's transition time
setTimeout(function() {
cube.style.animation = "spin 15s infinite linear";
cube.style.webkitAnimation = "spin 15s infinite linear";
document.querySelector("#toggle").disabled = false;
}, 1200);
}
body {background: #333;}
.cube-wrapper {
margin: auto;
width: 200px;
height: 200px;
top: 0;
bottom: 0;
right: 0;
left: 0;
position: absolute;
-webkit-perspective: 600px;
perspective: 600px;
perspective-origin: 50% 50%;
}
.cube-wrapper .cube {
width: 200px;
height: 200px;
position: relative;
bottom: 0;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
backface-visibility: visible;
transition: all 1s ease-in-out;
animation: spin 15s infinite linear;
}
.cube-wrapper .cube .side {
transition: transform 1s ease-in-out, background 0.5s ease-in-out, opacity 0.5s ease-in-out;
outline: 1px solid rgba(250, 250, 250, 0.3);
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
transform-origin: 50% 50%;
-webkit-transform-origin: 50% 50%;
}
.cube-wrapper .cube .right {
transform: rotateX(0deg) rotateY(90deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .left {
transform: rotateX(0deg) rotateY(270deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .top {
transform: rotateX(90deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .bottom {
transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .front {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translateZ(100px);
}
.cube-wrapper .cube .behind {
transform: rotateX(0deg) rotateY(180deg) rotateZ(0deg) translateZ(100px);
}
/* pause */
.preserve3d .cube-wrapper .cube.pause, .preserve3d .cube-wrapper .cube:hover {
-webkit-animation-play-state: paused !important;
animation-play-state: paused !important;
}
/* open */
.preserve3d .cube-wrapper .cube.open .right {
transform: rotateY(90deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .left {
transform: rotateY(-90deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .front {
transform: rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.open .behind {
transform: rotateY(180deg) rotateX(-90deg) translateY(-100px) !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .right {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .left {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .top {
opacity: 0;
pointer-events: none;
}
.preserve3d .cube-wrapper .cube.origin-bottom .front {
transform-origin: bottom !important;
}
.preserve3d .cube-wrapper .cube.origin-bottom .behind {
transform-origin: bottom !important;
}
.cube.origin-bottom{
animation-fill-mode: forwards;
}
/* animation */
@keyframes spin {
from {
transform: rotateX(-20deg) rotateY(42deg);
}
to {
transform: rotateX(340deg) rotateY(382deg);
}
}
<button id="toggle">toggle</button>
<div class="preserve3d">
<div class="cube-wrapper">
<div class="cube">
<div class="side right">Right
</div>
<div class="side left">Left
</div>
<div class="side top">Top
</div>
<div class="side bottom">Bottom
</div>
<div class="side front">Front
</div>
<div class="side behind">Behind
</div>
</div>
</div>
</div>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句