document body style minHeight 600 let canvas document createElement canvas document body appendChild canvas canvas width canvas height 500 canvas id canvas Helper function for fract fractional part function myfract x return x Math floor x Helper function indot product function dot v1 v2 return v1 x v2 x v1 y v2 y Random function function random uv return myfract Math sin dot uv x 12 9898 y 78 233 43758 5453 Smooth random function function randomsmooth st Integer grid coordinates let i x Math floor st x 3 0 y Math floor st y 3 0 Fractional coordinates within the grid cell let f x myfract st x 3 0 y myfract st y 3 0 Sample four corners of the cell using the random function let a random i let b random x i x 1 0 y i y let c random x i x y i y 1 0 let d random x i x 1 0 y i y 1 0 Smooth the interpolation factor f for smoother transition between values f x f x f x 3 0 2 0 f x f y f y f y 3 0 2 0 f y Bilinear interpolation between corners let x1 a 1 0 f x b f x let x2 c 1 0 f x d f x let y1 x1 1 0 f y x2 f y return y1 const simplex3 a b c c Math sin c 0 5 Generate smooth random values for each 3D coordinate direction let x0 randomsmooth x a y b let x1 randomsmooth x a c 0 03 y b c 0 003 let y0 randomsmooth x a 0 19392323 y b 2 3929323 let y1 randomsmooth x a c 0 19392323 y b c 2 3929323 Interpolate along c axis let xc x0 x1 x0 c let yc y0 y1 y0 c Interpolate between results return xc yc xc c function valid val if val undefined throw invalid value if isNaN val throw NaN value if val 9999999 throw number warning range if val 9999999 throw number warning range Constructor for vec2 function vec2 x y this x x this y y valid this x valid this y return this vec2 prototype float32 function let r new Float32Array 2 r 0 this x r 1 this y return r vec2 operations vec2 add function v0 v1 return new vec2 v0 x v1 x v0 y v1 y vec2 sub function v0 v1 return new vec2 v0 x v1 x v0 y v1 y vec2 scale function v0 s return new vec2 v0 x s v0 y s vec2 dot function v0 v1 return v0 x v1 x v0 y v1 y vec2 dist function v0 return Math sqrt v0 x v0 x v0 y v0 y vec2 norm function v0 let ln Math sqrt v0 x v0 x v0 y v0 y valid ln return vec2 scale v0 1 0 ln vec2 lerp function a b t let ti 1 t return new vec2 ti a x t b x ti a y t b y vec2 fromAngle function angle return new vec2 Math cos angle Math sin angle class Particle constructor x y this pos new vec2 x y this vel new vec2 Math random 2 1 Math random 2 1 this acc new vec2 0 0 this size 8 move acc if acc this acc vec2 add this acc acc this vel vec2 add this vel this acc this pos vec2 add this pos this vel if vec2 dist this vel 1 0 this vel vec2 norm this vel this acc new vec2 0 0 draw let ss this size ss 2 0 ctx fillRect this pos x this pos y ss ss wrap if this pos x w this pos x 0 else if this pos x this size this pos x w 1 if this pos y h this pos y 0 else if this pos y this size this pos y h 1 let ctx let field let w h let size let columns let rows let noiseZ let particles let hue function setup size 15 hue 0 noiseZ 0 canvas document querySelector canvas ctx canvas getContext 2d reset window addEventListener resize reset function initParticles particles let numberOfParticles w h 5000 for let i 0 i numberOfParticles i let particle new Particle Math random w Math random h particles push particle console log init particles function initField console log init field field new Array columns for let x 0 x columns x field x new Array columns for let y 0 y rows y field x y let v new vec2 0 0 field x y v function calculateField console log calc field for let x 0 x columns x for let y 0 y rows y let angle simplex3 x 20 y 20 noiseZ Math PI 2 let len simplex3 x 40 40000 y 40 40000 noiseZ 0 5 field x y vec2 norm field x y field x y angle angle field x y vec2 fromAngle angle field x y len len field x y angle angle function reset w canvas width window innerWidth h canvas height window innerHeight ctx strokeStyle white columns Math round w size 1 rows Math round h size 1 initParticles initField console log reset finished function draw now requestAnimationFrame draw calculateField noiseZ 0 001 now 0 0002 drawBackground drawFlowField drawParticles function drawBackground ctx fillStyle black ctx fillRect 0 0 w h function drawParticles hue 0 5 ctx fillStyle hsla hue 50 50 0 1 particles forEach p p draw let pos vec2 scale p pos 1 0 size div size let v x 1 y 1 if pos x 0 pos x columns pos y 0 pos y rows v field Math floor pos x Math floor pos y p move v p wrap function drawFlowField for let x 0 x columns x for let y 0 y rows y ctx beginPath let x1 x size let y1 y size ctx moveTo x1 y1 ctx lineTo x1 field x y x size 2 y1 field x y y size 2 ctx stroke setup draw performance now
c new vec2 0 0 this size 8 move acc if acc this acc vec2 add this acc acc this vel vec2 add this vel this acc this pos vec2 add this pos this vel if vec2 dist this vel 1 0 this vel vec2 norm this vel this acc new vec2 0 0 draw let ss this size ss 2 0 ctx fillRect this pos x this pos y ss ss wrap if this pos x w this pos x 0 else if this pos x this size this pos x w 1 if this pos y h this pos y 0 else if this pos y this size this pos y h 1 let ctx let field let w h let size let columns let rows let noiseZ let particles let hue function setup size 15 hue 0 noiseZ 0 canvas document querySelector canvas ctx canvas getContext 2d reset window addEventListener resize reset function initParticles particles let numberOfParticles w h 5000 for let i 0 i numberOfParticles i let particle new Particle Math random w Math random h particles push particle console log init particles function initField console log init field field new Array columns for let x 0 x columns x field x new Array columns for let y 0 y rows y field x y let v new vec2 0 0 field x y v function calculateField console log calc field for let x 0 x columns x for let y 0 y rows y let angle simplex3 x 20 y 20 noiseZ Math PI 2 let len simplex3 x 40 40000 y 40 40000 noiseZ 0 5 field x y vec2 norm field x y field x y angle angle field x y vec2 fromAngle angle field x y len len field x y angle angle function reset w canvas width window innerWidth h canvas height window innerHeight ctx strokeStyle white columns Math round w size 1 rows Math round h size 1 initParticles initField console log reset finished function draw now requestAnimationFrame draw calculateField noiseZ 0 001 now 0 0002 drawBackground drawFlowField drawParticles function drawBackground ctx fillStyle black ctx fillRect 0 0 w h function drawParticles hue 0 5 ctx fillStyle hsla hue 50 50 0 1 particles forEach p p draw let pos vec2 scale p pos 1 0 size div size let v x 1 y 1 if pos x 0 pos x columns pos y 0 pos y rows v field Math floor pos x Math floor pos y p move v p wrap function drawFlowField for let x 0 x columns x for let y 0 y rows y ctx beginPath let x1 x size let y1 y size ctx moveTo x1 y1 ctx lineTo x1 field x y x size 2 y1 field x y y size 2 ctx stroke setup draw performance now