Добавьте анимацию, которая будет завершена последовательно при запуске из событий быстрого пользовательского интерфейса - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть настройка приложения three.js, и я пытаюсь добавить хороший переход между двумя моделями.

Он должен быстро уменьшиться до нуля, а затем масштабировать следующую модель с нуля до правильного размера.

Я использую tween.js, и если событие пользовательского интерфейса происходит снова быстро, в то время какпредыдущий все еще оживляет, тогда они заканчивают тем, что пытались бежать вместе и чередовать.

Я просто хочу, чтобы это добавило это в очередь, поскольку у моей твина есть побочные эффекты в обработчике oncomplete.

setActiveBoxTypeByName(name) {
    let rnd = Math.random();
    console.log("starting setActiveBoxTypeByName", rnd);
    let boxToHide = this.scene.getObjectByName(Config.activeBoxName);
    let boxToDisplay = this.scene.getObjectByName(name);

    let originalScaleHide = new THREE.Vector3(0, 0, 0).copy(boxToHide.scale);
    let originalScaleShow = new THREE.Vector3(0, 0, 0).copy(boxToDisplay.scale);

    let tweenScaleToZero = new TWEEN.Tween(boxToHide.scale)
    .to({x: 0, y:0, z: 0}, 150)
    .easing(TWEEN.Easing.Quadratic.In)
    .onComplete(() => {
        boxToHide.visible = false;
        boxToHide.scale.copy(originalScaleHide);
        boxToDisplay.scale.copy(new THREE.Vector3(0,0,0));
        boxToDisplay.visible = true;
        console.log("oncomplete setActiveBoxTypeByName", rnd);
    });

    let tweenScaleUpFromZero = new TWEEN.Tween(boxToDisplay.scale)
    .to(originalScaleShow, 150)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .onComplete(() => {
        Config.activeBoxName = name;
        console.log("oncomplete setActiveBoxTypeByName", rnd);
    });

    tweenScaleToZero.chain(tweenScaleUpFromZero).start();
}

Проблема в том, что он прикреплен к списку переключателей, и если я быстро переключаюсь между ними, он попадает в беспорядок.

Это потому, что два отдельных набора анимацииможет закончить играть в то же время.Я положил туда console.log() s, чтобы доказать, что это именно то, что происходит:

    starting setActiveBoxTypeByName 0.8409190378614766
    oncomplete setActiveBoxTypeByName 0.8409190378614766
    oncomplete setActiveBoxTypeByName 0.8409190378614766
    starting setActiveBoxTypeByName 0.5498841071087592
    oncomplete setActiveBoxTypeByName 0.5498841071087592
    starting setActiveBoxTypeByName 0.16717439330596795 // here
    oncomplete setActiveBoxTypeByName 0.5498841071087592 // here
    oncomplete setActiveBoxTypeByName 0.16717439330596795
    oncomplete setActiveBoxTypeByName 0.16717439330596795

Я не могу придумать способ написать это без побочных эффектов, так как для этого требуется анимация, а затемустановите значение visible в значение false, и я не вижу способа добавить его в существующую очередь.

Есть ли уловка, которую мне не хватает?

1 Ответ

0 голосов
/ 06 октября 2018

Прежде всего, я использую TweenLite, но я думаю, что у вас есть те же методы в Tween.

Я думаю, что вы можете считать, сколько раз вы нажимаете на радио, чтобы подсчитать, какмного анимаций вы должны сделать.Затем вы можете проверить, выполняется ли первая анимация, а вторая должна запускаться методом первого «oncomplete».

Вот пример:

var iterations = 0;
var tweenScaleToZero, tweenScaleUpFromZero;

$('#yourRadioButton').click( function() { iterations++; }

setActiveBoxTypeByName(name) {
    let rnd = Math.random();
    console.log("starting setActiveBoxTypeByName", rnd);
    let boxToHide = this.scene.getObjectByName(Config.activeBoxName);
    let boxToDisplay = this.scene.getObjectByName(name);

    let originalScaleHide = new THREE.Vector3(0, 0, 0).copy(boxToHide.scale);
    let originalScaleShow = new THREE.Vector3(0, 0, 0).copy(boxToDisplay.scale);

    if( ( !tweenScaleToZero.isActive() || tweenScaleToZero === undefined ) && 
        ( !tweenScaleUpFromZero.isActive() || tweenScaleUpFromZero === undefined) ) { 

        tweenScaleToZero = new TWEEN.Tween(boxToHide.scale) 
            .to({x: 0, y:0, z: 0}, 150)
            .easing(TWEEN.Easing.Quadratic.In)
            .onComplete(() => {
            boxToHide.visible = false;
            boxToHide.scale.copy(originalScaleHide);
            boxToDisplay.scale.copy(new THREE.Vector3(0,0,0));
            boxToDisplay.visible = true;
            console.log("oncomplete setActiveBoxTypeByName", rnd);

            tweenScaleUpFromZero = new TWEEN.Tween(boxToDisplay.scale)
                .to(originalScaleShow, 150)
                .easing(TWEEN.Easing.Quadratic.InOut)
                .onComplete(() => {
                    Config.activeBoxName = name;
                    console.log("oncomplete setActiveBoxTypeByName", rnd);
                });

        }).start();

        if( iterations > 0 ) iterations--;

    } else console.log( "Boxes are already animating." );

}
...