1+ <#
2+ . SYNOPSIS
3+ Morphs a Turtle
4+ . DESCRIPTION
5+ Morphs a Turtle by animating its path.
6+
7+ Any two paths with the same number of points can be morphed into each other.
8+ . EXAMPLE
9+ $sierpinskiTriangle = turtle SierpinskiTriangle 42 4
10+ $SierpinskiTriangleFlipped = turtle rotate 180 SierpinskiTriangle 42 4
11+ turtle SierpinskiTriangle 42 4 morph (
12+ $SierpinskiTriangle,
13+ $SierpinskiTriangleFlipped,
14+ $sierpinskiTriangle
15+ ) save ./SierpinskiTriangleFlip.svg
16+ . EXAMPLE
17+ $sideCount = (3..24 | Get-Random )
18+ $stepCount = 36
19+
20+ $flower = turtle rotate ((Get-Random -Max 180) * -1) flower 42 10 $sideCount $stepCount
21+ $flower2 = turtle rotate ((Get-Random -Max 180)) flower 42 50 $sideCount $stepCount
22+ $flower3 = turtle rotate ((Get-Random -Max 90)) flower 42 20 $sideCount $stepCount
23+ turtle flower 42 10 $sideCount $stepCount duration ($sideCount * 3) morph ($flower, $flower2,$flower) |
24+ save-turtle ./flowerMorph.svg Pattern
25+ . EXAMPLE
26+ $flowerAngle = (40..60 | Get-Random )
27+ $stepCount = 36
28+ $radius = 23..42 | Get-Random
29+
30+ $flowerPetals = turtle rotate ((Get-Random -Max 180) * -1) flowerPetal $radius 10 $flowerAngle $stepCount
31+ $flowerPetals3 = turtle rotate ((Get-Random -Max 180)) flowerPetal $radius 40 $flowerAngle $stepCount
32+ turtle flowerPetal $radius 10 $flowerAngle $stepCount duration $radius morph (
33+ $flowerPetals,
34+ $flowerPetals3,
35+ $flowerPetals
36+ ) | Save-Turtle ./flowerPetalMorph.svg Pattern
37+ #>
38+ param (
39+ [Parameter (ValueFromRemainingArguments )]
40+ $Arguments
41+ )
42+
43+ $durationArgument = $null
44+
45+ $newPaths = @ (foreach ($arg in $Arguments ) {
46+ if ($arg -is [string ]) {
47+ if ($arg -match ' ^\s{0,}m' ) {
48+ $arg
49+ }
50+ } elseif ($arg.PathData ) {
51+ $arg.PathData
52+ } elseif ($arg.D ) {
53+ $arg.D
54+ } elseif ($arg -is [TimeSpan ]) {
55+ $durationArgument = $arg
56+ }
57+ elseif ($arg -is [double ] -or $arg -is [int ]) {
58+ $durationArgument = [TimeSpan ]::FromSeconds($arg )
59+ }
60+ })
61+
62+ if (-not $newPaths ) {
63+ return $this
64+ <# $pathSegments = @($this.PathData -split '(?=\p{L})')
65+ $newPaths = @(for ($segmentNumber = 0; $segmentNumber -lt $pathSegments.Count; $segmentNumber++) {
66+ $pathSegments[0..$segmentNumber] -join ' '
67+ }) -join ';'#>
68+ }
69+
70+ if ($this.PathAnimation ) {
71+ $updatedAnimations =
72+ @ (foreach ($animationXML in $this.PathAnimation -split ' (?<=/>)' ) {
73+ $animationXML = $animationXML -as [xml ]
74+ if (-not $animationXML ) { continue }
75+ if ($animationXML.attributeName -eq ' d' ) {
76+ $animationXML.values = " $ ( $newPaths -join ' ;' ) "
77+ }
78+ $animationXML.OuterXml
79+ })
80+ $this.PathAnimation = $updatedAnimations
81+ } else {
82+ $this.PathAnimation += [Ordered ]@ {
83+ attributeName = ' d' ; values = " $ ( $newPaths -join ' ;' ) " ; repeatCount = ' indefinite' ; dur = $ (
84+ if ($durationArgument ) {
85+ " $ ( $durationArgument.TotalSeconds ) s"
86+ } elseif ($this.Duration ) {
87+ " $ ( $this.Duration.TotalSeconds ) s"
88+ } else {
89+ " 4.2s"
90+ }
91+
92+ )
93+ }
94+ }
95+
96+ return $this
0 commit comments