首页 > 解决方案 > 同时使用 scaleX 和 translationX (VelocityJS)

问题描述

我有一个从某个百分比填充到另一个百分比(0% - 50%)的条形图。我想将其平滑地设置为一个新的范围(25% - 55%)。这意味着栏的宽度和位置都需要更改。我在同时顺利完成这两项工作时遇到了一些麻烦。

经过一些研究,我发现我需要使用scaleX平滑动画宽度和translateX平滑动画位置(translateX也受比例影响)。现在出现的问题是,条形图将超出所需的百分比 (55%),然后向后移动,如下面的片段所示。

/* Button function to restart. */
const restart = () => {
  animate();
}

const animate = () => {
  /* Reset the bar to its starting position. (from 0% - 50%) */
  Velocity(document.getElementById('movingBar'), {
    scaleX: 0.5,
    translateX: 0
  },
  {
    duration: 0,
    easing: [0, 0, 1, 1]
  });
  
  /* Move the bar to its final position. (from 25% - 55%). */
  /* Split into two velocity calls so that they can have a seperate duration/easing if needed. */
  Velocity(document.getElementById('movingBar'), {
    scaleX: 0.30
  },
  {
    duration: 1000,
    easing: [0, 0, 1, 1],
    queue: false
  });
  
  Velocity(document.getElementById('movingBar'), {
    translateX: (25 / 0.30) + '%'
  },
  {
    duration: 1000,
    easing: [0, 0, 1, 1],
    queue: false
  });
};

/* Start animation on run. */
animate();
#root {
  width: 700px;
  height: 100%;
}

#container {
  width: 100%;
  height: 90px;
  background-color: #000000;
}

.bar {
  width: 100%;
  height: 30px;
  transform: scaleX(0.5);
  transform-origin: left;
  background-color: #FF0000;
}

#description {
  display: flex;
}

.percentage {
  display: flex;
  justify-content: flex-end;
  width: 10%;
  height: 20px;
  text-align: right;
}

.odd {
  background-color: #DDDDDD;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<div id='root' style='width: 100%; height: 100%'>
  <div id='container'>
    <div class="bar" style="background-color: #00FF00;"></div>
    <div id='movingBar' class="bar"></div>
    <div class="bar" style="background-color: #00FF00; transform: scaleX(0.30) translateX(calc(25 / 0.30 * 1%))"></div>
  </div>
  <div id='description'>
    <div class="percentage even">10%</div>
    <div class="percentage odd">20%</div>
    <div class="percentage even">30%</div>
    <div class="percentage odd">40%</div>
    <div class="percentage even">50%</div>
    <div class="percentage odd">60%</div>
    <div class="percentage even">70%</div>
    <div class="percentage odd">80%</div>
    <div class="percentage even">90%</div>
    <div class="percentage odd">100%</div>
  </div>
  <button onClick="restart()">restart</button>
</div>

该示例显示了顶部绿色条中的起始位置,以及它应该在底部绿色条中设置动画的所需位置。中间的红色条是应该从起始位置动画到所需位置的条。如您所见,红色条最终达到了预期的结果,但在超过 55% 之前没有达到。我现在正在使用 VelocityJS 制作动画。

知道我做错了什么或者我将如何制作动画吗?我需要对持续时间/缓动进行一些计算以纠正出现的任何问题吗?

标签: csscss-transformsvelocity.js

解决方案


该问题与如何完成值的插值有关。确保使用 scaleX 和 translateX 进行全局线性变换将是一项艰巨的工作,因为您无法控制值的插值,而浏览器将为您执行此操作。因此,您要么对持续时间/缓动进行复杂计算以找到完美的结果,要么考虑另一种动画。

对于这种情况,clip-path即使支持不是最佳的,我也会考虑,但它会更容易处理,因为您只有一个属性要设置动画,并且您不需要任何复杂的计算,因为您只需要使用图表的百分比。

这是一个简化的示例:

body {
  background:#000;
}
.box {
  height:50px;
  background:red;
  clip-path:polygon(10% 100%,10% 0,     40% 0,40% 100%); /*from [10% 40%]*/
  transition:1s all;
}

body:hover .box {
  clip-path:polygon(50% 100%,50% 0,     60% 0,60% 100%); /*to [50% 60%]*/
}
<div class="box">

</div>


推荐阅读