dyna3/lang-trials/rust/app.civet
Aaron Fenyes 12abef4076 Trial a Rust engine powering a Civet interface
Write a basic web app with a Rust engine, compiled to WebAssembly,
powering a Civet interface. Do linear algebra in the engine using
the `nalgebra` crate.
2024-07-28 21:10:04 -07:00

114 lines
2.8 KiB
Plaintext

// engine functions
{default: init, Circle, circThru} from "./pkg/engine.js"
// === elements and state ===
// input
dataInputs .= new Array<HTMLInputElement>(6)
data .= new Float64Array(6)
// output and display
let circ: Circle | null
let display: HTMLCanvasElement
let ctx: CanvasRenderingContext2D
// === display ===
// display style
const rView = 5
const highlightStyle = "#fcfcfc"
const gridStyle = "#404040"
const dataFillStyles = ["#ba5d09", "#0e8a06", "#8951fb"]
const dataStrokeStyles = ["#f89142", "#58c145", "#c396fc"]
function render: void
// update resolution
res .= display.width / (2*rView)
// set transformation
ctx.setTransform 1, 0, 0, -1, 0.5*display.width, 0.5*display.height
// clear previous frame
ctx.clearRect -0.5*display.width, -0.5*display.height, display.width, display.height
// draw grid
gridRange .= [Math.ceil(-rView + 0.01) .. Math.floor(rView - 0.01)]
edgeScr .= res*rView
ctx.strokeStyle = gridStyle
for t of gridRange
tScr .= res*t
// draw horizontal grid line
ctx.beginPath()
ctx.moveTo -edgeScr, tScr
ctx.lineTo edgeScr, tScr
ctx.stroke()
// draw vertical grid line
ctx.beginPath()
ctx.moveTo tScr, -edgeScr
ctx.lineTo tScr, edgeScr
ctx.stroke()
// draw circle
if circ
ctx.beginPath()
ctx.strokeStyle = highlightStyle
ctx.arc res*circ.center_x, res*circ.center_y, res*circ.radius, 0, 2*Math.PI
ctx.stroke()
// draw data points
for n of [0..2]
const ind_x = 2*n
const ind_y = ind_x + 1
if dataInputs[ind_x].validity.valid and dataInputs[ind_y].validity.valid
ctx.beginPath()
ctx.fillStyle = dataFillStyles[n]
ctx.strokeStyle = dataStrokeStyles[n]
ctx.arc res*data[ind_x], res*data[ind_y], 3, 0, 2*Math.PI
ctx.fill()
ctx.stroke()
// === interaction ===
// --- inputs ---
function inputData: void
allDataValid .= true
for n of [0 .. dataInputs.length-1]
if dataInputs[n].validity.valid
data[n] = dataInputs[n].valueAsNumber
else
allDataValid = false
if allDataValid
try
circ = circThru data
catch ex
circ = null
console.error ex
else
circ = null
// update the display
requestAnimationFrame(render)
// --- binding ---
function bindDoc: Promise<void>
// wait for the engine to load
await init()
// set up the data inputs
for n of [0..5]
dataInputs[n] = document.querySelector(`#data-input-${n}`) as HTMLInputElement
dataInputs[n].addEventListener "input", inputData
dataInputs[n].style.borderColor = dataFillStyles[Math.floor(0.5*n)]
// initialize the display
display = document.querySelector("#display") as HTMLCanvasElement
ctx = display.getContext("2d") as CanvasRenderingContext2D
inputData()
document.addEventListener "DOMContentLoaded", bindDoc