Follow-up to Codex findings on #11 (#11).
When a morph pole is a closed path with a non-default strokeStart/strokeEnd (a partially drawn outline), the rotation alignment introduced in #11 can change the aligned path's start point/parameterization. ManimView trims strokes from the path start, so the visible trimmed segment can shift when the alignment picks a nonzero cyclic offset. This surfaces on both paths that now apply rotation alignment:
- Transform pipeline (
BezierPath.aligned(with:) → ManimScene.apply): apply interpolates the aligned (rotated) paths for 0 < p < 1 but switches to the exact, unrotated target at p >= 1 — so a transform into a partially drawn closed shape can show the wrong edge mid-morph and jump at completion.
- Direct
interpolate (structurally-matched fast path): same rotation, same trim-start sensitivity, whenever a caller interpolates two trimmed closed paths.
Full strokes (strokeStart == 0 && strokeEnd == 1, the overwhelmingly common case) render identically under any cyclic offset, so they are unaffected either way.
Proposed fix: thread the stroke-trim state into the alignment decision — e.g. aligned(with:minimizeTravel:) and a matching flag on the direct-interpolate fast path — and disable rotation when either pole carries a non-default trim. ManimScene.play passes false when a transform pole is trimmed. That plumbing lives in ManimScene.swift, which #12 is concurrently restructuring, so it's deferred rather than bolted onto #11 to avoid a cross-PR conflict.
Follow-up to Codex findings on #11 (#11).
When a morph pole is a closed path with a non-default
strokeStart/strokeEnd(a partially drawn outline), the rotation alignment introduced in #11 can change the aligned path's start point/parameterization.ManimViewtrims strokes from the path start, so the visible trimmed segment can shift when the alignment picks a nonzero cyclic offset. This surfaces on both paths that now apply rotation alignment:BezierPath.aligned(with:)→ManimScene.apply):applyinterpolates the aligned (rotated) paths for0 < p < 1but switches to the exact, unrotated target atp >= 1— so a transform into a partially drawn closed shape can show the wrong edge mid-morph and jump at completion.interpolate(structurally-matched fast path): same rotation, same trim-start sensitivity, whenever a caller interpolates two trimmed closed paths.Full strokes (
strokeStart == 0 && strokeEnd == 1, the overwhelmingly common case) render identically under any cyclic offset, so they are unaffected either way.Proposed fix: thread the stroke-trim state into the alignment decision — e.g.
aligned(with:minimizeTravel:)and a matching flag on the direct-interpolate fast path — and disable rotation when either pole carries a non-default trim.ManimScene.playpassesfalsewhen a transform pole is trimmed. That plumbing lives inManimScene.swift, which #12 is concurrently restructuring, so it's deferred rather than bolted onto #11 to avoid a cross-PR conflict.