Implement basic animation
This commit is contained in:
parent
a292b642e1
commit
1e3af85c40
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
import math
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
@ -8,10 +9,24 @@ from sugar.scene.Stage import Stage
|
|||||||
from sugar.scene.Group import Group
|
from sugar.scene.Group import Group
|
||||||
from sugar.scene.PixbufActor import PixbufActor
|
from sugar.scene.PixbufActor import PixbufActor
|
||||||
from sugar.scene.CircleLayout import CircleLayout
|
from sugar.scene.CircleLayout import CircleLayout
|
||||||
|
from sugar.scene.Timeline import Timeline
|
||||||
|
|
||||||
def drawing_area_expose_cb(widget, event, stage):
|
def __drawing_area_expose_cb(widget, event, stage):
|
||||||
stage.render(widget.window)
|
stage.render(widget.window)
|
||||||
|
|
||||||
|
def __next_frame_cb(timeline, frame_num, group):
|
||||||
|
angle = math.pi * 2 / timeline.get_n_frames() * frame_num
|
||||||
|
group.get_layout().set_angle(angle)
|
||||||
|
group.do_layout()
|
||||||
|
|
||||||
|
drawing_area.window.invalidate_rect(None, False)
|
||||||
|
|
||||||
|
def __completed_cb(timeline, group):
|
||||||
|
group.get_layout().set_angle(0)
|
||||||
|
group.do_layout()
|
||||||
|
|
||||||
|
drawing_area.window.invalidate_rect(None, False)
|
||||||
|
|
||||||
stage = Stage()
|
stage = Stage()
|
||||||
|
|
||||||
pixbuf = gtk.gdk.pixbuf_new_from_file('background.png')
|
pixbuf = gtk.gdk.pixbuf_new_from_file('background.png')
|
||||||
@ -26,7 +41,7 @@ while i <= 5:
|
|||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
layout = CircleLayout(100)
|
layout = CircleLayout(100)
|
||||||
icons_group.set_layout_manager(layout)
|
icons_group.set_layout(layout)
|
||||||
|
|
||||||
stage.add(icons_group)
|
stage.add(icons_group)
|
||||||
|
|
||||||
@ -34,10 +49,15 @@ window = gtk.Window()
|
|||||||
window.set_default_size(640, 480)
|
window.set_default_size(640, 480)
|
||||||
|
|
||||||
drawing_area = gtk.DrawingArea()
|
drawing_area = gtk.DrawingArea()
|
||||||
drawing_area.connect('expose_event', drawing_area_expose_cb, stage)
|
drawing_area.connect('expose_event', __drawing_area_expose_cb, stage)
|
||||||
window.add(drawing_area)
|
window.add(drawing_area)
|
||||||
drawing_area.show()
|
drawing_area.show()
|
||||||
|
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
|
timeline = Timeline(stage, 100)
|
||||||
|
timeline.connect('next-frame', __next_frame_cb, icons_group)
|
||||||
|
timeline.connect('completed', __completed_cb, icons_group)
|
||||||
|
timeline.start()
|
||||||
|
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
@ -7,13 +7,17 @@ class CircleLayout(LayoutManager):
|
|||||||
LayoutManager.__init__(self)
|
LayoutManager.__init__(self)
|
||||||
|
|
||||||
self._radium = radium
|
self._radium = radium
|
||||||
|
self._angle = 0
|
||||||
|
|
||||||
|
def set_angle(self, angle):
|
||||||
|
self._angle = angle
|
||||||
|
|
||||||
def layout_group(self, group):
|
def layout_group(self, group):
|
||||||
step = 2 * math.pi / len(group.get_actors())
|
step = 2 * math.pi / len(group.get_actors())
|
||||||
angle = 2 * math.pi
|
angle = self._angle
|
||||||
for actor in group.get_actors():
|
for actor in group.get_actors():
|
||||||
self._update_position(actor, angle)
|
self._update_position(actor, angle)
|
||||||
angle -= step
|
angle += step
|
||||||
|
|
||||||
def _update_position(self, actor, angle):
|
def _update_position(self, actor, angle):
|
||||||
x = math.cos(angle) * self._radium + self._radium
|
x = math.cos(angle) * self._radium + self._radium
|
||||||
|
@ -3,24 +3,29 @@ from sugar.scene.Actor import Actor
|
|||||||
class Group(Actor):
|
class Group(Actor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._actors = []
|
self._actors = []
|
||||||
self._layout_manager = None
|
self._layout = None
|
||||||
|
|
||||||
def add(self, actor):
|
def add(self, actor):
|
||||||
self._actors.append(actor)
|
self._actors.append(actor)
|
||||||
if self._layout_manager:
|
self.do_layout()
|
||||||
self._layout_manager.layout_group(slef)
|
|
||||||
|
|
||||||
def remove(self, actor):
|
def remove(self, actor):
|
||||||
self._actors.remove(actor)
|
self._actors.remove(actor)
|
||||||
if self._layout_manager:
|
self.do_layout()
|
||||||
self._layout_manager.layout_group(self)
|
|
||||||
|
|
||||||
def get_actors(self):
|
def get_actors(self):
|
||||||
return self._actors
|
return self._actors
|
||||||
|
|
||||||
def set_layout_manager(self, layout_manager):
|
def set_layout(self, layout):
|
||||||
self._layout_manager = layout_manager
|
self._layout = layout
|
||||||
self._layout_manager.layout_group(self)
|
self.do_layout()
|
||||||
|
|
||||||
|
def get_layout(self):
|
||||||
|
return self._layout
|
||||||
|
|
||||||
|
def do_layout(self):
|
||||||
|
if self._layout:
|
||||||
|
self._layout.layout_group(self)
|
||||||
|
|
||||||
def render(self, drawable):
|
def render(self, drawable):
|
||||||
for actor in self._actors:
|
for actor in self._actors:
|
||||||
|
@ -3,3 +3,7 @@ from sugar.scene.Group import Group
|
|||||||
class Stage(Group):
|
class Stage(Group):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Group.__init__(self)
|
Group.__init__(self)
|
||||||
|
self._fps = 50
|
||||||
|
|
||||||
|
def get_fps(self):
|
||||||
|
return self._fps
|
||||||
|
33
sugar/scene/Timeline.py
Normal file
33
sugar/scene/Timeline.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import gobject
|
||||||
|
|
||||||
|
class Timeline(gobject.GObject):
|
||||||
|
__gsignals__ = {
|
||||||
|
'next-frame': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([int])),
|
||||||
|
'completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, stage, n_frames):
|
||||||
|
gobject.GObject.__init__(self)
|
||||||
|
|
||||||
|
self._stage = stage
|
||||||
|
self._fps = stage.get_fps()
|
||||||
|
self._n_frames = n_frames
|
||||||
|
self._current_frame = 0
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
gobject.timeout_add(1000 / self._fps, self.__timeout_cb)
|
||||||
|
|
||||||
|
def get_n_frames(self):
|
||||||
|
return self._n_frames
|
||||||
|
|
||||||
|
def __timeout_cb(self):
|
||||||
|
self.emit('next-frame', self._current_frame)
|
||||||
|
|
||||||
|
# FIXME skip frames if necessary
|
||||||
|
self._current_frame += 1
|
||||||
|
|
||||||
|
if self._current_frame < self._n_frames:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.emit('completed')
|
||||||
|
return False
|
Loading…
Reference in New Issue
Block a user