diff --git a/docs/specs/properties.md b/docs/specs/properties.md index 32fc696..ab301ad 100644 --- a/docs/specs/properties.md +++ b/docs/specs/properties.md @@ -15,7 +15,10 @@ Their structure depends on whether it's animated or not: {schema_object:properties/base-keyframe} -Keyframe arrays MUST be stored in order of strictly ascending `t` frame number. Two keyframes cannot have the same `t` value. +Keyframe arrays MUST be stored in order of ascending `t` frame number. + +Two consecutive keyframes MAY have the same `t` value but a property MUST NOT have more that two keyframes with the same `t`. +If two keyframes share the `t` value, the implementation MUST render one of the two values at the given frame. All keyframes MUST have an `i` and `o` value, unless- diff --git a/docs/static/js/validator.js b/docs/static/js/validator.js index 2b21c4d..996b882 100644 --- a/docs/static/js/validator.js +++ b/docs/static/js/validator.js @@ -230,6 +230,11 @@ function patch_schema_enum(schema) } } +function keyframe_has_t(kf) +{ + return typeof kf == "object" && typeof kf.t == "number"; +} + class Validator { constructor(AjvClass, schema_json) @@ -359,14 +364,30 @@ class Validator if ( index > 0 ) { var prev_kf = data_cxt.parentData[index-1]; - if ( typeof prev_kf == "object" && typeof prev_kf.t == "number" && typeof data.t == "number" && data.t <= prev_kf.t ) + if ( keyframe_has_t(prev_kf) && typeof data.t == "number" ) { - validate_keyframe.errors.push({ - message: `keyframe 't' must be strictly increasing`, - type: "error", - instancePath: data_cxt.instancePath, - parentSchema: parent_schema, - }); + if ( data.t < prev_kf.t ) + { + validate_keyframe.errors.push({ + message: `keyframe 't' must be in ascending order`, + type: "error", + instancePath: data_cxt.instancePath, + parentSchema: parent_schema, + }); + } + else if ( data.t == prev_kf.t && index > 1 ) + { + var prev_prev = data_cxt.parentData[index-2]; + if ( keyframe_has_t(prev_prev) && data.t == prev_prev.t ) + { + validate_keyframe.errors.push({ + message: `there can be at most 2 keyframes with the same 't' value`, + type: "error", + instancePath: data_cxt.instancePath, + parentSchema: parent_schema, + }); + } + } } }