fix(ai): normalize gradient stop offsets to prevent NaN display
AI sometimes omits the offset field on gradient stops, causing Math.round(undefined * 100) = NaN in the UI. Fix at two layers: - normalize-pen-file.ts: auto-distribute missing offsets evenly across [0,1] and convert percentage-format offsets (>1) to 0-1 range - fill-section.tsx: defensive guard in the stop percentage display
This commit is contained in:
parent
763886ea01
commit
f4d313464e
|
|
@ -221,7 +221,7 @@ export default function FillSection({
|
|||
onChange={(c) => handleStopColorChange(i, c)}
|
||||
/>
|
||||
<NumberInput
|
||||
value={Math.round(stop.offset * 100)}
|
||||
value={Math.round((Number.isFinite(stop.offset) ? stop.offset : i / Math.max(currentStops.length - 1, 1)) * 100)}
|
||||
onChange={(v) => handleStopOffsetChange(i, v)}
|
||||
min={0}
|
||||
max={100}
|
||||
|
|
|
|||
|
|
@ -156,19 +156,31 @@ function normalizeSingleFill(
|
|||
function normalizeGradientStops(
|
||||
raw: unknown[] | undefined,
|
||||
): GradientStop[] {
|
||||
if (!Array.isArray(raw)) return []
|
||||
return raw.map((s: unknown) => {
|
||||
if (!Array.isArray(raw) || raw.length === 0) return []
|
||||
|
||||
// First pass: parse offsets, collecting which ones are explicitly set
|
||||
const parsed = raw.map((s: unknown) => {
|
||||
const stop = s as Record<string, unknown>
|
||||
const rawOffset =
|
||||
typeof stop.offset === 'number' && Number.isFinite(stop.offset)
|
||||
? stop.offset
|
||||
: typeof stop.position === 'number' && Number.isFinite(stop.position)
|
||||
? stop.position
|
||||
: null
|
||||
// Normalize percentage-format offsets (AI sometimes outputs 0-100 instead of 0-1)
|
||||
const offset = rawOffset !== null && rawOffset > 1 ? rawOffset / 100 : rawOffset
|
||||
return {
|
||||
offset:
|
||||
typeof stop.offset === 'number' && Number.isFinite(stop.offset)
|
||||
? stop.offset
|
||||
: typeof stop.position === 'number' && Number.isFinite(stop.position)
|
||||
? stop.position
|
||||
: 0,
|
||||
offset,
|
||||
color: typeof stop.color === 'string' ? stop.color : '#000000',
|
||||
}
|
||||
})
|
||||
|
||||
// Second pass: auto-distribute any stops that are missing an offset
|
||||
const n = parsed.length
|
||||
return parsed.map((s, i) => ({
|
||||
color: s.color,
|
||||
offset: s.offset !== null ? Math.max(0, Math.min(1, s.offset!)) : i / Math.max(n - 1, 1),
|
||||
}))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue