-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
141 lines (125 loc) Β· 3.67 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const FluidDynamicsSolver = require('./lib/fds')
const N_ = 30 // sim complexity...?
const ROW = 30
const COLUMN = 30
const SENSITIVITY = 0.05
const representation = [
'π',
'π',
'π',
'π',
'π',
'π',
'π',
]
const solver = new FluidDynamicsSolver(N_)
solver.initFDS()
const container = document.createElement('div')
container.classList.add('container')
document.body.appendChild(container)
const canvas = document.createElement('canvas')
canvas.classList.add('wiggle-zone')
const RESOLUTION = 512
// canvas.style.width = '100vw'
// canvas.style.height = '100vh'
canvas.setAttribute('width', RESOLUTION)
canvas.setAttribute('height', RESOLUTION)
// canvas.style.margin = '10px'
// canvas.style.background = 'yellow'
canvas.style.border = '1px solid white'
container.appendChild(canvas)
// our own renderer
const renderGrid = document.createElement('div')
renderGrid.classList.add('renderGrid')
container.appendChild(renderGrid)
const arrCells = []
// j: y, i: x
for(let j = 0; j < ROW; j++)
{
const row = document.createElement('div')
row.style.width = `${RESOLUTION}px`
for(let i = 0; i < COLUMN; i++)
{
const cell = document.createElement('div')
cell.innerText = '1'
cell.classList.add('cell')
cell.style.display = 'inline-block'
cell.style.width = `${RESOLUTION / COLUMN}px`
row.appendChild(cell)
arrCells.push(cell)
}
renderGrid.appendChild(row)
}
// interaction
const E_POINTER_MOVE = ('ontouchstart' in window) ? 'touchmove' : 'mousemove'
const INV_CANVAS_W = 1 / RESOLUTION
const INV_CANVAS_H = 1 / RESOLUTION
let prevX = 0
let prevY = 0
canvas.addEventListener(E_POINTER_MOVE, (e) => {
e.preventDefault()
if (E_POINTER_MOVE === 'touchmove') {
e = e.changedTouches[0];
e.offsetX = e.pageX - e.target.offsetLeft;
e.offsetY = e.pageY - e.target.offsetTop;
}
const _x = e.offsetX
const _y = e.offsetY
// normalize x and y
const x = _x * INV_CANVAS_W
const y = _y * INV_CANVAS_H
// calculate dx and dy: normalized direction of mouse movement
const dx = (_x - prevX) * INV_CANVAS_W;
const dy = (_y - prevY) * INV_CANVAS_H;
addSource(x, y, dx, dy)
// record x and y for next calculation of dx and dy
prevX = _x
prevY = _y
})
function addSource(x, y, dx, dy) {
const movement = dx * dx + dy * dy
if (movement === 0) return
const clampX = clamp(x, 0, 1)
const clampY = clamp(y, 0, 1)
const index = solver.NORM_IX(clampX, clampY)
// TODO refactor fds.js, so that this part doesn't rely on global variables in there
solver.record(clampX, clampY, dx, dy)
}
function clamp(input, min, max) {
if (input < min) return min
else if (input > max) return max
else return input
}
function draw()
{
// update fluid solver
solver.update();
// visualize
drawDensity();
// loop
window.requestAnimationFrame(draw)
}
function drawDensity()
{
// NOTE Start here
// the simulation gers rendered onto ImageData
// and then that imageData gets blit onto display canvas
// for simulation, i: column, j: row
// 30 of each
for(var j = 0; j < ROW; j++)
{
for(var i = 0; i < COLUMN; i++)
{
// in case you need to know what that is:
// https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas
const simRowPosition = Math.floor(N_ / ROW * j)
const simColumnPosition = Math.floor(N_ / COLUMN * i)
const dens_index = solver.REG_IX(simColumnPosition+1, simRowPosition+1);
const dens = solver.getDens(dens_index)
let cappedDens = (dens * SENSITIVITY).toFixed(0)
if (cappedDens > representation.length - 1) cappedDens = representation.length - 1
arrCells[ (j * COLUMN + i) ].innerText = representation[cappedDens]
}
}
}
draw()