2017-10-12 239 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/),因此我想我會堅持下去。無論如何,謝謝你的回答! –

相關問題