Process SMIL directives in XML data: Difference between revisions
Content added Content deleted
(added Perl 6 programming solution) |
|||
Line 194: | Line 194: | ||
</Scene> |
</Scene> |
||
</X3D> |
</X3D> |
||
</pre> |
|||
=={{header|Perl 6}}== |
|||
A crude attempt that only works with task data. |
|||
<lang perl6>#!/usr/bin/env perl6 |
|||
use XML::XPath; |
|||
my $smil = q:to<DATA>; # cramped verison, modified from task data |
|||
<?xml version="1.0" ?> <smil><X3D><Scene><Viewpoint position="0 0 8" orientation="0 0 1 0" /><PointLight color="1 1 1" location="0 2 0" /><Shape><Box size="2 1 2"><animate attributeName="size" from="2 1 2" to="1 2 1" begin="0s" dur="10s" /></Box><Appearance><Material diffuseColor="0.0 0.6 1.0"><animate attributeName="diffuseColor" from="0.0 0.6 1.0" to="1.0 0.4 0.0" begin="0s" dur="10s" /></Material></Appearance></Shape></Scene></X3D></smil> |
|||
DATA |
|||
class Animatee { has ($.todo, @.from, @.to, $.begin, $.dur) is rw }; |
|||
my %Parents; # keys store the parent tags that got <animate> child |
|||
my $x = XML::XPath.new(xml => $smil) or die; |
|||
for @($x.find("//animate")) { # strangely need .List or @ coercion to work |
|||
my $y = .parent.name; |
|||
%Parents{$y}:exists ?? die() !! %Parents{$y} = Animatee.new; # unique only |
|||
for .parent.elements { |
|||
(%Parents{$y}).todo = .attribs<attributeName>; |
|||
(%Parents{$y}).from = .attribs<from>.split(/\s+/); |
|||
(%Parents{$y}).to = .attribs<to>.split(/\s+/); |
|||
(%Parents{$y}).begin = .attribs<begin>.match(/\d+/); |
|||
(%Parents{$y}).dur = .attribs<dur>.match(/\d+/); |
|||
} |
|||
} |
|||
# use regex to strip SMIL tag and create a master template; sub-optimal approach |
|||
my $z = XML::XPath.new(xml => $smil.subst(/\<\/?smil\>/,'',:g:ii:ss)) or die; |
|||
for 0, 2, 4 -> $t { # task requires 0 & 2 only |
|||
my $clone = $z.clone; # work on a copy |
|||
for %Parents.kv -> $k,$v { |
|||
my @incre = ($v.to »-« $v.from) »/» $v.dur; # increment list |
|||
with $clone.find("//$k") { # moving attribute = @from + @increment*$t |
|||
.attribs{(%Parents{$_.name}).todo} = $v.from »+« @incre »*» $t; |
|||
.removeChild($_); # ditch <animate> and friends |
|||
} |
|||
} |
|||
say "when t = ", $t; |
|||
say $clone.find("/"); |
|||
}</lang> |
|||
{{out}} |
|||
<pre>when t = 0 |
|||
<?xml version="1.0"?><X3D><Scene><Viewpoint position="0 0 8" orientation="0 0 1 0"/><PointLight location="0 2 0" color="1 1 1"/><Shape><Box size="2 1 2"/><Appearance><Material diffuseColor="0 0.6 1"/></Appearance></Shape></Scene></X3D> |
|||
when t = 2 |
|||
<?xml version="1.0"?><X3D><Scene><Viewpoint position="0 0 8" orientation="0 0 1 0"/><PointLight location="0 2 0" color="1 1 1"/><Shape><Box size="1.8 1.2 1.8"/><Appearance><Material diffuseColor="0.2 0.56 0.8"/></Appearance></Shape></Scene></X3D> |
|||
when t = 4 |
|||
<?xml version="1.0"?><X3D><Scene><Viewpoint position="0 0 8" orientation="0 0 1 0"/><PointLight location="0 2 0" color="1 1 1"/><Shape><Box size="1.6 1.4 1.6"/><Appearance><Material diffuseColor="0.4 0.52 0.6"/></Appearance></Shape></Scene></X3D> |
|||
</pre> |
</pre> |
||