import { polyline } from "@thi.ng/hiccup-canvas/polyline" ; import { fitClamped } from "@thi.ng/math/fit" ; import { canvasPixels } from "@thi.ng/pixel/canvas" ; import { forkJoin } from "@thi.ng/rstream/forkjoin" ; import { reactive } from "@thi.ng/rstream/stream" ; import { bounds } from "@thi.ng/transducers-stats/bounds" ; import { NUM_WORKERS , type , WorkerJob , type , WorkerResult } from "./api" ; const W = 256 ; const H = 256 ; const rowsPerSlice = H / NUM_WORKERS ; const pixelsPerSlice = ( W * H ) / NUM_WORKERS ; const canvas = canvasPixels ( W , H ) ; document . body . appendChild ( canvas . canvas ) ; const imgU32 = new Uint32Array ( canvas . img . data . buffer ) ; const time = reactive ( 0 ) ; forkJoin < number , WorkerJob , WorkerResult , void > ( { src : time , fork : ( id , _ , time ) => ( { width : W , height : H , y1 : id * rowsPerSlice , y2 : ( id + 1 ) * rowsPerSlice , id , time , } ) , join : ( parts ) => { updatePixels ( parts ) ; drawStats ( parts ) ; time . next ( time . deref ( ) ! + 0.05 ) ; } , worker : "./assets/worker.js" , numWorkers : NUM_WORKERS , } ) ; const updatePixels = ( parts ) => { for ( let i = 0 ; i < NUM_WORKERS ; i ++ ) { imgU32 . set ( parts [ i ] . buf , i * pixelsPerSlice ) ; } canvas . ctx . putImageData ( canvas . img , 0 , 0 ) ; } ; const drawStats = ( parts ) => { canvas . ctx . strokeStyle = "white" ; for ( let i = 0 ; i < NUM_WORKERS ; i ++ ) { const x = i * 32 + 4 ; const stats = parts [ i ] . stats ; if ( stats && x < W ) { const [ min , max ] = bounds ( stats ) ; polyline ( canvas . ctx , { } , stats . map ( ( y , j ) => [ x + j , fitClamped ( y , min , max , 28 , 4 ) ] ) ) ; } } } ;