ExtJs 4.2 - Cancelling/clearing 组件的动画链

ExtJs 4.2 - Cancelling/clearing the animations chain for a component

我正在构建一个网络应用程序,其中有一个部分,如果单击一个按钮,该动画链将执行:

var textReference = Ext.getCmp('splashText');
var checker = Ext.getCmp('arrow');

var img;

//for some reason, the logic is flipped
if(checker){
    img = Ext.getCmp('arrow');
}
else{
    console.log('checker is defined');
    img = Ext.create('Ext.window.Window', {
        header: false,
        style: 'background-color: transparent; border-width: 0; padding: 0',
        bodyStyle: 'background-color: transparent; background-image: url(graphics/arrow_1.png); background-size: 100% 100%;',
        width: 70,
        id: 'arrow',
        height: 70,
        border: false,
        bodyBorder: false,
        frame: false,
        cls: 'noPanelBorder',
        x: textReference.getBox().x - 90,
        y: textReference.getBox().y - 10,
        shadow: false,
    });
}

img.show();

var origW = img.getBox().width,
    origH = img.getBox().height,
    origX = img.getBox().x,
    origY = img.getBox().y;

//go down
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 500,
    delay: 0,
    from: {
        x: textReference.getBox().x - 90,
        y: textReference.getBox().y - 10,
    },
    to: {
        y: origY + 180,
        opacity: 1,
    }
});

//bounce up 1st
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 500,
    delay: 500,
    from: {
    },
    to: {
        y: origY + 50,
    }
});
//fall down 1st
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 500,
    delay: 1000,
    from: {
    },
    to: {
        y: origY + 180,
    }
});

//bounce up 2nd
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 500,
    delay: 1500,
    from: {
    },
    to: {
        y: origY + 100,
    }
});

//fall down 2nd
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 500,
    delay: 2000,
    from: {
    },
    to: {
        y: origY + 180,
    }
});

//fade out
Ext.create('Ext.fx.Anim', {
    target: img,
    duration: 1000,
    delay: 3500,
    from: {
    },
    to: {
        x: textReference.getBox().x - 90,
        y: textReference.getBox().y - 10,
        opacity: 0
    }
});

这只是一个基本的动画,其中 "ball" 会掉落,然后上下弹跳,看起来像是在停留在底部之前先上下弹跳两次,然后淡出。

它运行良好,但是,如果用户在先前的动画链仍在动画时反复单击按钮,动画将会复合并且位置的计算也会复合,使球看起来更低于应有的水平。

为了防止这种情况发生,我想要发生的是一旦按钮被点击,整个动画链首先被取消,然后动画从顶部开始。这是为了确保任何现有的动画都将停止,然后开始一个新的序列。

有人知道如何执行吗?我试过 stopAnimation() 但没有任何反应。

球越来越低的问题是你把原来的Y定义为textReference.getBox().y - 10然后你试着把它移到不同的原来的Y+180。先把你原来的Y设置为textReference.getBox().y - 10 然后将其用于 window 放置、动画开始和其他动画部分。

其次,您应该使用 img.animate() 而不是

Ext.create('Ext.fx.Anim', {
    target: img,

如果这样做,您就可以使用您提到的 stopAnimation() 方法。

示例代码:

var windowId = 'basketBallAnimation';
var img = Ext.getCmp( windowId );

// Set whatever you want here and use it
var originalX = 30;
var originalY = 30;

if( !img )
{
    console.log('creating new image');
    img = Ext.create('Ext.window.Window', {
        header: false,
        style: 'background-color: transparent; border-width: 0; padding: 0',
        bodyStyle: 'background-color: transparent; background-image: url(//ph-live-02.slatic.net/p/6/molten-official-gr7-fiba-basketball-orange-4397-1336487-66ec7bf47676dee873cbb5e8131c4c1f-gallery.jpg); background-size: 100% 100%;',
        width: 70,
        height: 70,
        id: windowId,
        border: false,
        bodyBorder: false,
        frame: false,
        cls: 'noPanelBorder',
        x: originalX,
        y: originalY,
        shadow: false,
    });
}

img.stopAnimation();
img.show();

// go down
img.animate({
    duration: 500,
    from: {
        x: originalX,
        y: originalY,
    },
    to: {
        y: originalY + 180,
    }
});

// ...

工作 fiddle here.

其他 off-topic 对您的编码风格的评论:

  • 不需要保存图片window到'checker',如果'checker'存在再调用Ext.getCmp(),只需要获取图片就可以节省时间,如果未保存,请创建它。
  • 通常更多地使用变量来存储您的数据,而不是多次调用相同的方法(textReference.getBox().x - 90 仅在您的小片段中被调用了三次。如果您想更改它,您必须真正仔细地应用它的其他地方)。
  • 尽可能避免在 ExtJS 中定义任何样式。使用 CSS class 添加 cls 配置,并在单独的 CSS 文件中应用您的样式。