2017-10-12 237 views
1

我一直在玩CSS循环的循环(以下this article)。是否可以在单个CSS转换中结合translateX/translateY和scale?

过渡本身可划分为4(环状)阶段:
shrinked2 =>扩展=> expanded2 =>收缩
这些状态由4个等级表示:
shrinked2 - stateOne
扩大 - stateTwo
expanded2 - stateThree
已收缩2 - stateFour

我是,最初,设置我的元素的宽度和高度,正在过渡,以百分比通过id。然后,为了触发转换,我通过上面列出的状态类来更改transform: scale

直到他的观点,它基本上对我很好,这里是demonstration on JSFiddle

现在,作为下一步,我希望将过渡元素垂直和水平居中置于页面上(并将其保留在此处)。我正在通过在元素ID中添加以下内容来完成此操作:
top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%); 以及在州级别中将transform:附加到translateX(-50%) translateY(-50%)。现在这样scale不适用于元素(即大小不会在转换时更改) - 只有background属性受到影响,转换只发生一次(即不再循环),就好像transitionend从未被触发一样。 这里是the result on JSFiddle。将期望的属性名称(在loopTransition函数中)更改为background,has not effect (JSFiddle)

我完全知道的other方法居中元素。我想了解的是:

  1. 是否有可能在同一个CSS过渡translateX/translateYscale结合
  2. 如果元素与top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%);中心不是(如果是的话,我究竟做错了什么?)与一般的转换或scale兼容,推荐使用的方法是什么?

var the_circle = document.getElementById('circle'); 
 
the_circle.addEventListener("transitionend", loopTransition); 
 

 
function startTransition() { 
 
    var the_circle = document.getElementById('circle'); 
 
    if (the_circle.className === 'stateOne paused') { 
 
     the_circle.style.transitionDuration = 1; 
 
     the_circle.className = 'stateTwo animated'; 
 
    } else { 
 
     stopTransition(); 
 
    } 
 
} 
 

 
function stopTransition() { 
 
    var the_circle = document.getElementById('circle'); 
 
    the_circle.style.transitionDuration = "0.5s" 
 
    the_circle.className = "stateOne paused" 
 
} 
 

 
function loopTransition(e) { 
 
    var the_circle = document.getElementById('circle'); 
 
    if (e.propertyName === "transform") { 
 
     if (the_circle.className.indexOf('paused') !== -1) { 
 
      stopTransition() 
 
     } else { 
 
      if (the_circle.className === "stateTwo animated") { 
 
       the_circle.style.transitionDuration = "1s"; 
 
       the_circle.className = "stateThree animated"; 
 
      } else if (the_circle.className === "stateThree animated") { 
 
       the_circle.style.transitionDuration = "1s"; 
 
       the_circle.className = "stateFour animated"; 
 
      } else if (the_circle.className === "stateFour animated") { 
 
       the_circle.style.transitionDuration = "1s"; 
 
       the_circle.className = "stateOne animated"; 
 
      } else if (the_circle.className === "stateOne animated") { 
 
       the_circle.style.transitionDuration = "1s"; 
 
       the_circle.className = "stateTwo animated"; 
 
      } 
 
     } 
 
    } 
 
}
#circle { 
 
    top: 50%; 
 
    left: 50%; 
 
    transform: translateX(-50%) translateY(-50%); 
 
    position: absolute; 
 
    width: 10%; 
 
    padding-top: 10%; 
 
    border-radius: 50%; 
 
    transition: all 1s; 
 
} 
 

 
.stateOne { 
 
    background: #800080; 
 
    transform: scale(1.0001, 1.0001) translateX(-50%) translateY(-50%); 
 
} 
 

 
.stateTwo { 
 
    background: #ffe6ff; 
 
    transform: scale(2, 2) translateX(-50%) translateY(-50%); 
 
} 
 

 
.stateThree { 
 
    background: #ffe6ff; 
 
    transform: scale(2.0001, 2.0001) translateX(-50%) translateY(-50%); 
 
} 
 

 
.stateFour { 
 
    background: #800080; 
 
    transform: scale(1, 1) translateX(-50%) translateY(-50%); 
 
}
<div id='circle' class="stateOne paused" onclick=startTransition()></div>

+1

你有没有试着用['animation'&'keyframes' ](https://developer.mozilla.org/en-US/docs/Web/CSS/animation)? – Svenskunganka

+0

@Svenskunganka是的,(见:[另一个问题](https://stackoverflow.com/q/46402020/8554766)和[JSFiddle](https://jsfiddle.net/filippw/rpve2e9L/))和它工作得很好。虽然,因为我正在为学习目的而做这些工作,所以我的目标是让它现在用于“过渡”。 –

回答

1
  1. 在CSS中,#id选择优先于.class选择。因此,.state类中的transform声明从未得到应用。解决方案是:

    • 增加您规则的specificity,即#circle.stateTwo

    • !important标志添加到您的声明:

      transform: scale(2, 2) translate(-50%, -50%) !important; 
      

      然而,这应该避免和尽可能使用第一种方法。

  2. 更简单的方法来居中元素,不会与你的动画混合,是用flexbox

    .flex-container { 
        display: flex; 
        align-items: center; 
        justify-content: center; 
        width: 100vw; 
        height: 100vh; 
    } 
    
    #circle { 
        width: 10%; 
        padding-top: 10%; 
        border-radius: 50%; 
        transition: all 1s; 
    } 
    
    .stateOne { 
        background: #800080; 
        transform: scale(1.0001, 1.0001); 
    } 
    
    .stateTwo { 
        background: #ffe6ff; 
        transform: scale(2, 2); 
    } 
    
    .stateThree { 
        background: #ffe6ff; 
        transform: scale(2.0001, 2.0001); 
    } 
    
    .stateFour { 
        background: #800080; 
        transform: scale(1, 1); 
    } 
    
+0

我假设按照百分比“左”和“右”定位并没有考虑到“尺度”变换,但是平移却是这样。我可能稍后会对此进行测试...... – tobiv

+0

第一个建议的方法(使用'#circle.stateTwo')最初居中元素,尽管[失败(JSFiddle)](https://jsfiddle.net/filippw/1cf98h76/3/ )在转换过程中保持居中,我会很感激并解释为什么会发生这种情况。第二,方法(使用flexbox)[工程(JSFiddle)](https://jsfiddle.net/filippw/1cf98h76/4/),因此我想我会坚持下去。无论如何,谢谢你的回答! –

相关问题