Types/Turtle/get_Pattern.ps1
| 
                                <# .SYNOPSIS Gets a Turtle Pattern .DESCRIPTION Gets the current turtle as a pattern that stretches off to infinity. .EXAMPLE turtle star 42 4 | Save-Turtle "./GridPattern.svg" .EXAMPLE turtle star 42 6 | Save-Turtle "./StarPattern6.svg" .EXAMPLE turtle star 42 8 | Save-Turtle "./StarPattern8.svg" .EXAMPLE turtle star 42 5 | Save-Turtle "./StarPattern5.svg" .EXAMPLE turtle star 42 7 | Save-Turtle "./Star7Pattern.svg" .EXAMPLE turtle viewbox 100 start 25 25 square 50 | Save-Turtle "./WindowPattern.svg" Pattern .EXAMPLE turtle star 100 4 morph @( turtle star 100 4 turtle rotate 90 star 100 4 turtle rotate 180 star 100 4 turtle rotate 270 star 100 4 turtle star 100 4 ) | Save-Turtle "./GridPatternMorph.svg" .EXAMPLE turtle star 100 3 morph @( turtle star 100 3 turtle rotate 90 star 100 3 turtle rotate 180 star 100 3 turtle rotate 270 star 100 3 turtle star 100 3 ) | Save-Turtle "./TriPatternMorph.svg" .EXAMPLE turtle star 100 6 morph @( turtle star 100 6 turtle rotate 90 star 100 6 turtle rotate 180 star 100 6 turtle rotate 270 star 100 6 turtle star 100 6 ) | Save-Turtle "./Star6PatternMorph.svg" | Show-Turtle .EXAMPLE # We can use a pattern transform to scale the pattern turtle sierpinskiTriangle PatternTransform @{ scale = 0.25 rotate = 120 } | Save-Turtle "./SierpinskiTrianglePattern.svg" Pattern | show-Turtle .EXAMPLE # We can use pattern animations to change the pattern # Animations are relative to initial transforms turtle sierpinskiTriangle PatternTransform @{ scale = 0.25 rotate = 120 } PatternAnimation ([Ordered]@{ type = 'scale' ; values = 1.33,0.66, 1.33 ; repeatCount = 'indefinite' ;dur = "23s"; additive = 'sum' }) | Save-Turtle "./SierpinskiTrianglePattern.svg" Pattern | Show-Turtle .LINK https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Patterns .LINK https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/pattern #> [OutputType([xml])] param() # Get our viewbox $viewBox = $this.ViewBox # and get the width and height $viewX, $viewY, $viewWidth, $viewHeight = $viewBox # Initialize our core attributes. # These may be overwritten by user request. $coreAttributes = [Ordered]@{ 'id' = "$($this.ID)-pattern" 'patternUnits' = 'userSpaceOnUse' 'x' = $viewX 'y' = $viewY 'width' = $viewWidth 'height' = $viewHeight 'transform-origin' = '50% 50%' } # If we have specified any transforms if ($this.PatternTransform) { $coreAttributes."patternTransform" = # Then generate a transform expression @(foreach ($key in $this.PatternTransform.Keys) { # transforms are a name, followed by parameters in paranthesis "$key($($this.PatternTransform[$key]))" }) -join ' ' } # Pattern attributes can be defined within .SVGAttribute or .Attribute # provided they have the appropriate prefix $prefix = [Regex]::new('^/?pattern/', 'IgnoreCase') # (slashes are invalid markup, and thus a fine way to target nested instances) foreach ($collection in $this.SVGAttribute, $this.Attribute) { # If the connection does not exist, continue. if (-not $collection) { continue } # For each key that matches the prefix foreach ($key in $collection.Keys -match $prefix) { # add it to the attributes after stripping the prefix. $coreAttributes[$attributeName -replace $prefix] = $collection[$attributeName] } } $segments = @( "<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'>" "<defs>" "<pattern$( foreach ($attributeName in $coreAttributes.Keys) { " $attributeName='$($coreAttributes[$attributeName])'" } )>" $(if ($this.PatternAnimation) { $this.PatternAnimation }) $($this.SVG.SVG.InnerXML) "</pattern>" "</defs>" "<rect width='10000%' height='10000%' x='-5000%' y='-5000%' fill='url(#$($this.ID)-pattern)' transform-origin='50% 50%' />" "</svg>" ) [xml]$segments  |