Skip to content

Instantly share code, notes, and snippets.

@ptrelford
Last active December 14, 2015 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptrelford/7a71ac3132e647a2f163 to your computer and use it in GitHub Desktop.
Save ptrelford/7a71ac3132e647a2f163 to your computer and use it in GitHub Desktop.
Falling Snowflakes (as F# strings) using WPF canvas
#r "PresentationCore.dll"
#r "PresentationFramework.dll"
#r "WindowsBase.dll"
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Media
let w, h = 800.0, 600.0
let rnd = Random()
type flake = { mutable X:float; mutable Y:float; V:float; A:float; Element:UIElement }
let draw (canvas:Canvas) (flakes:ResizeArray<_>) =
if (rnd.Next(5)= 0) then
let x, y = rnd.NextDouble() * w, -16.0
let a = 45.0 + rnd.NextDouble() * 90.0
let v = 0.5 + rnd.NextDouble()
let element = TextBlock(Text="F#")
Canvas.SetLeft(element, x)
Canvas.SetTop(element, y)
element.RenderTransform <- RotateTransform(a)
let flake = { X=x; Y=y; V=v; A=a; Element=element }
flakes.Add(flake)
canvas.Children.Add(element) |> ignore
let onScreen, offScreen = flakes |> Seq.toList |> List.partition (fun flake -> flake.Y < h)
for flake in onScreen do
let r = flake.A * Math.PI / 180.0
flake.X <- flake.X + ((cos r) * flake.V)
flake.Y <- flake.Y + ((sin r) * flake.V)
Canvas.SetLeft(flake.Element, flake.X)
Canvas.SetTop(flake.Element, flake.Y)
for flake in offScreen do
flakes.Remove(flake) |> ignore
canvas.Children.Remove(flake.Element)
do
let window = Window(SizeToContent = SizeToContent.WidthAndHeight)
let canvas = Canvas(Width=w,Height=h)
window.Content <- canvas
let flakes = ResizeArray<_>()
CompositionTarget.Rendering.Add (fun _ ->
draw canvas flakes
)
window.Show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment