feature/layout-updates #1
							
								
								
									
										30
									
								
								src/app.js
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/app.js
									
									
									
									
									
								
							| @ -48,32 +48,30 @@ const Controls =()=> | ||||
| const Audiogram =()=> | ||||
| { | ||||
|     const [State] = Store.Consumer(); | ||||
|      | ||||
|     /** @type {(inAmount:number)=>string} */ const Perc =(inAmount)=> (inAmount*100)+"%"; | ||||
| 
 | ||||
|     const testMarksL = State.Draw.TestL.Points.map(p=>html`<${UI.Mark} x=${Perc(p.X)} y=${Perc(p.Y)} response=${p.Mark.Resp} right=${false}/>`); | ||||
|     const userMarksL = State.Draw.UserL.Points.map(p=>html`<${UI.Mark} x=${Perc(p.X)} y=${Perc(p.Y)} response=${p.Mark.Resp} right=${false} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); | ||||
|     const testMarksR = State.Draw.TestR.Points.map(p=>html`<${UI.Mark} x=${Perc(p.X)} y=${Perc(p.Y)} response=${p.Mark.Resp} right=${true} />`); | ||||
|     const userMarksR = State.Draw.UserR.Points.map(p=>html`<${UI.Mark} x=${Perc(p.X)} y=${Perc(p.Y)} response=${p.Mark.Resp} right=${true} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); | ||||
|     const testMarksL = State.Draw.TestL.Points.map(p=>html`<${UI.Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${false}/>`); | ||||
|     const userMarksL = State.Draw.UserL.Points.map(p=>html`<${UI.Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${false} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); | ||||
|     const testMarksR = State.Draw.TestR.Points.map(p=>html`<${UI.Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${true} />`); | ||||
|     const userMarksR = State.Draw.UserR.Points.map(p=>html`<${UI.Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${true} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); | ||||
| 
 | ||||
|     const testLinesL = State.Draw.TestL.Paths.map( p=>html`<line class="opacity-60" x1=${Perc(p.Head.X)} y1=${Perc(p.Head.Y)} x2=${Perc(p.Tail.X)} y2=${Perc(p.Tail.Y)} />`); | ||||
|     const userLinesL = State.Draw.UserL.Paths.map( p=>html`<line class="opacity-60" x1=${Perc(p.Head.X)} y1=${Perc(p.Head.Y)} x2=${Perc(p.Tail.X)} y2=${Perc(p.Tail.Y)} />`); | ||||
|     const testLinesR = State.Draw.TestR.Paths.map( p=>html`<line class="opacity-60" x1=${Perc(p.Head.X)} y1=${Perc(p.Head.Y)} x2=${Perc(p.Tail.X)} y2=${Perc(p.Tail.Y)} />`); | ||||
|     const userLinesR = State.Draw.UserR.Paths.map( p=>html`<line class="opacity-60" x1=${Perc(p.Head.X)} y1=${Perc(p.Head.Y)} x2=${Perc(p.Tail.X)} y2=${Perc(p.Tail.Y)} />`); | ||||
|     const testLinesL = State.Draw.TestL.Paths.map( p=>html`<line class="opacity-60" x1=${p.Head.X} y1=${p.Head.Y} x2=${p.Tail.X} y2=${p.Tail.Y} />`); | ||||
|     const userLinesL = State.Draw.UserL.Paths.map( p=>html`<line class="opacity-60" x1=${p.Head.X} y1=${p.Head.Y} x2=${p.Tail.X} y2=${p.Tail.Y} />`); | ||||
|     const testLinesR = State.Draw.TestR.Paths.map( p=>html`<line class="opacity-60" x1=${p.Head.X} y1=${p.Head.Y} x2=${p.Tail.X} y2=${p.Tail.Y} />`); | ||||
|     const userLinesR = State.Draw.UserR.Paths.map( p=>html`<line class="opacity-60" x1=${p.Head.X} y1=${p.Head.Y} x2=${p.Tail.X} y2=${p.Tail.Y} />`); | ||||
| 
 | ||||
|     return html` | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible stroke(blue-700 bold draw) opacity-50">${testMarksL}${testLinesL}</svg> | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible stroke(red-700 bold draw)  opacity-50">${testMarksR}${testLinesR}</svg> | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible stroke(blue-700 2 draw)">${userMarksL}${userLinesL}</svg> | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible stroke(red-700 2 draw)">${userMarksR}${userLinesR}</svg> | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible" > | ||||
|         <ellipse cx="0" cy="0" rx="5" ry="30" fill="url(#glow)"></ellipse> | ||||
|         <ellipse cx="0" cy="0" rx="30" ry="5" fill="url(#glow)"></ellipse> | ||||
|     <svg class="absolute top-0 w-full h-full overflow-visible transition-all duration-500" style=${{top:State.Draw.Cross?.Y, left:State.Draw.Cross?.X}}> | ||||
|         <ellipse cx="0" cy="0" rx="8" ry="30" fill="url(#glow)"></ellipse> | ||||
|         <ellipse cx="0" cy="0" rx="30" ry="8" fill="url(#glow)"></ellipse> | ||||
|         <defs> | ||||
|             <radialGradient id="glow"> | ||||
|                 <stop stop-color="blue" stop-opacity="0.6" offset="0.0"></stop> | ||||
|                 <stop stop-color="blue" stop-opacity="0.3" offset="0.2"></stop> | ||||
|                 <stop stop-color="blue" stop-opacity="0.0" offset="1.0"></stop> | ||||
|                 <stop stop-color=${State.Chan.Value ? "red" : "blue"} stop-opacity="0.6" offset="0.0"></stop> | ||||
|                 <stop stop-color=${State.Chan.Value ? "red" : "blue"} stop-opacity="0.3" offset="0.2"></stop> | ||||
|                 <stop stop-color=${State.Chan.Value ? "red" : "blue"} stop-opacity="0.0" offset="1.0"></stop> | ||||
|             </radialGradient> | ||||
|         </defs> | ||||
|     </svg> | ||||
|  | ||||
							
								
								
									
										30
									
								
								src/store.js
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/store.js
									
									
									
									
									
								
							| @ -25,6 +25,9 @@ export const ColumnLookup =(inFrequency)=> | ||||
|     return false; | ||||
| }; | ||||
| 
 | ||||
| /** @type {(inDecimal:number)=>string} */ | ||||
| const Perc =(inDecimal)=> `${inDecimal*100}%`; | ||||
| 
 | ||||
| /** Creates a new Store.Context object that contain the current selections  | ||||
|  * @type {(inState:Store.State, inTest?:Store.Test)=>Store.Context} */ | ||||
| const Reselect =(inState, inTest)=> | ||||
| @ -69,8 +72,8 @@ const Redraw =(inTest, inChan, inStim, inIsUser)=> | ||||
|                 { | ||||
|                     /** @type {Store.DrawPoint} */ | ||||
|                     const point = { | ||||
|                         X: lookup[1], | ||||
|                         Y: (mark.Stim - inStim.Min)/(inStim.Max - inStim.Min), | ||||
|                         X: Perc(lookup[1]), | ||||
|                         Y: Perc((mark.Stim - inStim.Min)/(inStim.Max - inStim.Min)), | ||||
|                         Mark: mark | ||||
|                     }; | ||||
|                     output.Points.push(point); | ||||
| @ -81,14 +84,21 @@ const Redraw =(inTest, inChan, inStim, inIsUser)=> | ||||
|         { | ||||
|             /** @type {Store.DrawLine} */ | ||||
|             const line = {Head:output.Points[i-1], Tail:output.Points[i]}; | ||||
|             if(line.Head.Mark.Resp && line.Tail.Mark.Resp) | ||||
|             if(line.Head.Mark?.Resp && line.Tail.Mark?.Resp) | ||||
|             { | ||||
|                 output.Paths.push(line); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return output; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| /** Create a new cursor position from the state | ||||
|  * @type {(inState:Store.State)=>Store.DrawPoint} */ | ||||
| const Reposition =(inState)=> ({ | ||||
|     X: Perc(ColumnMapping[inState.Freq.Value][1]), | ||||
|     Y: Perc((inState.Stim.Value - inState.Stim.Min)/(inState.Stim.Max - inState.Stim.Min)) | ||||
| }); | ||||
| 
 | ||||
| /** @type {Store.Reducer} */ | ||||
| export function Reducer(inState, inAction) | ||||
| @ -100,7 +110,9 @@ export function Reducer(inState, inAction) | ||||
|     { | ||||
|         const test = clone.Tests[Data]; | ||||
|         clone.Live = Reselect(clone, test); | ||||
|         clone.Draw = { | ||||
|         clone.Draw = | ||||
|         { | ||||
|             Cross: Reposition(clone), | ||||
|             UserL: Redraw(test, 0, clone.Stim, true ), | ||||
|             UserR: Redraw(test, 1, clone.Stim, true ), | ||||
|             TestL: Redraw(test, 0, clone.Stim, false), | ||||
| @ -123,6 +135,8 @@ export function Reducer(inState, inAction) | ||||
|         tone.Value += Data*tone.Step; | ||||
|         tone.Value = Math.max(tone.Value, tone.Min); | ||||
|         tone.Value = Math.min(tone.Value, tone.Max); | ||||
| 
 | ||||
|         clone.Draw.Cross = Reposition(clone); | ||||
|         if(Name != "Stim") | ||||
|         { | ||||
|             clone.Live = Reselect(clone); | ||||
| @ -133,7 +147,7 @@ export function Reducer(inState, inAction) | ||||
| } | ||||
| 
 | ||||
| /** @type {Store.State} */ | ||||
| export const Initial = | ||||
| export const Initial = Reducer( | ||||
| { | ||||
|     Chan: { Min:0,   Max:1,   Value:0,  Step:1 }, | ||||
|     Freq: { Min:2,   Max:8,   Value:2,  Step:1 }, | ||||
| @ -166,7 +180,7 @@ export const Initial = | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
| }, {Name:"Test", Data:0}); | ||||
| 
 | ||||
| /** @type {preact.Context<Store.Binding>} */ | ||||
| export const Context = React.createContext([Initial, (_a)=>{}]); | ||||
| @ -175,7 +189,7 @@ export const Context = React.createContext([Initial, (_a)=>{}]); | ||||
| export const Provider =(props)=> | ||||
| { | ||||
|     /** @type {Store.Binding} */ | ||||
|     const reducer = React.useReducer(Reducer, Initial, ()=>Reducer(Initial, {Name:"Test", Data:0})); | ||||
|     const reducer = React.useReducer(Reducer, Initial); | ||||
|     return React.createElement(Context.Provider, {value:reducer, children:props.children}); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										6
									
								
								store.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								store.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -25,7 +25,7 @@ declare namespace Store { | ||||
|     Freq: Range; | ||||
|     Stim: Range; | ||||
|     Live: Context; | ||||
|     Draw: DrawTest; | ||||
|     Draw: DrawChart; | ||||
|     Tests: Array<Test>; | ||||
|   }; | ||||
| 
 | ||||
| @ -42,10 +42,10 @@ declare namespace Store { | ||||
|   type PlotKeyTest = "TestL" | "TestR"; | ||||
|   type PlotKey = PlotKeyUser | PlotKeyTest; | ||||
| 
 | ||||
|   type DrawPoint = { X: number; Y: number; Mark: TestFrequencySample }; | ||||
|   type DrawPoint = { X: string; Y: string; Mark?: TestFrequencySample }; | ||||
|   type DrawLine = { Head:DrawPoint, Tail:DrawPoint}; | ||||
|   type DrawGroup = { Points: Array<DrawPoint>; Paths: Array<DrawLine> }; | ||||
|   type DrawTest = { UserL: DrawGroup, UserR: DrawGroup, TestL: DrawGroup, TestR: DrawGroup }; | ||||
|   type DrawChart = { Cross?:DrawPoint, UserL: DrawGroup, UserR: DrawGroup, TestL: DrawGroup, TestR: DrawGroup }; | ||||
| 
 | ||||
|   type Binding = [state:State, dispatch:(inAction:Action)=>void] | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user