在paperjs中链接补间

问题描述

我正在尝试在 paperjs 中链接补间,但由于某种原因,start()tween 函数在另一个间的 then() 函数中不起作用。如果我在外面调用 start() 函数,它会起作用。解决这个问题的唯一方法是,如果我在 then() 函数中定义了补间,但在我看来,我的链接错误的,.then() 如何与 Promise 链接错误



var size = new Size(605,605);
var back = new Path.Rectangle(view.center-size/2,size);
back.fillColor = 'black';

project.currentStyle = {
    strokeColor: 'white',strokeWidth: 4,strokeCap: 'round'
}

var ln = 150;
var group = new Group();
var line1 = new Path.Line(
    {x: view.center.x + ln/2,y: view.center.y - ln},{x: view.center.x + ln/2,y: view.center.y - ln*2/3});
group.addChild(line1);

var lineh1 = new Path.Line(
    {x: view.center.x + ln/2,y: view.center.y - ln*2/3},{x: view.center.x - ln/3,y: view.center.y - ln*2/3});
var arc1 = new Path.Arc(
    {x: view.center.x - ln/3,{x: view.center.x - ln/3 - ln/4-ln/12,y: view.center.y - ln*1/3},y: view.center.y });
var ref1 = {x: view.center.x + ln/4,y: view.center.y};
var ref2 = {x: view.center.x + ln/2 + ln/4,y: view.center.y - ln/8};
var lineh2 = new Path.Line(
    {x: view.center.x - ln/3,y: view.center.y},{x: view.center.x + ln/4,y: view.center.y});
var arc2 = new Path.Arc(
    {x: view.center.x + ln/4,{x: view.center.x + ln/4 + ln/4+ln/4,y: view.center.y + ln/2},y: view.center.y + ln});
var lineh3 = new Path.Line(
    {x: view.center.x + ln/4,y: view.center.y + ln},{x: view.center.x - ln/3 - ln/4,y: view.center.y + ln})
group.addChildren([lineh1,arc1,lineh2,arc2,lineh3]);    
// group.scale(0.8,1);
// var groupC = group.clone().scale(-1,1);
// var arc1C = arc1.clone().scale(-1,1,view.center);
// var arc2C = arc2.clone().scale(-1,view.center);
var arc1C = arc1.clone();
var arc2C = arc2.clone();
arc1C.visible = false;
arc2C.visible = false;

// arc1C.scale(1.2,-1.5,arc1C.lastSegment.point);
// arc2C.scale(0.8,-0.67,arc2C.firstSegment.point);


// animations
var tspan = 4000;
var amp = 0.1;


var t1a1 = arc1C.tween(
    {'firstSegment.point': arc2.lastSegment.point,'firstSegment.handleOut': arc2.lastSegment.handleIn,'lastSegment.point': arc2.firstSegment.point,'lastSegment.handleIn': arc2.firstSegment.handleOut,'segments[1].point': arc2.segments[1].point,'segments[1].handleIn': arc2.segments[1].handleIn*-1,'segments[1].handleOut': arc2.segments[1].handleOut*-1
    },{   
        duration: tspan,start: false,});
var t1a2 = arc2C.tween(
    {'lastSegment.point': arc1.firstSegment.point,'lastSegment.handleIn': arc1.firstSegment.handleOut,'firstSegment.point': arc1.lastSegment.point,'firstSegment.handleOut': arc1.lastSegment.handleIn,'segments[1].point': arc1.segments[1].point,'segments[1].handleIn': arc1.segments[1].handleIn*-1,'segments[1].handleOut': arc1.segments[1].handleOut*-1
    },});

// t1a1.start();

var t1 = arc2.tween(tspan)
t1.onUpdate = function(event) {
    var times = tspan/1000 * 61;
    var t = event.factor*times/6;
    var f = Math.sin(t);
    twerk(t,f);
}
t1.then(function() {
    console.log('hello');
    arc1C.visible = true;
    arc2C.visible = true;
    arc1C.scale(-1,view.center);
    arc2C.scale(-1,view.center);
    t1a1.start();
    t1a2.start();
})

function twerk(t,f) {
    arc2.shear(0,-Math.sin(t*2)*0.06,arc2.firstSegment.point);
    arc1.scale(1 + f*0.02,1)
    arc2C.shear(0,Math.sin(t*2)*0.06,arc2C.firstSegment.point);
    arc1C.scale(1 + f*0.02,1)
}


var linetop = new Path.Line(
            {x: view.center.x - ln + ln/8,{x: view.center.x + ln - ln/8,y: view.center.y - ln}
            )
linetop.style = {
    strokeColor: '#fae0e4',strokeWidth: 15,strokeCap: 'butt'
}

解决方法

我在开始使用 Tween 时遇到了同样的问题。 发生这种情况是因为当您创建 Tween 时,它绑定到对象的当前状态,因此当对象在动画期间发生更改时,所有先前创建的 Tween 都不起作用。

我的解决方案是使用回调创建补间结构

看起来像这样:

function getTween(object,tweenDescr,tweenOptions){
    // DEFAULTS
    tweenOptions = tweenOptions || { duration: 2000,start: false };
    return function(callback){
        tw = object.tweenTo(tweenDescr,tweenOptions);
        tw.start();
        tw.then(function(){
            callback && callback();
        })
    }
}

这就是我使用它的方式:

var circle = new Path.Circle({
    center: view.center,radius: 40,fillColor: 'blue'
});

var one = getTween(circle,{fillColor: 'red'});
var two = getTween(circle,{fillColor: 'green'});
var three = getTween(circle,{fillColor: 'blue'});

one(function(){
    two(function(){
        three();
    });
});

如果您想避免“回调地狱”,您可以使用 async.js 及其 eachSeries 或类似实用程序

用法如下:

async.eachSeries([one,two,three],function(tweenOperation,callback) {
    tweenOperation(callback);
},function(err) {
    console.log('all done');
});

Here's my sketch with callback-hell