• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

Popmotion 简介:指针和物理

欢迎回到 Popmotion 简介系列教程。在第 1 部分中,我们发现了如何使用补间和关键帧来制作精确的、按时间安排的动画

在第 2 部分中,我们将研究指针跟踪和基于速度的动画。

指针跟踪允许我们创建可滚动的产品货架、自定义值滑块或拖放界面。

基于速度的动画与基于时间的动画(如补间)不同,影响动画行为方式的主要属性是 velocity动画本身可能需要任何时间。

我们将看看 Popmotion 中的三个基于速度的动画 spring,  decay、 和 physics我们将使用 velocity指针跟踪动画来启动这些动画,这将演示基于速度的动画如何以基于时间的动画无法创建的方式创建引人入胜且有趣的 UI。

首先,打开这个 CodePen一起玩。

指针跟踪

Popmotion 提供了 跟踪和输出鼠标或单点触摸指针坐标的pointer功能。

让我们将它与 一起导入 styler,这将允许我们设置球的位置

const { pointer, styler } = popmotion;

const ball = document.queryselector('.ball');
const ballStyler = styler(ball);

对于此示例,我们要拖动球。让我们添加一个事件,将指针的位置输出到球:

let pointerTracker;

const startTracking = () => {
  pointerTracker = pointer().start(ballStyler.set);
};

ball.addeventListener('mousedown', startTracking);
ball.addEventListener('touchstart', startTracking);

我们还需要一些代码在我们释放球时停止跟踪:

const stopTracking = () => pointerTracker && pointerTracker.stop();

document.addEventListener('mouseup', stopTracking);
document.addEventListener('touchend', stopTracking);

如果您现在尝试拖动球,就会出现明显的问题。当我们触摸它时,球会跳开!不是很好的用户体验。

这是因为,默认情况下, pointer输出指针 相对于页面的位置。

要输出指针 相对于另一个点的位置,在这种情况下是球的 x/y 变换,我们可以简单地将该位置传递给 pointer这样的:

const startTracking = () => {
  pointerTracker = pointer({
    x: ballStyler.get('x'),
    y: ballStyler.get('y')
  }).start(ballStyler.set);
};

现在你已经用很少的几行代码让球可以拖动了!然而,当用户释放球时,它就停止了。

这并不令人满意:想象一个可滚动的产品轮播,用户可以拖动它来滚动。如果它只是停止而不是动量滚动,那么使用起来会不太愉快。

这也会更难,因为滚动轮播所需的整体体力会更高。

要启用这样的动画,我们首先需要知道 velocity被抛出的对象的类型。

跟踪速度

Popmotion 提供了一个可以帮助我们跟踪速度的功能。它被称为 value让我们导入:

const { pointer, styler, value } = popmotion;

暂时从技术上讲,Popmotion 的所有动画都称为 动作动作是可以启动和停止的反应性值流。

value相反,  A是一个反应它无法停止或启动。它只是在 update调用其方法时被动响应。它可以跟踪值并可以用来查询它们的速度。

所以,在我们定义之后 ballStyler,让我们定义一个新 value的 for  ballXY

const ballXY = value({ x: 0, y: 0 });

每当 ballXY更新时,我们都想更新 ballStyler我们可以将第二个参数传递给 value,该函数将在 ballXY更新时运行:

const ballXY = value({ x: 0, y: 0 }, ballStyler.set);

现在我们可以重写我们 pointer的更新 ballXY而不是ballStyler.set

const startTracking = () => {
  pointer(ballXY.get())
    .start(ballXY);
};

现在,在任何指针处,我们都可以调用 ballXY.getVelocity()并且我们将接收到 和 的速度 x, y准备好插入我们基于速度的动画。

基于速度的动画

spring

要介绍的第一个基于速度的动画是 spring它基于管理 Apple 的 CASpringAnimation 的相同方程式,即所有ios弹性俏皮背后的弹簧动画。

进口:

const { pointer, spring, styler, value } = popmotion;

现在,修改 stopTracking它不是停止pointerTracker动画,而是像这样开始一个 spring动画:

