我正在寻找一种从rotate
转换中关键帧转换回来的方法。我有一个长期运行的关键帧,可以从0deg
重复转换为360deg
。
当该动画停止时(通过删除类),我希望元素从当前位置返回0deg
,。目前,我正在使用第二个关键帧来动画回0deg
,但是这个关键帧总是将完整的360deg
转回0deg
,这不是我想要的。
我做了一个JSFiddle来演示这个问题:https://jsfiddle.net/egdct6qz/2/
感谢您的帮助!
答案 0 :(得分:1)
您可以使用以下CSS和JavaScript组合来实现这一点,该组合使用getComputedStyle ()
。
const circle = document.querySelector (".circle");
circle.onclick = () => {
if (circle.classList.contains ("circle--spinning")) {
// Get rotation and start animating back
let currentRotation = getRotationDegrees (circle);
animateRotationBack (currentRotation);
}
// Toggle the spinning itself
circle.classList.toggle ("circle--spinning");
}
function animateRotationBack (angle) {
const keyframe = `
@keyframes spin-back {
from { transform: rotate(${angle}deg); }
to { transform: rotate(0deg); }
}
`;
// Get inserted style-tag or create a new one
const style = document.getElementById ("spin-back-kf") || document.createElement ("style");
style.textContent = keyframe;
style.id = "spin-back-kf";
// Remove previously inserted style tag if existant
style.parentNode && style.parentNode.removeChild (style);
// Append style tag and set animation
document.body.appendChild (style);
}
function getRotationDegrees (element) {
// get the computed style object for the element
const style = window.getComputedStyle (element);
// this string will be in the form 'matrix(a, b, c, d, tx, ty)'
let transformString = style["-webkit-transform"]
|| style["-moz-transform"]
|| style["transform"];
if (!transformString || transformString === "none")
return 0;
// Remove matrix notation
transformString = transformString
.substr (0, transformString.length - 2)
.substr (7);
// Split and parse to floats
const parts = transformString
.split (",")
.map (num => parseFloat (num));
// Destructure in a and b
let [a, b] = parts;
// Doing atan2 on (b, a) will give you the angle in radians
// Convert it to degrees and normalize it from (-180...180) to (0...360)
const degrees = ((180 * Math.atan2 (b, a) / Math.PI) + 360) % 360;
return degrees;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
margin: 5% auto;
text-align: center;
}
.circle {
padding: 3em;
border-radius: 3em;
position: relative;
background-color: #EE5622;
display: inline-block;
cursor: pointer;
animation: .5s spin-back forwards;
}
.circle--spinning {
animation: 2s spin infinite linear;
}
.square {
padding: 1em;
background-color: #F1F7ED;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<div class="wrapper">
<span class="circle circle--spinning">
<span class="square"></span>
</span>
</div>