From: Emmanuel Rodriguez Date: Wed, 25 Mar 2009 21:02:05 +0000 (+0100) Subject: The marker is now animated X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f084d4457bedc7aeb369b232933c878a13b88011;p=libchamplain The marker is now animated --- diff --git a/bindings/perl/Champlain/examples/animated-marker.pl b/bindings/perl/Champlain/examples/animated-marker.pl index 7616a2c..3c6303a 100755 --- a/bindings/perl/Champlain/examples/animated-marker.pl +++ b/bindings/perl/Champlain/examples/animated-marker.pl @@ -1,97 +1,103 @@ #!/usr/bin/perl +# +# Custom marker that's animated and drawn through Cairo. The marker is composed +# of 1 static filled circle and 1 stroked circle animated as an echo. +# +package Champain::Ex::AnimatedMarker; + use strict; use warnings; use Glib qw(TRUE FALSE); -use Clutter qw(-threads-init -init); +use Clutter; use Champlain; use Math::Trig ':pi'; - my $MARKER_SIZE = 10; - -exit main(); - - -sub main { - - my $stage = Clutter::Stage->get_default(); - $stage->set_size(800, 600); - - # Create the map view - my $map = Champlain::View->new(); - $map->set_size($stage->get_size); - $stage->add($map); - - - # Create the marker layer - my $layer = Champlain::Layer->new(); - $map->add_layer($layer); - - # Create the marker - my $marker = create_marker(); - $layer->add($marker); - - - # Finish initializing the map view - $map->set_property("zoom-level", 5); - $map->set_property("scroll-mode", 'kinetic'); - $map->center_on(45.466, -73.75); - - - $stage->show_all(); - - Clutter->main(); - - return 0; +# +# In order to have the marker animated the timeline and the behaviours must live +# long enough for the code to use them. One way to do this is to keep the +# references to this objects as global variables (it's uggly but it works). +# +# Another way it so create a base class of Marker and to keep this timeline and +# the behaviours associated with the marker. This approach is implemented here. +# +use Glib::Object::Subclass 'Champlain::Marker' => + properties => [ + + # The timeline controlling the animation + Glib::ParamSpec->object( + 'timeline', + 'Timeline', + 'Timeline controling the animation', + 'Clutter::Timeline', + [ qw(readable writable) ], + ), + + # The opacity change in the echo + Glib::ParamSpec->object( + 'behaviour-opacity', + 'Behaviour Opacity', + 'Behaviour controling the opacity of the marker', + 'Clutter::Behaviour::Opacity', + [ qw(readable writable) ], + ), + + # The growing of the echo + Glib::ParamSpec->object( + 'behaviour-zoom', + 'Behaviour Zoom', + 'Behaviour controling the zoom of the marker', + 'Clutter::Behaviour::Scale', + [ qw(readable writable) ], + ), + ], +; + + +# Constructor +sub INIT_INSTANCE { + my $self = shift; + + # The middle dot + my $circle = create_static_circle(); + $self->add($circle); + + # The echo ring + my $echo_circle = create_echo_circle(); + $self->add($echo_circle); + + # Animate the echo ring + $self->create_animation($echo_circle); } -# -# The marker is drawn with cairo. It is composed of 1 static filled circle and 1 -# stroked circle animated as an echo. -# -sub create_marker { - my $marker = Champlain::Marker->new(); - - # Static filled circle - create_static_circle($marker); +sub create_animation { + my $self = shift; + my ($texture) = @_; - - # Echo circle - my $echo = create_echo_circle($marker); - - ## - ## Animate the echo circle - ## + # Timeline controlling the animation my $timeline = Clutter::Timeline->new_for_duration(1000); + $self->set(timeline => $timeline); $timeline->set_loop(TRUE); my $alpha = Clutter::Alpha->new($timeline, \&Clutter::Alpha::sine_inc); - my $behaviour = Clutter::Behaviour::Scale->new($alpha, 0.5, 0.5, 2.0, 2.0); - $behaviour->apply($echo); + # Circle's echo growing + my $behaviour_zoom = Clutter::Behaviour::Scale->new($alpha, 0.5, 0.5, 2.0, 2.0); + $self->set(behaviour_zoom => $behaviour_zoom); + $behaviour_zoom->apply($texture); - $behaviour = Clutter::Behaviour::Opacity->new($alpha, 255, 0); - $behaviour->apply($echo); - $timeline->signal_connect('new-frame', sub { - my ($timeline, $frame) = @_; - print $frame, "\n"; - }); + # Circle's echo fading + my $behaviour_opacity = Clutter::Behaviour::Opacity->new($alpha, 255, 0); + $self->set(behaviour_opacity => $behaviour_opacity); + $behaviour_opacity->apply($texture); $timeline->start(); - - - # Sets marker position on the map - $marker->set_position(45.528178, -73.563788); - - return $marker; } sub create_static_circle { - my ($marker) = @_; - my $texture = Clutter::Texture::Cairo->new($MARKER_SIZE, $MARKER_SIZE); my $cr = $texture->create_context(); @@ -104,18 +110,14 @@ sub create_static_circle { $cr->set_source_rgba(0.1, 0.1, 0.9, 1.0); $cr->fill(); - # Add the circle to the marker - $marker->add($texture); $texture->set_anchor_point_from_gravity('center'); $texture->set_position(0, 0); - + return $texture; } sub create_echo_circle { - my ($marker) = @_; - my $texture = Clutter::Texture::Cairo->new($MARKER_SIZE * 2, $MARKER_SIZE * 2); my $cr = $texture->create_context(); @@ -129,11 +131,57 @@ sub create_echo_circle { $cr->set_source_rgba(0.1, 0.1, 0.7, 1.0); $cr->stroke(); - # Add the circle to the marker - $marker->add($texture); - $texture->lower_bottom(); # Ensure it is under the previous circle - $texture->set_position(0, 0); $texture->set_anchor_point_from_gravity('center'); + $texture->set_position(0, 0); return $texture; } + + + +package main; + +use strict; +use warnings; + +use Glib qw(TRUE FALSE); +use Clutter qw(-threads-init -init); +use Champlain; + + +exit main(); + + +sub main { + + my $stage = Clutter::Stage->get_default(); + $stage->set_size(800, 600); + + # Create the map view + my $map = Champlain::View->new(); + $map->set_size($stage->get_size); + $stage->add($map); + + + # Create the marker layer + my $layer = Champlain::Layer->new(); + $map->add_layer($layer); + + # Create the marker + my $marker = Champain::Ex::AnimatedMarker->new(); + $marker->set_position(45.528178, -73.563788); # Montreal, Canada + $layer->add($marker); + + + # Finish initializing the map view + $map->set_property("zoom-level", 5); + $map->set_property("scroll-mode", 'kinetic'); + $map->center_on(45.466, -73.75); + + + $stage->show_all(); + + Clutter->main(); + + return 0; +}