cursor, initialization
This commit is contained in:
parent
da9f569308
commit
78049da309
30
src/app.js
30
src/app.js
@ -49,31 +49,29 @@ const Audiogram =()=>
|
|||||||
{
|
{
|
||||||
const [State] = Store.Consumer();
|
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=${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 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 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 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 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 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 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 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 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} />`);
|
||||||
|
|
||||||
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)} />`);
|
|
||||||
|
|
||||||
return html`
|
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(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(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(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 stroke(red-700 2 draw)">${userMarksR}${userLinesR}</svg>
|
||||||
<svg class="absolute top-0 w-full h-full overflow-visible" >
|
<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="5" ry="30" fill="url(#glow)"></ellipse>
|
<ellipse cx="0" cy="0" rx="8" ry="30" fill="url(#glow)"></ellipse>
|
||||||
<ellipse cx="0" cy="0" rx="30" ry="5" fill="url(#glow)"></ellipse>
|
<ellipse cx="0" cy="0" rx="30" ry="8" fill="url(#glow)"></ellipse>
|
||||||
<defs>
|
<defs>
|
||||||
<radialGradient id="glow">
|
<radialGradient id="glow">
|
||||||
<stop stop-color="blue" stop-opacity="0.6" offset="0.0"></stop>
|
<stop stop-color=${State.Chan.Value ? "red" : "blue"} stop-opacity="0.6" offset="0.0"></stop>
|
||||||
<stop stop-color="blue" stop-opacity="0.3" offset="0.2"></stop>
|
<stop stop-color=${State.Chan.Value ? "red" : "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.0" offset="1.0"></stop>
|
||||||
</radialGradient>
|
</radialGradient>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
30
src/store.js
30
src/store.js
@ -25,6 +25,9 @@ export const ColumnLookup =(inFrequency)=>
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {(inDecimal:number)=>string} */
|
||||||
|
const Perc =(inDecimal)=> `${inDecimal*100}%`;
|
||||||
|
|
||||||
/** Creates a new Store.Context object that contain the current selections
|
/** Creates a new Store.Context object that contain the current selections
|
||||||
* @type {(inState:Store.State, inTest?:Store.Test)=>Store.Context} */
|
* @type {(inState:Store.State, inTest?:Store.Test)=>Store.Context} */
|
||||||
const Reselect =(inState, inTest)=>
|
const Reselect =(inState, inTest)=>
|
||||||
@ -69,8 +72,8 @@ const Redraw =(inTest, inChan, inStim, inIsUser)=>
|
|||||||
{
|
{
|
||||||
/** @type {Store.DrawPoint} */
|
/** @type {Store.DrawPoint} */
|
||||||
const point = {
|
const point = {
|
||||||
X: lookup[1],
|
X: Perc(lookup[1]),
|
||||||
Y: (mark.Stim - inStim.Min)/(inStim.Max - inStim.Min),
|
Y: Perc((mark.Stim - inStim.Min)/(inStim.Max - inStim.Min)),
|
||||||
Mark: mark
|
Mark: mark
|
||||||
};
|
};
|
||||||
output.Points.push(point);
|
output.Points.push(point);
|
||||||
@ -81,14 +84,21 @@ const Redraw =(inTest, inChan, inStim, inIsUser)=>
|
|||||||
{
|
{
|
||||||
/** @type {Store.DrawLine} */
|
/** @type {Store.DrawLine} */
|
||||||
const line = {Head:output.Points[i-1], Tail:output.Points[i]};
|
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);
|
output.Paths.push(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
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} */
|
/** @type {Store.Reducer} */
|
||||||
export function Reducer(inState, inAction)
|
export function Reducer(inState, inAction)
|
||||||
@ -100,7 +110,9 @@ export function Reducer(inState, inAction)
|
|||||||
{
|
{
|
||||||
const test = clone.Tests[Data];
|
const test = clone.Tests[Data];
|
||||||
clone.Live = Reselect(clone, test);
|
clone.Live = Reselect(clone, test);
|
||||||
clone.Draw = {
|
clone.Draw =
|
||||||
|
{
|
||||||
|
Cross: Reposition(clone),
|
||||||
UserL: Redraw(test, 0, clone.Stim, true ),
|
UserL: Redraw(test, 0, clone.Stim, true ),
|
||||||
UserR: Redraw(test, 1, clone.Stim, true ),
|
UserR: Redraw(test, 1, clone.Stim, true ),
|
||||||
TestL: Redraw(test, 0, clone.Stim, false),
|
TestL: Redraw(test, 0, clone.Stim, false),
|
||||||
@ -123,6 +135,8 @@ export function Reducer(inState, inAction)
|
|||||||
tone.Value += Data*tone.Step;
|
tone.Value += Data*tone.Step;
|
||||||
tone.Value = Math.max(tone.Value, tone.Min);
|
tone.Value = Math.max(tone.Value, tone.Min);
|
||||||
tone.Value = Math.min(tone.Value, tone.Max);
|
tone.Value = Math.min(tone.Value, tone.Max);
|
||||||
|
|
||||||
|
clone.Draw.Cross = Reposition(clone);
|
||||||
if(Name != "Stim")
|
if(Name != "Stim")
|
||||||
{
|
{
|
||||||
clone.Live = Reselect(clone);
|
clone.Live = Reselect(clone);
|
||||||
@ -133,7 +147,7 @@ export function Reducer(inState, inAction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @type {Store.State} */
|
/** @type {Store.State} */
|
||||||
export const Initial =
|
export const Initial = Reducer(
|
||||||
{
|
{
|
||||||
Chan: { Min:0, Max:1, Value:0, Step:1 },
|
Chan: { Min:0, Max:1, Value:0, Step:1 },
|
||||||
Freq: { Min:2, Max:8, Value:2, 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>} */
|
/** @type {preact.Context<Store.Binding>} */
|
||||||
export const Context = React.createContext([Initial, (_a)=>{}]);
|
export const Context = React.createContext([Initial, (_a)=>{}]);
|
||||||
@ -175,7 +189,7 @@ export const Context = React.createContext([Initial, (_a)=>{}]);
|
|||||||
export const Provider =(props)=>
|
export const Provider =(props)=>
|
||||||
{
|
{
|
||||||
/** @type {Store.Binding} */
|
/** @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});
|
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;
|
Freq: Range;
|
||||||
Stim: Range;
|
Stim: Range;
|
||||||
Live: Context;
|
Live: Context;
|
||||||
Draw: DrawTest;
|
Draw: DrawChart;
|
||||||
Tests: Array<Test>;
|
Tests: Array<Test>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,10 +42,10 @@ declare namespace Store {
|
|||||||
type PlotKeyTest = "TestL" | "TestR";
|
type PlotKeyTest = "TestL" | "TestR";
|
||||||
type PlotKey = PlotKeyUser | PlotKeyTest;
|
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 DrawLine = { Head:DrawPoint, Tail:DrawPoint};
|
||||||
type DrawGroup = { Points: Array<DrawPoint>; Paths: Array<DrawLine> };
|
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]
|
type Binding = [state:State, dispatch:(inAction:Action)=>void]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user