旋转元素也会更改CSS动画中的scaleX

时间:2019-02-24 02:36:43

标签: javascript css animation

我有五个图像元素,每个图像元素包含一张羽毛图片。我想将它们添加到DOM中,其中一些以任意旋转角度随机向右或向左翻转。

我希望每根羽毛都进行动画处理,以使其与X轴对齐(即回到0度),同时还要保持scaleX。在下面的代码中,重新排列有效,但是对于翻转的羽毛,它们还会在动画过程中扭曲原始的“未翻转”外观。

如何防止这种情况发生?我知道我可以通过使用<div>作为每根羽毛的包装纸来实现此目的,但是有更好的解决方案吗?

JavaScript

function feathersPuff() {

    for (let i = 0; i < 5; i++) {

        let feather = document.createElement("img");

        feather.src = "imgs/feather" + i + ".svg";

        document.body.appendChild(feather);

        let plusOrMinus = Math.random() < 0.5 ? -1 : 1;

        feather.style.transform = "scaleX(" + plusOrMinus + ") rotate(" + getRandomInt(50) * plusOrMinus + "deg)"

        feather.classList.add("feather");    
    }    
}

CSS

.feather {    
    display: block;
    height: 2%;
    position: absolute;

    animation: realign;
    animation-iteration-count: 1;
    animation-direction: linear;
    animation-timing-function: ease-in-out;
    animation-duration: 500ms;
    animation-delay: 0;
    animation-fill-mode: forwards;        
}

@keyframes realign {

    100% { transform: rotate(0deg) }
}

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,那么一个解决方案可能是定义两个动画,其中一个动画的最终转换与否定的羽毛预乘以负数scaleX(以确保它不会产生)动画过程中不希望出现的“翻转” /扭曲):

/* 
Define flipped feather animation with positive scale (redundant)
*/
@keyframes regular {
  100% {
    transform: scaleX(1) rotate(0deg)
  }
}

/* 
Define flipped feather animation with negated scale. Assuming the 
starting transform has scaleX(-1), this animation will stop the 
twisting effect from happening 
*/
@keyframes flipped {
  100% {
    transform: scaleX(-1) rotate(0deg)
  }
}

在定义了这两个动画之后,您还可以定义相应的修饰符类以将其随机选择并应用于羽毛元素:

function getRandomInt() {
  return Math.random() * 180;
}

function feathersPuff() {

  for (let i = 0; i < 10; i++) {

    let feather = document.createElement("img");

    /* Placeholder image - replace this with your svg */
    feather.src = "https://pngriver.com/wp-content/uploads/2017/12/download-free-birds-feather-png-transparent-images-transparent-backgrounds-feather_PNG12958-300x160.png";

    document.body.appendChild(feather);

    /* Randomly orrientate feather */
    if (Math.random() < 0.5) {

      /* If regular orrientation, then apply regular modifier class which
      will use the "regular" animation (without scaling) */
      feather.classList.add("regular");
      feather.style.transform =
        "rotate(" + getRandomInt(50) + "deg)";
    } else {

      /* If flipped orrientation, then apply flipped modifier class which
      will apply the "flipped" animation (with negated scaling factored in) */
      feather.classList.add("flipped");
      feather.style.transform =
        "scaleX(-1) rotate(" + getRandomInt(50) + "deg)"
    }
    
    feather.classList.add("feather");
  }
}

feathersPuff();
/* Define flipped feather animation with positive scale (redundant)*/
@keyframes regular {
  100% {
    transform: scaleX(1) rotate(0deg)
  }
}

/* Define flipped feather animation with negated scale */
@keyframes flipped {
  100% {
    transform: scaleX(-1) rotate(0deg)
  }
}

/* Modifier class which animates feathers of the "regular orientation" */
.feather.regular {
  animation-name: regular;
}

/* Modifier class which animates feathers of the "flipped orientation" */
.feather.flipped {
  animation-name: flipped;
}

.feather {
  height: 30px;
  display: block;
  /* position: absolute; Removed this to prevent feathers overlapping to better
  demonstrate the techniques final result */
  animation-iteration-count: 1;
  animation-direction: linear;
  animation-timing-function: ease-in-out;
  animation-duration: 2500ms;
  animation-fill-mode: forwards;
}