我正在尝试在过渡进度(而不是时间)的一半触发事件。听起来很简单,但是由于过渡可以具有任何曲线,因此非常棘手。在我的特定情况下,它不会被暂停或执行任何操作,因此不会影响您的考虑。
(简化)基本上,我可以在修改器上触发动画,如下所示:
function scaleModifierTo(stateModifier, scale, animationDuration) {
stateModifier.setTransform(
Transform.scale(scale, scale, scale),
{
duration: animationDuration,
curve: this.options.curve
}
);
}
当Transitionable的插值状态达到0.5(半途)时,我想触发一个函数。
我尚未在famo.us的源代码中深入挖掘此问题,但也许需要做一些类似的事情
子类化某些东西,并在状态经过特定点时增加收听的可能性?
反转定义的曲线并使用
setTimeout
(或尝试使用所选曲线算法(ew)的几次迭代来查找接近度)是否可以轻松做到这一点?我应该走哪条路线?
最佳答案
我可以想到几种实现此目的的方法,并且两种方法都适合在StateModifier上使用Modifier。如果您是新手,并且还没有真正探索这些差异的机会,则Modifier会使用transformFrom方法的状态,该方法采用返回转换的函数。在这里,我们可以使用自己的Transitionable在修改器的整个生命周期内提供状态。
为了实现您希望的效果,我使用了带有基本transformFrom的Modifier,它将基于Transitionable的值来更改曲面的X位置。然后,我可以监视可转换对象,以确定何时最接近或在我的情况下大于或等于最终值的一半。在引擎的每个滴答声中都会调用并检查prerender函数,并且在我们击中目标时将取消绑定。
这是一个例子。
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var Transitionable = require('famous/transitions/Transitionable');
var SnapTransition = require('famous/transitions/SnapTransition');
Transitionable.registerMethod('snap',SnapTransition);
var snap = { method:'snap', period:1000, damping:0.6};
var context = Engine.createContext();
var surface = new Surface({
size:[200,200],
properties:{
backgroundColor:'green'
}
});
surface.trans = new Transitionable(0);
surface.mod = new Modifier();
surface.mod.transformFrom(function(){
return Transform.translate(surface.trans.get(),0,0);
});
context.add(surface.mod).add(surface);
function triggerTransform(newValue, transition) {
var prerender = function(){
var pos = surface.trans.get();
if (pos >= (newValue / 2.0)) {
// Do Something.. Emit event etc..
console.log("Hello at position: "+pos);
Engine.removeListener('prerender',prerender);
}
}
Engine.on('prerender',prerender);
surface.trans.halt();
surface.trans.set(newValue,transition);
}
surface.on('click',function(){ triggerTransform(400, snap); });
此示例的缺点是您查询了两次可转换对象。一种替代方法是在transformFrom方法中添加可转换检查。这可能有点奇怪,但是从本质上来说,我们正在修改我们的transformFrom方法,直到达到目标值,然后我们恢复为原始的transformFrom方法。triggerTransform的定义如下。
希望这可以帮助!
function triggerTransform(newValue, transition) {
surface.mod.transformFrom(function(){
pos = surface.trans.get()
if (pos >= newValue/2.0) {
// Do something
console.log("Hello from position: " + pos)
surface.mod.transformFrom(function(){
return Transform.translate(surface.trans.get(),0,0);
});
}
return Transform.translate(pos,0,0)
})
surface.trans.set(newValue,transition);
}