Here is an example of doing a centered rotation in Goo. There is a line in the timeout, that does a set_simple_transform.
#!/usr/bin/perl -w
use strict;
use warnings;
use Goo::Canvas;
use Gtk2 '-init';
use Glib qw(TRUE FALSE);
my $window = Gtk2::Window->new('toplevel');
$window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
$window->set_size_request(640, 600);
my $swin = Gtk2::ScrolledWindow->new;
$swin->set_shadow_type('in');
$window->add($swin);
my $canvas = Goo::Canvas->new();
$canvas->set_size_request(800, 650);
$canvas->set_bounds(0, 0, 1000, 1000);
$swin->add($canvas);
my $root = $canvas->get_root_item();
# first offset set
my $pts_ref = [50,50,180,120,90,100,50,50];
my $line = Goo::Canvas::Polyline->new(
$root, TRUE,
$pts_ref,
'stroke-color' => 'black',
'line-width' => 3,
'fill-color-rgba' => 0x3cb37180,
);
my ($midx, $midy) = _get_CM( @$pts_ref );
my $ellipse = Goo::Canvas::Ellipse->new(
$root, $midx-2, $midy-2,$midx+2, $midy+2,
'stroke-color' => 'goldenrod',
'line-width' => 8
);
my $ellipse1 = Goo::Canvas::Ellipse->new(
$root, -2, -2, +2, +2,
'stroke-color' => 'black',
'line-width' => 4
);
$ellipse1->translate($midx,$midy);
# end first set
my $xd = 100;
my $yd = 100;
$root->translate($xd,$yd);
my $id = Glib::Timeout->add (10, sub {
$xd += .1;
$yd += .1;
$line->rotate (10, $midx, $midy);
$root->set_simple_transform ($xd, $yd,1,0); #or a group
# $item->set_simple_transform ($x, $y, $scale, $rotation)
+
return 1;
});
$window->show_all();
Gtk2->main;
################################################
# This sub finds the center of mass of a polygon.
# I grabbed the algorithm somewhere from the web.
# I grabbed it from Ala Qumsieh's RotCanvas :-)
sub _get_CM {
my ($x, $y, $area);
my $i = 0;
while ($i < $#_) {
my $x0 = $_[$i];
my $y0 = $_[$i+1];
my ($x1, $y1);
if ($i+2 > $#_) {
$x1 = $_[0];
$y1 = $_[1];
} else {
$x1 = $_[$i+2];
$y1 = $_[$i+3];
}
$i += 2;
my $a1 = 0.5*($x0 + $x1);
my $a2 = ($x0**2 + $x0*$x1 + $x1**2)/6;
my $a3 = ($x0*$y1 + $y0*$x1 + 2*($x1*$y1 + $x0*$y0))/6;
my $b0 = $y1 - $y0;
$area += $a1 * $b0;
$x += $a2 * $b0;
$y += $a3 * $b0;
}
return split ' ', sprintf "%.0f %0.f" => $x/$area, $y/$area;
}
#############################################
__END__