Tier 1: origin anchor, detents, theming, type-in editing, ImageKnob
- origin: bipolar anchor value — Arc from=center, Fader fill and LEDFader segments draw from origin instead of min/mid-travel - detents + detentSize: magnetic snap while dragging (normalized space, wheel/keyboard unaffected); applyDetents exported - DreamknobProvider + KnobTheme: accent/track/face/text/label/ticks/ focusRing/fonts tokens with dark and light bases; every skin resolves defaults from the theme, instance props win - editable + parseValue: double-click knobs (or click fader readouts) to type exact values; Enter/blur commits, Esc cancels, 1.2k parses; ValueInput + defaultParseValue exported; setValue added to context - ImageKnob: film-strip sprite knob (KnobMan-style strips), vertical or horizontal, with focus ring, editing, value/label - Docs: LED gallery cards for film-strip/bipolar/editing/theming, playground editable toggle, theming API section, README updates
This commit is contained in:
parent
d8992408fa
commit
804a85cca6
25 changed files with 999 additions and 162 deletions
|
|
@ -10,7 +10,11 @@ export interface ArcProps {
|
|||
color?: string;
|
||||
/** Background track color. Omit to skip the track. */
|
||||
trackColor?: string;
|
||||
/** Draw the value arc from the minimum ('min') or from the travel center ('center', pan-style). */
|
||||
/**
|
||||
* Draw the value arc from the minimum ('min') or from the anchor ('center',
|
||||
* pan-style). The anchor is the knob's `origin` value when set, otherwise
|
||||
* the travel midpoint.
|
||||
*/
|
||||
from?: 'min' | 'center';
|
||||
cap?: 'butt' | 'round';
|
||||
/** Extra SVG props for the value arc path (e.g. filter for glow). */
|
||||
|
|
@ -29,16 +33,17 @@ export const Arc: React.FC<ArcProps> = ({
|
|||
arcProps,
|
||||
opacity,
|
||||
}) => {
|
||||
const { size, center, normalized, angleOffset, angleRange } = useKnobContext();
|
||||
const { size, center, normalized, originNormalized, angleOffset, angleRange } =
|
||||
useKnobContext();
|
||||
const r = radius ?? (size - thickness) / 2;
|
||||
|
||||
let start: number;
|
||||
let end: number;
|
||||
if (from === 'center') {
|
||||
const mid = angleOffset + angleRange / 2;
|
||||
const anchor = angleOffset + (originNormalized ?? 0.5) * angleRange;
|
||||
const now = angleOffset + normalized * angleRange;
|
||||
start = Math.min(mid, now);
|
||||
end = Math.max(mid, now);
|
||||
start = Math.min(anchor, now);
|
||||
end = Math.max(anchor, now);
|
||||
} else {
|
||||
start = angleOffset;
|
||||
end = angleOffset + normalized * angleRange;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue