Clipping actors (and groups of groups of... etc.) into a path shape
So, you have a shape and you want to force all the children in that Group (groups are Actors) to show within that path? Here you go:
import clutterAdventures in Time(line)
from clutter import cogl
"""
pyClutter 1.0
Demonstration of how to clip groups to a path.
"""
zoom = 1
def zoomify(obj,evt):
global zoom
if evt.direction == clutter.SCROLL_UP:
zoom += .1
else:
zoom -= .1
# When the zoom gets small, the cogl clip goes all wonky...
obj.set_scale(zoom, zoom)
class ClipGroup(clutter.Group):
""" Custom Group to perform clipping from a path."""
# Vital line.
# Registers the specified Python class as a PyGTK type.
# Also enables the do_paint method. I am not sure why...
__gtype_name__ = 'ClipGroup'
def __init__(self,w,h):
clutter.Group.__init__(self)#,*args)
self.width, self.height = w, h
def do_paint(self):
# Draw a triangle.
cogl.path_move_to(self.width / 2, 0)
cogl.path_line_to(self.width, self.height)
cogl.path_line_to(0, self.height)
cogl.path_line_to(self.width / 2, 0)
cogl.path_close()
# Start the clip
cogl.clip_push_from_path()
# errr.. the idea is to have the other stuff in the group
# get painted -- I assume Group knows what to do.
clutter.Group.do_paint(self)
# Finish the clip
cogl.clip_pop()
def main():
stage = clutter.Stage()
stage.set_size(500, 500)
stage.set_color(clutter.color_from_string("#000"))
rect_red, rect_green, rect_blue, rect_bounce = \
clutter.Rectangle(), clutter.Rectangle(), clutter.Rectangle(), clutter.Rectangle()
# We make two of our special groups.
clipped_group = ClipGroup(300,300)
inner_group = ClipGroup(100,100)
rect_red.set_position(0, 0)
rect_red.set_size(550, 550) #Big to be backdrop.
rect_red.set_color(clutter.color_from_string("#FF0000FF"))
rect_green.set_position(120, 10)
rect_green.set_size(50, 50)
rect_green.set_color(clutter.color_from_string("#00FF0090"))
rect_bounce.set_position(0,0)
rect_bounce.set_size(500,20)
rect_bounce.set_color(clutter.color_from_string("#AABBCCFF"))
clipped_group.add(rect_red, rect_green)
clipped_group.add(inner_group) # Add entire inner_group into clipped_group
rect_blue.set_color(clutter.color_from_string("#0000FF90"))
rect_blue.set_size(50, 50)
rect_blue.set_position(50,50) #relative to inner_group...
inner_group.add(rect_blue) # even though this comes after set_position...
clipped_group.set_position(100, 100)
inner_group.set_position(100,50)
stage.add(rect_bounce)
stage.add(clipped_group)
# Make rect_blue move around somewhat.
path = clutter.Path('M 0 0 L 40 0 L 40 40 L 0 40 Z')
timeline = clutter.Timeline(4000)
timeline.set_loop(True)
alpha = clutter.Alpha(timeline,clutter.EASE_OUT_SINE)
p_behaviour = clutter.BehaviourPath(alpha, path)
p_behaviour.apply(rect_blue)
timeline.start()
# Make rect_bounce go up and down
animation = rect_bounce.animate(clutter.EASE_IN_OUT_BOUNCE, 2000, "y", 500)
animation.set_loop(True)
# Start the main clipped_group rotating around the Y axis. For giggles.
timeline = clutter.Timeline(15000)
timeline.set_loop(True)
alpha = clutter.Alpha(timeline, clutter.LINEAR)
r_behave = clutter.BehaviourRotate(clutter.Y_AXIS, 0.0, 360.0, alpha=alpha)
r_behave.set_center(150, 0, 0)
r_behave.apply(clipped_group)
timeline.start()
stage.show_all()
stage.connect('key-press-event', clutter.main_quit)
stage.connect('destroy', clutter.main_quit)
stage.connect('scroll-event', zoomify)
clutter.main()
if __name__ == '__main__':
main()
I wanted to see for myself how Timelines could be controlled from a Score. This is very cool. Here, three rectangles fire in sequence given markers in their timelines. It sounds complicated, but the code should be easy to follow:
import clutter
from clutter import cogl
def main():
stage = clutter.Stage()
stage.set_size(500, 500)
stage.set_color(clutter.color_from_string("#000"))
rect_red, rect_green, rect_blue = \
clutter.Rectangle(), clutter.Rectangle(), clutter.Rectangle()
rect_red.set_position(30, 30)
rect_red.set_size(20, 20)
rect_red.set_color(clutter.color_from_string("#FF0000FF"))
rect_green.set_position(100, 100)
rect_green.set_size(50, 50)
rect_green.set_color(clutter.color_from_string("#00FF0090"))
rect_blue.set_color(clutter.color_from_string("#0000FF90"))
rect_blue.set_size(80, 80)
rect_blue.set_position(200,200)
stage.add(rect_red, rect_green, rect_blue)
t_red=clutter.Timeline(10000)
t_green=clutter.Timeline(5000)
t_blue=clutter.Timeline(5000)
a_blue=clutter.Alpha(t_blue,clutter.EASE_OUT_SINE)
a_green=clutter.Alpha(t_green,clutter.EASE_OUT_SINE)
a_red=clutter.Alpha(t_red,clutter.EASE_OUT_SINE)
b_red = clutter.BehaviourRotate(clutter.Z_AXIS, 0.0, 360.0, alpha=a_red)
b_green = clutter.BehaviourRotate(clutter.Z_AXIS, 0.0, 360.0, alpha=a_green)
b_blue = clutter.BehaviourRotate(clutter.Z_AXIS, 0.0, 360.0, alpha=a_blue)
b_blue.apply(rect_blue)
b_green.apply(rect_green)
b_red.apply(rect_red)
s=clutter.Score()
t_red.set_loop(True)
s.append(t_red)
t_red.add_marker_at_time("go_green",2000)
s.append_at_marker(t_red,"go_green",t_green)
t_green.add_marker_at_time("go_blue",5000)
s.append_at_marker(t_green,"go_blue", t_blue)
stage.show_all()
s.start()
stage.connect('key-press-event', clutter.main_quit)
stage.connect('destroy', clutter.main_quit)
clutter.main()
if __name__ == '__main__':
main()
No comments:
Post a Comment