Clutter没有做完整的动画。
这是我目前的代码:
from gi.repository import Clutter, Gtk
import sys
def onClick(actor, event):
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280]) # clutter does not seem to be running this line
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
def main():
Clutter.init(sys.argv)
# Colors
red = Clutter.Color().new(255, 0, 0, 255)
black = Clutter.Color().new(0, 0, 0, 255)
# Create Stage
stage = Clutter.Stage()
stage.set_title("Basic Usage")
stage.set_size(400, 200)
stage.set_color(black)
# Rectangle Actor
actor = Clutter.Rectangle()
actor.set_size(100, 50)
actor.set_position(150, 100)
actor.set_color(red)
actor.set_reactive(True)
actor.connect("button-press-event", onClick)
# Add Actor to the Stage
stage.add_actor(actor)
stage.connect("destroy", lambda w: Clutter.main_quit())
stage.show_all()
Clutter.main()
if __name__ == '__main__':
main()
看看我的问题的这个例子:
对于那些不喜欢GIF的人来说,这是我用语言描述的问题: 我希望演员从中间向右移动,然后一直向左移动。相反,它只是从中间直线向左移动。
造成这种情况的原因是什么,我该如何解决?
答案 0 :(得分:2)
就像ClutterActor.animate()的文档说:
在已经动画化的actor上调用此函数将会 导致当前动画随新的最终值而改变 新的宽松模式和新的持续时间 https://developer.gnome.org/clutter/stable/clutter-Implicit-Animations.html#clutter-actor-animate
表示以下代码:
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
完全等同于:
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
这就是你所看到的。
如果你想连接两个动画,你必须使用completed
函数连接到ClutterAnimation
的{{1}}信号,以便Clutter可以创建一个新动画:
connect_after
我想指出def moveLeft (animation, actor):
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280]).connect_after('completed', moveLeft)
和animatev()
已被弃用;可以使用显式ClutterAnimation
或隐式转换替换它们,例如:
Clutter.KeyframeTransition
它可以比这更复杂;您还需要记住断开from gi.repository import Clutter
Clutter.init(None)
stage = Clutter.Stage()
stage.connect('destroy', lambda x: Clutter.main_quit())
actor = Clutter.Actor()
actor.set_background_color(Clutter.Color.get_static(Clutter.StaticColor.RED))
actor.set_reactive(True)
actor.set_size(32, 32)
stage.add_child(actor)
actor.set_position(82, 82)
def moveLeft(actor):
actor.set_x(20)
def moveRight(actor):
actor.set_easing_duration(1000)
actor.set_easing_mode(Clutter.AnimationMode.LINEAR)
actor.set_x(280)
actor.connect('transition-stopped::x', lambda a, n, t: moveLeft(actor))
actor.connect('button-press-event', lambda a, e: moveRight(actor))
stage.show()
Clutter.main()
信号处理程序,并恢复缓动状态以避免每次更改actor的状态时创建隐式动画,但我会将其作为练习留给读者。
答案 1 :(得分:1)
请尝试以下代码:
def onClick(actor, event):
animation1 = actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
animation1.connect_after(
'completed',
lambda animation: actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
)
答案 2 :(得分:0)
当你紧接着对着这些行
时def onClick(actor, event):
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
Clutter在没有等待对方完成的情况下完成这两项工作。这意味着在第二个命令接管之前,第一个命令几乎没有时间移动代理。
以下是使用“已完成”信号的示例:
def onClick(actor, event):
animate(actor)
def animate(actor):
firstAnimation = actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
firstAnimation.connect_after("completed", moveLeft)
def moveLeft():
self.actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
Here is the documentation on clutter animations
Here is the documentation on the "completed" signal
Here is some working example code