modules/skottie/src/text/TextAnimator.cpp
sk_sp<TextAnimator> TextAnimator::Make(const skjson::ObjectValue* janimator,
                                       const AnimationBuilder* abuilder,
                                       AnimatablePropertyContainer* acontainer) {
    if (!janimator) {
        return nullptr;
    }

    const skjson::ObjectValue* jprops = (*janimator)["a"];
    if (!jprops) {
        return nullptr;
    }

    std::vector<sk_sp<RangeSelector>> selectors;

    // Depending on compat mode and whether more than one selector is present,
    // BM exports either an array or a single object.
    if (const skjson::ArrayValue* jselectors = (*janimator)["s"]) {
        selectors.reserve(jselectors->size());
        for (const skjson::ObjectValue* jselector : *jselectors) {
            if (auto sel = RangeSelector::Make(*jselector, abuilder, acontainer)) {
                selectors.push_back(std::move(sel));
            }
        }
    } else {
        if (auto sel = RangeSelector::Make((*janimator)["s"], abuilder, acontainer)) {
            selectors.reserve(1);
            selectors.push_back(std::move(sel));
        }
    }

    return sk_sp<TextAnimator>(
                new TextAnimator(std::move(selectors), *jprops, abuilder, acontainer));
}
/*
 * Text layers can have optional text property animators.
 *
 * Each animator consists of
 *
 *   1) a list of animated properties (e.g. position, fill color, etc)
 *
 *   2) a list of range selectors
 *
 * Animated properties yield new values to be applied to the text, while range selectors
 * determine the text subset these new values are applied to.
 *
 * The best way to think of range selectors is in terms of coverage: they combine to generate
 * a coverage value [0..1] for each text fragment/glyph.  This coverage is then used to modulate
 * how the new property value is applied to a given fragment (interpolation weight).
 *
 * Note: Bodymovin currently only supports a single selector.
 *
 * JSON structure:
 *
 * "t": {              // text node
 *   "a": [            // animators list
 *     {               // animator node
 *       "s": {...},   // selector node
 *       "a": {        // animator properties node
 *         "a":  {}    // optional anchor point value
 *         "p":  {},   // optional position value
 *         "s":  {},   // optional scale value
 *         "o":  {},   // optional opacity
 *         "fc": {},   // optional fill color value
 *         "sc": {},   // optional stroke color value
 *
 *         // TODO: more props?
 *       }
 *     },
 *     ...
 *   ],
 *   ...
 * }
 */
Text layers can have optional text property animators.
Each animator consists of

1) a list of animated properties

2) a list of range selectors

Animated properties yield new values to be applied to the text, while range selectors
determine the text subset these new values are applied to.

The best way to think of range selectors is in terms of coverage: they combine to generate
a coverage value [0..1] for each text fragment/glyph.  This coverage is then used to modulate
how the new property value is applied to a given fragment (interpolation weight).

Bodymovin currently only supports a single selector.

JSON structure.



more props.
Text layers can have optional text property animators . Each animator consists of 1 ) a list of animated properties 2 ) a list of range selectors Animated properties yield new values to be applied to the text while range selectors determine the text subset these new values are applied to . The best way to think of range selectors is in terms of coverage : they combine to generate a coverage value [ 0 .. 1 ] for each text fragment / glyph . This coverage is then used to modulate how the new property value is applied to a given fragment ( interpolation weight ) . Bodymovin currently only supports a single selector . JSON structure . more props .
sk_sp<TextAnimator> TextAnimator::Make(const skjson::ObjectValue* janimator,
                                       const AnimationBuilder* abuilder,
                                       AnimatablePropertyContainer* acontainer) {
    if (!janimator) {
        return nullptr;
    }
    const skjson::ObjectValue* jprops = (*janimator)["a"];
    if (!jprops) {
        return nullptr;
    }
    std::vector<sk_sp<RangeSelector>> selectors;
    if (const skjson::ArrayValue* jselectors = (*janimator)["s"]) {
        selectors.reserve(jselectors->size());
        for (const skjson::ObjectValue* jselector : *jselectors) {
            if (auto sel = RangeSelector::Make(*jselector, abuilder, acontainer)) {
                selectors.push_back(std::move(sel));
            }
        }
    } else {
        if (auto sel = RangeSelector::Make((*janimator)["s"], abuilder, acontainer)) {
            selectors.reserve(1);
            selectors.push_back(std::move(sel));
        }
    }
    return sk_sp<TextAnimator>(
                new TextAnimator(std::move(selectors), *jprops, abuilder, acontainer));
}
sk_sp < TextAnimator > TextAnimator :: Make ( const skjson :: ObjectValue * janimator , const AnimationBuilder * abuilder , AnimatablePropertyContainer * acontainer ) { if ( ! janimator ) { return nullptr ; } const skjson :: ObjectValue * jprops = ( * janimator ) [ " " ] ; if ( ! jprops ) { return nullptr ; } std :: vector < sk_sp < RangeSelector > > selectors ; if ( const skjson :: ArrayValue * jselectors = ( * janimator ) [ " " ] ) { selectors . reserve ( jselectors -> size ( ) ) ; for ( const skjson :: ObjectValue * jselector : * jselectors ) { if ( auto sel = RangeSelector :: Make ( * jselector , abuilder , acontainer ) ) { selectors . push_back ( std :: move ( sel ) ) ; } } } else { if ( auto sel = RangeSelector :: Make ( ( * janimator ) [ " " ] , abuilder , acontainer ) ) { selectors . reserve ( 1 ) ; selectors . push_back ( std :: move ( sel ) ) ; } } return sk_sp < TextAnimator > ( new TextAnimator ( std :: move ( selectors ) , * jprops , abuilder , acontainer ) ) ; }
Text layers can have optional text property animators.
Text layers can have optional text property animators .
// Depending on compat mode and whether more than one selector is present, // BM exports either an array or a single object.