in packages/sdk/src/animation/animationData.ts [181:228]
public static Validate(data: AnimationDataLike) {
const errors: string[] = [];
// make sure data has at least one track
if (data.tracks.length === 0) {
errors.push("Data must contain at least one track");
}
const maxTrackLen = data.tracks.reduce(
(max, t) => Math.max(max, t.keyframes[t.keyframes.length - 1]?.time),
-Infinity);
for (let ti = 0; ti < data.tracks.length; ti++) {
const t = data.tracks[ti];
// make sure keyframes are in order by time
for (let ki = 0; ki < t.keyframes.length; ki++) {
const k = t.keyframes[ki];
if (ki === 0) {
if (k.time < 0) {
errors.push(`Track ${ti} keyframe ${ki} time cannot be less than 0`);
}
} else if (k.time <= t.keyframes[ki - 1].time) {
errors.push(`Track ${ti} keyframe ${ki} is out of sequence`);
}
if (k.easing) {
if (k.easing[0] < 0 || k.easing[0] > 1) {
errors.push(`Track ${ti} keyframe ${ki} easing[0] must be between 0 and 1`);
}
if (k.easing[2] < 0 || k.easing[2] > 1) {
errors.push(`Track ${ti} keyframe ${ki} easing[2] must be between 0 and 1`);
}
}
if (k.value instanceof TargetPath && t.relative) {
errors.push(`Relative track ${ti} cannot contain keyframe ${ki}'s realtime value`);
}
}
if (t.keyframes[t.keyframes.length - 1]?.time !== maxTrackLen) {
errors.push(`Track ${ti} is a different length from the others`);
}
}
return errors.length > 0 ? errors : null;
}