KeyTable class final

An editable keyframe track — anim-04's own row, the mutable half of what AnimationTrack is the immutable, sample-ready half of.

Why this exists beside AnimationTrack. That class is built once by a decoder or a writer and samples fast — binary search over a flat Float32List, the shape a player reads sixty times a second. Editing one key of a hundred means rebuilding the whole flat array regardless, which is the wrong cost to pay on every drag of a timeline. KeyTable holds the same information as a list of Keys instead — cheap to insert into, move within, or delete from — and toAnimationTrack is the one place that pays the flattening cost, once, when something actually needs to sample.

Keys stay sorted by Key.time, always. AnimationTrack's own contract requires ascending times for its binary search to mean anything, and a table that let them fall out of order would produce a track that silently samples the wrong key. Every mutator here restores the order before returning rather than trusting a caller to have kept it.

Constructors

KeyTable({required int componentCount, AnimationInterpolation interpolation = AnimationInterpolation.linear, List<Key>? keys})
KeyTable.fromAnimationTrack(AnimationTrack track)
track read into an editable table — the same values, split back out of whichever of AnimationTrack's two flat layouts track.interpolation used, cubic's own in/value/out triple included.
factory

Properties

componentCount → int
final
duration → double
no setter
hashCode → int
The hash code for this object.
no setterinherited
interpolation ↔ AnimationInterpolation
getter/setter pair
keyCount → int
no setter
keys → List<Key>
Read-only — see KeyTable.values and every mutator on this class for the one way to change what is here.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

deleteKeys(List<int> indices) → void
Removes the keys at indices. Sorted and walked back to front internally, so an earlier removal never shifts a later index still waiting to be read — the caller hands over indices into the table as it was before this call, in whatever order it likes.
moveKeys(List<int> indices, double deltaTime) → void
Shifts the keys at indices by deltaTime, re-sorting afterward so two keys crossing each other on the way past land in the order their new times say rather than the order they had before the move.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
sample(double time, Float32List out) → void
Samples this table at time as it currently stands — anim-04's own "sample(t) после правок" acceptance, so an edit is visible to a caller without a manual round trip through toAnimationTrack first.
setInterpolation(AnimationInterpolation next) → void
Switches how the table's own keys are read — linear or cubic, anim -04's own "linear↔cubic". Every Key's own tangents stay exactly as they were; only interpolation itself changes, which is what lets a key already sculpted survive a person switching modes to check what a straight line would have looked like and switching straight back.
setKey(double time, List<double> values, {List<double>? inTangent, List<double>? outTangent}) → void
Writes (or replaces) the key at time. An existing key within _kSameKeyTolerance of this time is replaced outright rather than getting a second key beside it — setKey is what a person calling it once, twice, or a hundred times while dragging a value at a fixed playhead expects every time.
setTangent(int index, {List<double>? inTangent, List<double>? outTangent}) → void
Sets one key's own tangents, leaving its time and value untouched. Read only while interpolation is AnimationInterpolation.cubicSpline — see Key.inTangent for what a tangent set while linear is showing still means once the table switches back.
toAnimationTrack({required int nodeIndex, required AnimationPath path}) → AnimationTrack
This table's keys, flattened into an AnimationTrack ready to sample or write — the exact inverse of KeyTable.fromAnimationTrack. Throws the same ArgumentError AnimationTrack's own constructor would for an empty table: a track with no keyframes is not a thing either class can honestly claim to sample.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

frameOfTime(double time, double fps) → int
The frame nearest time, given fps frames a second — the inverse of timeOfFrame. Rounds rather than truncates, so a key captured a hair past a frame boundary — the ordinary case, a person's own drag landing a float away from the exact instant — still reads as the frame it was meant for rather than the one before it.
snappedToFrame(double time, double fps) → double
time, snapped to the nearest frame boundary at fps — frameOfTime and timeOfFrame composed, named separately because a caller wants the snapped instant itself far more often than the frame number that produced it. What ProjectProfile.frameSnap asks a drag to do when it is switched on; this is the arithmetic, not the switch.
timeOfFrame(int frame, double fps) → double
The time frame frame plays at, given fps frames a second — syn-03's own row: a project's own ProjectProfile.fps, read by a caller and handed in here rather than this class holding a profile of its own, the same way every other per-vertex or per-key primitive in this package stays decoupled from the project structure around it.