javascript - 元素上的 CSS 过渡更平滑

标签 javascript css animation css-animations timing

const dot = document.querySelector( `.dot` ).style;

function getRandomInteger( min,max ) {
  min = Math.ceil( min );
  max = Math.floor( max );
  return Math.floor( Math.random() * ( max - min + 1 ) ) + min;
}

// use randomInteger for x and y values 
// for transform: translate( x%,y% )
// range here will be from negative integer 
// to positive integer. The CSS unit is a %
function move( element,range ) { 
  element.transform = 
    `
      translate( 
        ${ getRandomInteger( -range,range ) }%,
        ${ getRandomInteger( -range,range ) }%
      )
    ` 
}

//range here is 250 negative ad positive percent
setInterval( function() { move( dot,250 ) },500 );
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html, body {
  overflow: hidden;
  height: 100%;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #eee;
}
.dot {
  border-style: none;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  background-color: rgba( 0,0,0,0.5 );
  transition-property: transform;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
<hr class='dot'>

上面的代码将一个点移动到页面上的随机位置。

除了从一个位置到另一个位置的转换之外,它按预期工作。 目标是每个 Action 之间的过渡更加平滑。

最初的想法是通过微妙的运动来创建漂浮或悬停的效果,类似于轻轻漂浮在水面上的物体。

我们在最后一个 CSS 行上使用了 transition-timing-function: escape-in​​-out 来尝试减少上面方向变化的突然性。然而,将计时函数更改为任何值似乎并没有多大帮助。包括自定义cubic-bezier值。

我们怎样才能让动画的方向改变不那么突然,并且整体 Action 更加平滑?

最佳答案

您可以通过 JavaScript 创建一个包含关键帧的列表,并根据该列表创建一个新的动画。这样你就可以避免 setInterval 并且浏览器将自己为你的元素设置动画。

如果您想要更平滑的移动,您应该使用更少的随机值并提供位置更平滑的关键帧列表。

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const range = 200;
const steps = 50;

const keyframes = Array.apply(null, Array(50)).map(() => {
  return {
    transform: `translate(${getRandomInteger(-range, range)}%, ${getRandomInteger(-range, range)}%)`
  };
});

document.querySelector('.dot').animate(keyframes, {
  duration: steps * 500, // 0.5 sec for keyframe
  direction: 'alternate',
  fill: 'both',
  iterations: Infinity
});
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  overflow: hidden;
  height: 100%;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #eee;
}

.dot {
  border-style: none;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  background-color: rgba( 0, 0, 0, 0.5);
}
<hr class='dot'>

如果您想实现真正平滑的运动,您应该删除随机化并使用一些数学函数来定义路径。这是基于利萨如曲线的示例,但您可以使用任何其他曲线。

function getLissajousCurve(radius, steps, a, b, d, A, B) {
  const result = [];
  for (let t = 0; t <= 2 * Math.PI; t += Math.PI / steps) {
    const x = radius * A * Math.sin(a * t + d);
    const y = radius * B * Math.sin(b * t);
    result.push([x, y]);
  }
  return result;
}

const steps = 50;

const curve = getLissajousCurve(200, steps, 4, 5, 0, 1, 1);

const keyframes = curve.map(([x, y]) => {
  return {
    transform: `translate(${x}%, ${y}%)`
  };
});

document.querySelector('.dot').animate(keyframes, {
  duration: steps * 500, // 0.5 sec for keyframe
  direction: 'alternate',
  fill: 'both',
  iterations: Infinity
});
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  overflow: hidden;
  height: 100%;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #eee;
}

.dot {
  border-style: none;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  background-color: rgba( 0, 0, 0, 0.5);
}
<hr class='dot'>

关于javascript - 元素上的 CSS 过渡更平滑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68368259/

相关文章:

php - 动态创建带有悬停文本的 "button"图像

javascript - 从左侧和右侧计算溢出的列表项。 (不是顶部/底部)

css - 在 index.html 中导入 css 和在 Angular 5 中导入 styleUrls 之间的区别

javascript - 如何动态改变元素对齐方式?

javascript - 在 React 中为 div 列表设置动画

javascript - 流类型 : Field between square brackets

javascript - 如何使用 JavaScript 获取 URI 参数 - 查询字符串?

html - 如何使用 Tab 键使 Toggle 按钮可聚焦

jquery - 切换类 : How does this CSS work?

ios - 如何像 iPhone 设置搜索栏一样打开 UISearchBar?