我正在使用帧运动(react )来制作一个包含100张幻灯片的滑块的动画.动画只是将幻灯片相对于视区向左移动,以便目标幻灯片直接位于中间并聚焦.目标幻灯片是动态确定的,所以我遇到的问题是,对于硬编码的动画持续时间(3s),如果目标幻灯片是幻灯片100,它看起来非常陡峭和快速,如果它是幻灯片3,则看起来非常慢.

我正在寻找的是一个公式,它将采取我的目标幻灯片(1-100),并使其趋于理想的动画持续时间,比方说3秒.因此,如果从幻灯片1到幻灯片3设置动画,可能需要1秒,但如果从幻灯片1到100设置动画,可能需要大约5秒.

我相信这是可以优雅地完成的,但我的数学不是最好的.也许是一种互惠的功能?我已经try 过简单地设置断点(例如,如果目标在10秒之外,则将持续时间设置为1秒;否则,如果目标在20秒之外,则将持续时间设置为2秒,等等),但我想用更少的代码来解决这个问题.

如有建议,敬请指教.

推荐答案

而不是简单地提供给你的公式,我想推你的"I'm not greatest at maths"位.我将带你通过逻辑步骤计算出公式,并告诉你,一旦你知道如何把它拆开,它不再是魔术,但可行的.


假设我们希望5s张幻灯片上的动画拍摄5s张,相邻幻灯片之间的动画拍摄1s张.

This means each animation takes 1s plus some extra time, based on additional slides travelled.
We put the second aside for now (we'll add it back in the end) and look for a relation between extra slides travelled and extra time added. We have 0s extra time without any additional slide and 4s with 99 additional slides, which gives us:

additional slides travelled extra time (s) total time (s)
0 0 1
99 4 5
x x * 4/99 1 + (x * 4/99)

公式用rule of three(x * 4 = 99 * y)来确定,因为额外的滑梯行程和额外时间之间的关系是正比的.102

作为函数,上述总时间公式为:x => 1 + x * 4/99,其中:

  • 1等于minDuration
  • x是额外移动的幻灯片的数量,所以是indexesDiff - 1
  • 4等于maxDuration - minDuration
  • 99totalSlides - 1

这给了我们:

const [minDuration, maxDuration, totalSlides] = [1, 5, 100]
const getDuration = (distance = 1) =>
  minDuration +
  ((distance - 1) * (maxDuration - minDuration)) / (totalSlides - 1)

其中distance是动画开始幻灯片和结束幻灯片之间的索引差.

让我们来看看它的实际效果:

const { computed, reactive, createApp } = Vue
const [min, max, total] = [1, 5, 100]
const state = reactive({
  distance: 1,
  total,
  d: computed(() => min + ((max - min) * (state.distance - 1)) / (total - 1)),
  duration: computed(() => (Math.round(state.d * 1e3) / 1e3).toFixed(3))
})

createApp({
  setup: () => state
}).mount('#app')
#app {
  font-family: monospace
}
<script src="https://cdn.jsdelivr.net/npm/vue@3.3.9/dist/vue.global.prod.js"></script>
<div id="app">
  <label>
    distance:
    <input
      type="range"
      min="1"
      :max="total"
      v-model.number="distance"
    />
  </label>
  {{ distance }} slide{{ distance === 1 ? '' : 's' }}
  <div>duration: {{ duration }}s</div>
</div>


100--换句话说,我们把最多的额外时间分成和最多额外幻灯片一样多的部分,对于每一张额外的幻灯片,我们增加等量的时间.

Reactjs相关问答推荐

过滤对象数组并通过迭代对象数组将属性放入新数组

sourceBuffer. appendBuffer成功,但h5视频播放器卡住了

如何使用皮金贴图在Reactjs中制作 map 上的点之间的线的动画?

无法在主组件的返回语句中呈现预期组件

有没有一种方法可以在没有强烈动画的情况下有条件地渲染组件?

StrictMode+SetInterval=双重渲染(即使使用useEffect清理)

通过createRoot创建的React元素无法调用Provider值

在reduce()方法上得到NaN

在React中使用if条件时如何更改Tailwind中元素的文本 colored颜色

对于 ref 上的可见 prop 或 open 方法来react 组件,哪种方式更好?

数据表格组件需要所有行都具有唯一的ID属性.或者,您可以使用getRowId属性.

ReactJS中使用setState方法时,Context内部的State未进行更新

将水平滚动视图添加到底部导航选项卡

基于标记名的博客详细信息分组没有发生

如何在不重新加载页面的情况下加载新添加的数据?

将路径数组传递给Route会引发错误

使用 React.UseEffect 从 api 获取但我的清理返回不起作用

ReactJs 行和列

用 scss 覆盖 MUI

哪个是创建 React 应用程序的更好方法?