我正在学习反应式编程和rxjs。作为概念验证,我选择了我在应用程序中的交互式动画。该应用程序由36帧(图像)组成。当用户向左/向右拖动鼠标时,帧以循环顺序翻转,产生动画效果。
在36帧中,有四个关键帧(0,9,18,27)。当用户释放鼠标时,动画将继续,直到到达其中一个关键帧。 即当用户在第4帧释放鼠标时,向右拖动时,动画会以间隔显示5,6,7,8,9,然后停止。
我可以在这里找到一个带有我的被动实现的plunker:http://plnkr.co/edit/cM42VkTQgydyofsW47cj?p=preview代替图像,它只显示一个带有帧号的div,以显示这个想法。
这几乎可行。它检测拖动的开始/结束。它用计时器动画。当用户再次开始拖动时,计时器动画会中断。 不起作用的是,当用户停止在特定帧处拖动时,例如如图12所示,计时器动画上升到第18帧并停止。当用户再次开始拖动时,它会翻转回12并从那里开始,而不是从第18帧开始。问题是,我的计时器动画不会更新当前帧编号。
通过将当前帧编号存储在变量中并从流中引用它,可以很容易地解决问题。但它似乎并没有遵循反应模式。我的问题是,如何在流中管理状态(本例中的当前帧)?
我实现帧计算的方式以及下面代码的一些解释。
我创建了三个基于事件的流:panStartStream
用于鼠标按下事件,panStream
用于鼠标移动,panEndStream
用于鼠标移动。
在panStart
中,我使用map生成由panStream
终止的相关平移事件流(panEndStream
)。来自各种rxjs演示的经典示例。这会生成panningStream
个流。在那里我提取mouseX
(map),将两个后续事件合并为一个并确定delta,然后我用它来计算帧增量。
接下来是panningDetectionStream
,它有一个用于平移开始和平移结束的事件。在平移结束时,我存储了最后一个delta,之后我用它来确定基于计时器的动画的方向。
panningRotationStream
就是那个,只要用户正在拖动鼠标,我就会计算显示的帧数。在那里,我简单地用panStream
展平concatAll
s的序列,从增量(scan
)计算累积帧数,并将其标准化为0-35范围以包装动画。
上一个流是rotationStream
。在这里,我将panningRotationStream
和panningDetectionStream
组合在一起,以便在用户停止平移时我可以发现。只要用户正在平移,我就将帧号传递给订户。如果在关键帧上完成平移,我什么都不做。如果在中间帧上完成平移,则在当前帧和主帧之间生成帧序列,每个帧都延迟一些定时器。然后使用concatAll
将其展平为主流。
问题是,我必须在平移时计算帧数。我需要它来确定基于计时器的序列中的帧数。然后在计时器动画中,我需要更新此值,以便下次平移开始时,此值将用作基础。但是我没有看到将这个值推向流的方法。我正在考虑一些选项,比如将两个增量(一个来自平移,一个来自动画)组合成一个帧编号,生成总是8个基于计时器的帧并在合并的流上过滤它们,到达关键帧后等等。我的所有想法都增加了复杂性并且似乎不对。 我怎么能在一个好的和反应性的'方式是什么?