我希望我的无限svg动画暂停它的初始或最终状态时,我悬停它。我尝试使用JS删除类,或者在CSS中在悬停或设置animation-iteration-count: unset;时设置animation: none;,但在每种情况下,转换都是突然的。我想要顺滑的。下面是代码: HTML
<div class="button">
<svg version="1.1" id="sound--icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" >
<rect class="rect-1 rect-anim" x="10" fill="currentColor"></rect>
<rect class="rect-2 rect-anim" x="30" fill="currentColor"></rect>
<rect class="rect-3 rect-anim" x="50" fill="currentColor"></rect>
<rect class="rect-4 rect-anim" x="70" fill="currentColor"></rect>
</svg>
</div>CSS
#sound--icon .rect-anim{
animation-name: sound-icon-anim;
animation-duration: .8s;
animation-timing-function: cubic-bezier(.97,0,0,1);
animation-iteration-count: infinite;
}
/* #sound--icon:hover .rect-anim{
animation-iteration-count: unset;
}
*/
#sound--icon .rect-1{
animation-delay: .1s;
}
#sound--icon .rect-2{
animation-delay: .3s;
}
#sound--icon .rect-3{
animation-delay: .5s;
}
#sound--icon .rect-4{
animation-delay: .7s;
}
@keyframes sound-icon-anim{
0%{
height: 30%;
}
10%{
height: 70%;
}
20%{
height: 50%;
}
50%{
height: 80%;
}
60%{
height: 100%;
}
70%{
height: 70%;
}
100%{
height: 30%;
}
}我最终要做的是:
在纯CSS中,这似乎是可能的吗?
发布于 2020-11-26 16:12:52
我不认为你能在纯CSS中做到这一点。有了Web动画API,这是可能的,但在目前的实现状态下,只有一部分是现实的。
您可以实现的是在迭代周期结束时停止动画。在一个不是循环结束的点停止将需要实现AnimationTimeline。但Chrome目前还缺少这款手机。
document.querySelectorAll('.button').forEach(button => {
//.getAnimations() returns an array
const animations = [...button.querySelectorAll('.rect-anim')]
.map(r => r.getAnimations())
.flat();
button.addEventListener('mouseenter', () => {
for (let animation of animations) {
const iterations = animation.effect.getComputedTiming()
.currentIteration + 1;
animation.effect.updateTiming({iterations})
}
});
button.addEventListener('mouseleave', () => {
for (let animation of animations) {
animation.effect.updateTiming({iterations: Infinity});
}
});
});.button {
margin: 20px;
width: 100px;
}
#sound--icon .rect-anim{
animation-name: sound-icon-anim;
animation-duration: .8s;
animation-timing-function: cubic-bezier(.97,0,0,1);
animation-iteration-count: infinite;
}
#sound--icon .rect-1{
animation-delay: .1s;
}
#sound--icon .rect-2{
animation-delay: .3s;
}
#sound--icon .rect-3{
animation-delay: .5s;
}
#sound--icon .rect-4{
animation-delay: .7s;
}
@keyframes sound-icon-anim{
0%{
height: 30%;
}
10%{
height: 70%;
}
20%{
height: 50%;
}
50%{
height: 80%;
}
60%{
height: 100%;
}
70%{
height: 70%;
}
100%{
height: 30%;
}
}<div id="this-button" class="button">
<svg version="1.1" id="sound--icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" >
<rect class="rect-1 rect-anim" x="10" y="40" width="20" height="20" fill="currentColor"></rect>
<rect class="rect-2 rect-anim" x="30" y="40" width="20" height="20" fill="currentColor"></rect>
<rect class="rect-3 rect-anim" x="50" y="40" width="20" height="20" fill="currentColor"></rect>
<rect class="rect-4 rect-anim" x="70" y="40" width="20" height="20" fill="currentColor"></rect>
</svg>
</div>
发布于 2020-11-26 17:30:33
谢谢,伙计,我学到了一些东西。最后,对于JS的结果,我做了一些非常令人满意的事情。在使用getComputedStyle时,我计算了矩形的高度,并将其更改为我希望添加的转换。我认为可以优化代码,特别是删除定义动画的CSS类的setTimeout部件。如果它不在那里,它就会破坏第四个矩形。
const svg = document.querySelector('#sound__icon')
const btn = document.querySelector('.mute')
const rects = svg.children
let mute = false
function muting(){
if(!mute){
mute = true
for(let rect of rects){
rect.style.height = '30%'
}
}
else{
mute = false
audioAnimActivate()
}
}
function audioAnimActivate(){
for(let rect of rects){
rect.classList.add('rect-anim')
}
svg.classList.add('sound__icon--on')
}
function audioAnimFreeze(){
for(let rect of rects){
let rectHeight = window.getComputedStyle(rect).height
rect.style.height = rectHeight
rect.classList.remove('rect-anim')
rect.style.transition = 'height .5s ease'
rect.style.height = '50%'
}
//? How to code this better ???
setTimeout(() => svg.classList.remove('sound__icon--on'), 16)
}
btn.addEventListener('click', muting)
btn.addEventListener('mouseenter', () => {
if(mute){
rects[0].style.height = '60%'
rects[1].style.height = '20%'
rects[2].style.height = '40%'
rects[3].style.height = '80%'
}
else{
audioAnimFreeze()
}
})
btn.addEventListener('mouseleave', () => {
if(!mute){
audioAnimActivate()
}
else{
for(let rect of rects){
rect.style.height = '30%'
}
}
}) .mute{
width: 25vw;
height: 25vw;
border: none;
display: flex;
justify-content: center;
align-items: center;
background: none;
}
.rect-1, .rect-2, .rect-3, .rect-4{
width: 10%;
height: 30%;
}
.sound__icon--on .rect-anim{
animation-name: sound-icon-anim;
animation-duration: 1s;
animation-timing-function: cubic-bezier(.97,0,0,1);
animation-iteration-count: infinite;
}
.sound__icon--on .rect-1{
animation-delay: .1s;
}
.sound__icon--on .rect-2{
animation-delay: .3s;
}
.sound__icon--on .rect-3{
animation-delay: .5s;
}
.sound__icon--on .rect-4{
animation-delay: .7s;
}
@keyframes sound-icon-anim{
0%{
height: 30%;
}
10%{
height: 70%;
}
20%{
height: 50%;
}
50%{
height: 80%;
}
60%{
height: 100%;
}
70%{
height: 70%;
}
100%{
height: 30%;
}
} <div class="mute">
<svg version="1.1" id="sound__icon" class="sound__icon--on"xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" >
<rect class="rect-1 rect-anim" x="15" fill="currentColor"></rect>
<rect class="rect-2 rect-anim" x="35" fill="currentColor"></rect>
<rect class="rect-3 rect-anim" x="55" fill="currentColor"></rect>
<rect class="rect-4 rect-anim" x="75" fill="currentColor"></rect>
</svg>
</div>
https://stackoverflow.com/questions/65021727
复制相似问题