const stopTracking = () => spring({
  from: ballXY.get(),
  velocity: ballXY.getVelocity(),
  to: 0,
  stiffness: 100,
  damping: 20
}).start(ballXY);

我们向它提供球的当前位置、速度和目标,然后运行模拟。它会根据用户投球的方式而变化。

弹簧最酷的地方在于它们富有表现力。通过调整 mass、 stiffness和 damping属性,您可以得到完全不同的弹簧感觉。

例如,如果您仅将 stiffness上述更改为 1000,则可以创建一个感觉就像高能捕捉的动作。然后,通过更改 mass为 20,您可以创建看起来几乎像重力的运动。

几乎在任何情况下,总有一种组合会让您的用户感到正确和满意,并且适合您的品牌。通过玩不同的弹簧感觉,您可以传达不同的感觉,例如严格的出界快照或更柔和的肯定弹跳。

decay

decay 动画,顾名思义, 衰减提供的  速度,使动画逐渐减慢到完全停止。

这可用于创建智能手机上的动量滚动效果,如下所示:

导入 decay 函数:

const { decay, pointer, spring, styler, value } = popmotion;

并将 函数替换为 以下内容:stopTracking

const stopTracking = () => decay({
  from: ballXY.get(),
  velocity: ballXY.getVelocity()
}).start(ballXY);

decay 根据提供的 from 和 velocity 道具自动计算一个新的目标。

可以通过弄乱上面链接的文档中概述的道具来调整减速的感觉,但与 spring and 不同的是physics, decay 它被设计为开箱即用。 

physics

最后,我们有了 physics动画这是 Popmotion 的基于速度的动画的瑞士军刀。有了它,你可以模拟:

  • 等速

  • 加速度

  • 弹簧

  • 摩擦

spring并 decay提供超精确的运动和更广泛的“感觉”。很快,它们都将是可擦洗的。

但两者都是 不可变的。一旦你开始了,它们的属性就一成不变了。当我们想要基于初始 from/velocity状态启动动画时非常适合,但如果我们想要持续交互则不是那么好。

physics相反,它是一种 更接近视频游戏集成模拟。它的工作原理是,每帧一次,获取当前状态,然后根据该时间点的当前属性对其进行修改。

这允许它是 mutable,这意味着我们可以更改这些属性,然后更改模拟的结果。

为了证明这一点,让我们对经典的指针平滑进行扭曲,使用弹性平滑。

进口 physics

const { pointer, spring, physics, styler, value } = popmotion;

这一次,我们要改变 startTracking功能。我们将使用 , 而不是更改 ballXYwith  pointerphysics

const startTracking = () => {
  const physicsAnimation = physics({
    from: ballXY.get(),
    to: ballXY.get(),
    velocity: ballXY.getVelocity(),    restSpeed: false,
    friction: 0.6,
    springStrength: 400
  }).start(ballXY);
};

在这里,我们正在设置 from和 velocity正常。 friction并且 springStrength都调整了弹簧的属性。

restSpeed: false覆盖运动停止时动画停止的默认行为。我们想手动停止它 stopTracking

就其本身而言,这个动画不会做任何事情,因为我们将 to弹簧的目标 设置为与 相同 from所以 pointer这次让我们重新实现跟踪来改变 physics在 的最后一行 startTracking,添加:

pointerTracker = pointer(ballXY.get()).start((v) => {
  physicsAnimation.setSpringTarget(v);
});

在这里,我们使用与 pointer以前类似的动画。除了这一次,我们用它来改变另一个动画的目标。为此,我们创建了这个弹性指针跟踪:

结论

基于速度的动画与指针跟踪配对可以创建引人入胜且有趣的界面。

spring可用于创建各种弹簧感觉,同时 decay专为动量滚动动画量身定制。 physics在可配置性方面比任何一种都更有限,但也提供了改变正在进行的模拟的机会,开辟了新的交互可能性。


文章目录
  • 指针跟踪
  • 跟踪速度
  • 基于速度的动画
    • spring
    • decay
    • physics
  • 结论