是否可以在单个CSS过渡中组合translateX / translateY和scale?

时间:2017-10-12 08:39:16

标签: javascript html css css-transitions transitions

我一直在玩CSS转换的循环(this article之后)。

过渡本身可分为4个(循环)阶段:
shrinked2 =>膨胀=> expanded2 =>收缩
这些状态由4个类表示:
shrinked2 - stateOne
扩展 - stateTwo
expanded2 - stateThree
shrinked2 - 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属性受到影响,转换只发生一次(即它不再循环),就好像loopTransition从未被解雇过。 这是the result on JSFiddle。将预期的媒体资源名称(background功能)更改为translateXhas not effect (JSFiddle)

我完全清楚lotsother方法可以使元素居中。我想了解的是:

  1. 是否可以在同一个CSS过渡中合并translateY / scaletop: 50%; left: 50%; transform: translateX(-50%) translateY(-50%);(如果是,我做错了什么?)
  2. 如果以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"; } } } }不兼容,建议使用哪种方法?
  3. #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>
    react-native run-android

1 个答案:

答案 0 :(得分:1)

  1. 在CSS中,#id选择器优先于.class选择器。因此,transform类中的.state声明永远不会被应用。解决方案是:

    • 增加规则的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);
    }