import { AffineTransform, Point, Rect } from "@noya-app/noya-geometry"; import { clamp01 } from "@noya-app/noya-utils"; import { GradientEditorGradient, GradientStopHandle, } from "./gradientEditorPlugin"; export type GradientEditorLinearGradient = { from: Point; to: Point; stops: { color: string; offset: number; }[]; }; export type GradientEditorDetails = { gradient: GradientEditorGradient; stopMap: Map; }; export function createGradientEditorDetails({ linearGradient, artRect, transform, }: { linearGradient: GradientEditorLinearGradient; artRect: Rect; transform: AffineTransform; }): GradientEditorDetails { const rect = transform.applyTo(artRect); const from = { x: clamp01(linearGradient.from.x), y: clamp01(linearGradient.from.y), }; const to = { x: clamp01(linearGradient.to.x), y: clamp01(linearGradient.to.y), }; const stops: GradientStopHandle[] = linearGradient.stops.map( (stop, index, allStops) => { const position = allStops.length > 1 ? clamp01(stop.offset ?? index / (allStops.length - 1)) : 0; const normalizedPoint = { x: from.x + (to.x - from.x) * position, y: from.y + (to.y - from.y) * position, }; const point = transform.applyTo({ x: artRect.x + normalizedPoint.x * artRect.width, y: artRect.y + normalizedPoint.y * artRect.height, }); const type: GradientStopHandle["type"] = index === 0 ? "start" : index === allStops.length - 1 ? "end" : "stop"; return { id: `stop-${index}`, index, type, position, point, color: stop.color, }; } ); const stopMap = new Map(stops.map((stop) => [stop.id, stop.index])); return { gradient: { rect, stops, }, stopMap, }; }