import { DaumiShape, getDaumiInstructions } from './daumiShape' import { getPointOnCurve } from './getPointOnCurve' import { getTweenBetweenCurves, makePartialCurve } from './nemiCurve' import { SuperPath2D } from './SuperPath2D' // duplicated const LANE_PADDING = 0.02 const getLaneSpec = (lineIndex: number, numberOfLanes: number) => { return { from: lineIndex / numberOfLanes + LANE_PADDING, to: (lineIndex + 1) / numberOfLanes - LANE_PADDING, } } export const makeSegment = ( { daumiShape, numberOfLanes, }: { daumiShape: DaumiShape numberOfLanes: number }, path: SuperPath2D, { startPercentage, endPercentage, laneNumber, }: { startPercentage: number endPercentage: number laneNumber: number }, ) => { if (startPercentage < 0 || startPercentage > 1) { throw new Error(`startPercentage must be between 0 and 1, got ${startPercentage}`) } if (endPercentage < 0 || endPercentage > 1) { throw new Error(`endPercentage must be between 0 and 1, got ${endPercentage}`) } const laneSpec = getLaneSpec(laneNumber, numberOfLanes) const instructionsClockwise = getDaumiInstructions(daumiShape, { startPercentage, endPercentage, reverse: false, }) const instructionsCounterClockwise = getDaumiInstructions(daumiShape, { startPercentage: endPercentage, endPercentage: startPercentage, reverse: true, }) const reversedInstructionsCounterClockwise = [...instructionsCounterClockwise].reverse() const zipped = instructionsClockwise.map((instruction, i) => { return { clockwiseInstruction: instruction, counterClockwiseInstruction: reversedInstructionsCounterClockwise[i], } }) zipped.forEach(({ clockwiseInstruction, counterClockwiseInstruction }) => { const { element: elementForward } = clockwiseInstruction const curveForward = getTweenBetweenCurves(elementForward.innerCurve, elementForward.outerCurve, laneSpec.from) path.moveTo(getPointOnCurve(curveForward, clockwiseInstruction.startPercentage)) makePartialCurve(curveForward, path, { startPercentage: clockwiseInstruction.startPercentage, endPercentage: clockwiseInstruction.endPercentage, }) const { element: elementBack } = counterClockwiseInstruction const curveBack = getTweenBetweenCurves(elementBack.innerCurve, elementBack.outerCurve, laneSpec.to) makePartialCurve(curveBack, path, { startPercentage: counterClockwiseInstruction.startPercentage, endPercentage: counterClockwiseInstruction.endPercentage, }) path.closePath() }) } // like makeSegment, but only a single curve, single direction export const makeCurve = ( { daumiShape, }: { daumiShape: DaumiShape }, path: SuperPath2D, { startPercentage, endPercentage, t, }: { startPercentage: number endPercentage: number t: number }, ) => { if (startPercentage < 0 || startPercentage > 1) { throw new Error(`startPercentage must be between 0 and 1, got ${startPercentage}`) } if (endPercentage < 0 || endPercentage > 1) { throw new Error(`endPercentage must be between 0 and 1, got ${endPercentage}`) } const instructionsClockwise = getDaumiInstructions(daumiShape, { startPercentage, endPercentage, reverse: false, }) instructionsClockwise.forEach((instruction, i) => { const { element: elementForward } = instruction const curveForward = getTweenBetweenCurves(elementForward.innerCurve, elementForward.outerCurve, t) if (i === 0) { path.moveTo(getPointOnCurve(curveForward, instruction.startPercentage)) } makePartialCurve(curveForward, path, { startPercentage: instruction.startPercentage, endPercentage: instruction.endPercentage, }) }) }