-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* remove fp-ts * refactor widget update logic into a hook * improve file upload config form * make it easier to add new widgets * more refactor * better typing * it kinda works * fix skipping bug * require step to be positive * implement step * cleanup * move some stuff out * simplify code * properly handle floating points (#1133)
- Loading branch information
Showing
22 changed files
with
593 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { KnobConfig, WidgetProps } from "@/renderer/types/control"; | ||
import WidgetLabel from "@/renderer/components/common/widget-label"; | ||
import { useControl } from "@/renderer/hooks/useControl"; | ||
import { useRef } from "react"; | ||
import { Vector2, clamp, frac, nearestMultiple } from "@/renderer/utils/math"; | ||
|
||
const minAngle = -Math.PI / 6; | ||
const maxAngle = (7 * Math.PI) / 6; | ||
|
||
const angleFromValue = (value: number, min: number, max: number) => { | ||
const angleRange = maxAngle - minAngle; | ||
const f = frac(value, min, max); | ||
return clamp(minAngle + angleRange * f, minAngle, maxAngle); | ||
}; | ||
|
||
const valueFromAngle = ( | ||
angle: number, | ||
min: number, | ||
max: number, | ||
step: number, | ||
) => { | ||
const angleRange = maxAngle - minAngle; | ||
const valRange = max - min; | ||
const computedVal = min + valRange * ((angle - minAngle) / angleRange); | ||
return clamp(nearestMultiple(computedVal, step), min, max); | ||
}; | ||
|
||
type Props = { | ||
value: number; | ||
min: number; | ||
max: number; | ||
step: number; | ||
radius: number; | ||
onValueChange: (value: number) => void; | ||
}; | ||
|
||
const Knob = ({ value, min, max, step, radius, onValueChange }: Props) => { | ||
const knobRef = useRef<HTMLDivElement>(null); | ||
const angle = useRef(angleFromValue(value, min, max)); | ||
|
||
const handleMouseDown = ( | ||
event: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>, | ||
) => { | ||
event.preventDefault(); | ||
angle.current = angleFromValue(value, min, max); | ||
document.addEventListener("mousemove", handleMouseMove); | ||
document.addEventListener("mouseup", handleMouseUp); | ||
}; | ||
|
||
const handleMouseMove = (event: MouseEvent) => { | ||
if (knobRef.current === null) { | ||
return; | ||
} | ||
const rect = knobRef.current.getBoundingClientRect(); | ||
const centerX = rect.left + rect.width / 2; | ||
const centerY = rect.top + rect.height / 2; | ||
|
||
const mouseVec = new Vector2( | ||
event.clientX - centerX, | ||
centerY - event.clientY, | ||
).normalized(); | ||
const newPos = mouseVec.scaled(radius); | ||
let newAngle = Math.atan2(newPos.y, newPos.x); | ||
if (newAngle < -Math.PI / 2) { | ||
newAngle += 2 * Math.PI; | ||
} | ||
|
||
const newValue = valueFromAngle(newAngle, min, max, step); | ||
angle.current = newAngle; | ||
|
||
onValueChange(newValue); | ||
}; | ||
|
||
const handleMouseUp = () => { | ||
document.removeEventListener("mousemove", handleMouseMove); | ||
document.removeEventListener("mouseup", handleMouseUp); | ||
}; | ||
|
||
return ( | ||
<div className="nodrag mb-4 flex flex-col items-center"> | ||
<div | ||
className="relative cursor-pointer rounded-full border-2 bg-background" | ||
onMouseDown={handleMouseDown} | ||
onTouchStart={handleMouseDown} | ||
ref={knobRef} | ||
style={{ | ||
transform: `rotate(${-angleFromValue(value, min, max)}rad)`, | ||
width: radius, | ||
height: radius, | ||
}} | ||
> | ||
<div className="absolute right-0 top-1/2 h-2 w-4 -translate-y-1/2 transform rounded-sm bg-accent1" /> | ||
</div> | ||
<span className="text-sm text-gray-600">{value}</span> | ||
</div> | ||
); | ||
}; | ||
|
||
export const KnobNode = ({ id, data }: WidgetProps<KnobConfig>) => { | ||
const control = useControl(data); | ||
if (!control) { | ||
return <div className="text-2xl text-red-500">NOT FOUND</div>; | ||
} | ||
|
||
const { name, value, onValueChange } = control; | ||
|
||
return ( | ||
<div className="flex flex-col items-center gap-2"> | ||
<WidgetLabel | ||
label={data.label} | ||
placeholder={`${name} (${data.blockParameter})`} | ||
widgetId={id} | ||
/> | ||
<Knob | ||
value={value as number} | ||
onValueChange={onValueChange} | ||
min={data.config.min} | ||
max={data.config.max} | ||
step={data.config.step} | ||
radius={80} | ||
/> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.