Skip to content

Commit 8602431

Browse files
Add color fountain sample
1 parent 0ab466d commit 8602431

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

public/samples/Samples.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Compile Include="visual/basic-canvas.fs" />
2020
<Compile Include="visual/mandelbrot.fs" />
2121
<Compile Include="visual/hokusai.fs" />
22+
<Compile Include="visual/color-fountain.fs" />
2223
<Compile Include="interop/interop-samples.fs" />
2324
<Compile Include="interop/jquery.fs" />
2425
<Compile Include="other/parser.fs" />

public/samples/samples.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@
9191
"label": "Hokusai",
9292
"fsharpCode": "visual/hokusai.fs",
9393
"htmlCode": "visual/hokusai.html"
94+
},
95+
{
96+
"type": "menu-item",
97+
"label": "Color Fountain",
98+
"fsharpCode": "visual/color-fountain.fs",
99+
"htmlCode": "visual/color-fountain.html"
94100
}
95101
]
96102
},
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
module Color.Fountain
2+
3+
// Color Fountain by Erik Novales: https://github.com/enovales
4+
5+
open Fable.Core.JsInterop
6+
open Fable.Import
7+
open Fable.Import.Browser
8+
9+
let canvas = document.getElementsByTagName_canvas().[0]
10+
canvas.width <- 1000.
11+
canvas.height <- 800.
12+
let ctx = canvas.getContext_2d()
13+
14+
let rng (): float = JS.Math.random()
15+
16+
let particleLimit = 200
17+
18+
type Particle = {
19+
x: double
20+
y: double
21+
xvel: double
22+
yvel: double
23+
c: (int * int * int)
24+
rot: double
25+
rotVel: double
26+
}
27+
with
28+
override this.ToString() =
29+
let (r,g,b) = this.c
30+
sprintf "Particle(x = %O, y = %O, xvel = %O, yvel = %O, c = (%O, %O, %O))"
31+
this.x this.y this.xvel this.yvel r g b
32+
33+
34+
let updateParticle(dt: double)(p: Particle) =
35+
{
36+
p with
37+
x = p.x + p.xvel * dt
38+
y = p.y + p.yvel * dt
39+
yvel = p.yvel + 1. * dt
40+
rot = (p.rot + p.rotVel * dt) % (2. * 3.14159)
41+
}
42+
43+
let refillParticles(p: Particle array, dt: double) =
44+
let stillValid =
45+
p |> Array.filter(fun pt -> (pt.y < 1000.))
46+
//System.Console.WriteLine("stillValid.Length = " + stillValid.Length.ToString())
47+
let updatedPos =
48+
stillValid
49+
|> Array.map(updateParticle(dt))
50+
51+
//System.Console.WriteLine("updatedPos = " + updatedPos |> Array.map(fun p -> p.ToString()).ToString())
52+
let toCreate = particleLimit - stillValid.Length
53+
//System.Console.WriteLine("going to create " + toCreate.ToString() + " particles")
54+
let newParticles =
55+
seq {
56+
for i in 0..toCreate do
57+
yield {
58+
Particle.x = 200.
59+
y = 300.
60+
xvel = (rng() - 0.5) * (rng() * 30.)
61+
yvel = -(rng() * 25.)
62+
c = (int (rng() * 255.), int (rng() * 255.), int (rng() * 255.))
63+
rot = (rng() * 2. * 3.14159)
64+
rotVel = (rng() * 1.5)
65+
}
66+
}
67+
|> Seq.toArray
68+
69+
updatedPos |> Array.append(newParticles)
70+
71+
let mutable particles = [||]
72+
let timestep = 0.8
73+
74+
let rec loop last t =
75+
// Comment out this line to make sure the animation runs
76+
// with same speed on different frame rates
77+
// let timestep = (t - last) / 20.
78+
particles <- refillParticles(particles, timestep)
79+
80+
ctx.clearRect(0., 0., 10000., 10000.)
81+
let drawParticle(p: Particle) =
82+
let (r,g,b) = p.c
83+
let fs = "rgb(" + r.ToString() + ", " + g.ToString() + ", " + b.ToString() + ")"
84+
ctx.fillStyle <- !^fs
85+
86+
let x1 = (p.x - 5.)
87+
let x2 = (p.x + 5.)
88+
let y1 = (p.y - 5.)
89+
let y2 = (p.y + 5.)
90+
91+
// let x1 = (p.x - (10. * System.Math.Cos(p.rot)))
92+
// let x2 = (p.x + (10. * System.Math.Cos(p.rot)))
93+
// let y1 = (p.y - (10. * System.Math.Sin(p.rot)))
94+
// let y2 = (p.y + (10. * System.Math.Sin(p.rot)))
95+
96+
// ctx.fillRect(x1, y1, 10., 10.)
97+
ctx.beginPath()
98+
ctx.moveTo(x1, y1)
99+
ctx.lineTo(x2, y1)
100+
ctx.lineTo(x2, y2)
101+
ctx.lineTo(x1, y2)
102+
ctx.lineTo(x1, y1)
103+
ctx.closePath()
104+
ctx.fill()
105+
106+
particles
107+
|> Array.iter drawParticle
108+
109+
window.requestAnimationFrame(loop t) |> ignore
110+
111+
// start the loop
112+
loop 0. 0.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<html>
2+
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
5+
</head>
6+
7+
<body>
8+
<canvas align="center" id="canvas" width="1000" height="800"></canvas>
9+
</body>
10+
11+
</html>

0 commit comments

Comments
 (0)