import type { IDeref } from "@thi.ng/api" ; import { defAtom } from "@thi.ng/atom/atom" ; import { canvas2D } from "@thi.ng/hdom-components/canvas" ; import { dropdown } from "@thi.ng/hdom-components/dropdown" ; import { start } from "@thi.ng/hdom/start" ; import { serialize } from "@thi.ng/hiccup/serialize" ; const state = defAtom < any > ( { bg : "red" , freq : 0.01 , } ) ; const setBg = ( x ) => state . resetIn ( [ "bg" ] , x ) ; const setFreq = ( x ) => state . resetIn ( [ "freq" ] , x ) ; const app = ( ) => { const canvas = canvas2D ( { update : ( el , ctx , _ , time , __ , ___ , bg , freq ) => { const y = el . height / 2 ; ctx . fillStyle = bg ; ctx . fillRect ( 0 , 0 , el . width , el . height ) ; ctx . strokeStyle = "white" ; ctx . lineWidth = 3 ; ctx . beginPath ( ) ; ctx . moveTo ( 0 , y + y * Math . sin ( time * freq ) ) ; for ( let x = 5 ; x < el . width ; x += 5 ) { ctx . lineTo ( x , y + y * Math . sin ( ( time + x ) * freq ) ) ; } ctx . stroke ( ) ; } , } ) ; return ( _state ) => { const state = _state . deref ( ) ; return [ "div#root.w-50-ns.flex.ma2.sans-serif" , [ "div.w-50-ns" , [ canvas , { width : 200 , height : 200 } , state . bg , state . freq ] , ] , [ "div.w-50-ns" , [ "label.db.mb3" , { for : "#bg" } , "Background color" , [ dropdown , { id : "bg" , class : "w-100" , onchange : ( e ) => setBg ( ( < HTMLSelectElement > e . target ) . value ) , } , [ [ "" , "Choose..." ] , [ "red" , "Red" ] , [ "green" , "Green" ] , [ "blue" , "Blue" ] , ] , state . bg , ] , ] , [ "label.db.mb3" , { for : "#freq" } , "Frequency" , [ "input" , { id : "freq" , class : "w-100" , type : "range" , min : 0.001 , max : 0.02 , step : 0.001 , value : state . freq , oninput : ( e ) => setFreq ( parseFloat ( ( < HTMLInputElement > e . target ) . value ) ) , } , ] , ] , ] , ] ; } ; } ; const html = serialize ( app ( ) ( state ) , null , false , true ) ; document . getElementById ( "app" ) ! . innerHTML = html ; console . log ( html ) ; start ( app ( ) , { hydrate : true , ctx : state } ) ;