我正在尝试在过渡进度(而不是时间)的一半触发事件。听起来很简单,但是由于过渡可以具有任何曲线,因此非常棘手。在我的特定情况下,它不会被暂停或执行任何操作,因此不会影响您的考虑。

(简化)基本上,我可以在修改器上触发动画,如下所示:

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);

}

07-25 20:50