1=pod 2 3=head1 NAME 4 5examples/spline.pl - A spline demo 6 7=head1 FEATURES 8 9Demonstrates parabolic splines as graphic primitives. 10The points arount the filled shapes are spline vertexes, 11which are dragable by the mouse. 12 13Using L<Prima::Drawable::CurvedText>. 14 15=cut 16 17use strict; 18use warnings; 19use Prima qw(Application Drawable::CurvedText); 20 21my @bounds; 22my @points = ( 23 10, 10, 24 130, 30, 25 20, 20, 26 20, 300, 27 50, 300, 28); 29my @vectors = ( 30 2, 2, 31 2, 1, 32 -1, -1, 33 -1, 3, 34 -2, 2, 35); 36my @rgb = ( 37 0, 38 0, 39 0, 40); 41my @rgb_vectors = ( 42 -1.04, 43 1.79, 44 1.38, 45); 46my $capture; 47my $aperture = 6 * $::application-> uiScaling; 48 49my $w = Prima::MainWindow-> create( 50 text => 'Spline demo', 51 antialias => (( $ARGV[0] // '' ) eq 'aa'), 52 backColor => cl::Black, 53 buffered => 1, 54 onPaint => sub { 55 my ( $self, $canvas) = @_; 56 $canvas-> clear; 57 58 my $spline = $canvas-> render_spline( [ @points, @points[0,1]]); 59 $canvas-> fillpoly( $spline); 60 if ( defined $capture) { 61 $canvas-> fill_ellipse( 62 $points[$capture], $points[$capture+1], 63 $aperture, $aperture 64 ); 65 } 66 67 $canvas-> rop( rop::XorPut); 68 $canvas-> curved_text_out("Hello, world!", $spline); 69 70 my $i; 71 for ( $i = 0; $i < @points; $i+=2) { 72 $canvas-> ellipse( 73 $points[$i], $points[$i+1], 74 $aperture, $aperture 75 ); 76 } 77 }, 78 onSize => sub { 79 my ( $self, $ox, $oy, $x, $y) = @_; 80 @bounds = ( $x, $y); 81 }, 82 onMouseDown => sub { 83 my ( $self, $btn, $mod, $x, $y) = @_; 84 my $i; 85 $capture = undef; 86 for ( $i = 0; $i < @points; $i+=2) { 87 if ( $points[$i] > $x - $aperture && $points[$i] < $x + $aperture && 88 $points[$i+1] > $y - $aperture && $points[$i+1] < $y + $aperture) { 89 $capture = $i; 90 last; 91 } 92 } 93 }, 94 onMouseUp => sub { 95 undef $capture; 96 }, 97 onMouseMove => sub { 98 my ( $self, $btn, $x, $y) = @_; 99 return unless defined $capture; 100 $points[$capture] = $x if $x >= 0 && $x < $bounds[0]; 101 $points[$capture+1] = $y if $y >= 0 && $y < $bounds[1]; 102 }, 103); 104 105$w-> insert( Timer => 106 timeout => 50, 107 onTick => sub { 108 my $i; 109 my $idx = 0; 110 for ( $i = 0; $i < @points; $i++) { 111 next if defined $capture && ( $capture == $i || $capture == $i - 1); 112 $points[$i] += $vectors[$i]; 113 if ( $points[$i] < 0) { 114 $points[$i] *= -1; 115 $vectors[$i] *= -1; 116 } elsif ( $points[$i] >= $bounds[$idx]) { 117 $points[$i] = $bounds[$idx] * 2 - $points[$i]; 118 $vectors[$i] *= -1; 119 } 120 $idx = ($idx ? 0 : 1); 121 } 122 123 for ( $i = 0; $i < 3; $i++) { 124 $rgb[$i] += $rgb_vectors[$i]; 125 if ( $rgb[$i] < 0) { 126 $rgb_vectors[$i] *= -1; 127 $rgb[$i] *= -1; 128 } elsif ( $rgb[$i] > 255) { 129 $rgb[$i] = 511 - $rgb[$i]; 130 $rgb_vectors[$i] *= -1; 131 } 132 } 133 $w-> color( int($rgb[2]) + int($rgb[1]) * 256 + int($rgb[0]) * 65536); 134 }, 135)-> start; 136 137run Prima; 138