Created
December 24, 2015 09:12
-
-
Save SoulFireMage/c87494a8bdbdb12989d7 to your computer and use it in GitHub Desktop.
Phil Trelford did this one on the train: Snowflakes using WriteableBitmap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#r "WriteableBitmapEx.Wpf.dll" // requires custom version with DrawString | |
//Email me if you want the custom dll - if I haven't already dumped it on Github! | |
module flake | |
open System | |
open System.Windows | |
open System.Windows.Controls | |
open System.Windows.Media | |
open System.Windows.Media.Imaging | |
open System.Windows.Threading | |
let w, h = 800.0, 600.0 | |
let rnd = Random() | |
type flake = { mutable X:float; mutable Y:float; V:float; A:float } | |
let render (context:BitmapContext) flakes = | |
let bitmap = context.WriteableBitmap | |
bitmap.Clear() | |
let color = Colors.Gray | |
let fontSize = 16 | |
let font = PortableFontDesc("Arial", fontSize, true, false,false) | |
for flake in flakes do | |
bitmap.DrawString(int flake.X, int flake.Y, color, font, "F#") |> ignore | |
let draw (bitmap:WriteableBitmap) flakes = | |
using (bitmap.GetBitmapContext()) (fun context -> render context flakes) | |
let update (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())*2.0 | |
let flake = { X=x; Y=y; V=v; A=a } | |
flakes.Add(flake) | |
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) | |
for flake in offScreen do | |
flakes.Remove(flake) |> ignore | |
do | |
let window = Window(SizeToContent = SizeToContent.WidthAndHeight) | |
let view = Image(Width=w,Height=h) | |
window.Content <- view | |
let dispatcherTimer = new DispatcherTimer() | |
dispatcherTimer.Interval <- new TimeSpan(0, 0, 0, 0, 15) | |
dispatcherTimer.Start() | |
let flakes = ResizeArray<_>() | |
window.Loaded.Add(fun _ -> | |
let bitmap = BitmapFactory.New(int w, int h) | |
view.Source <- bitmap | |
dispatcherTimer.Tick.Add(fun _ -> | |
update flakes | |
draw bitmap flakes | |
) | |
) | |
window.Show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment