跳转至

ui/components/material/token/animation_token_mapping.h

Animation Token to MotionSpec Mapping. More...

Namespaces

Name
cf
cf::ui
cf::ui::components
cf::ui::components::material
cf::ui::components::material::token_literals

Classes

Name
struct cf::ui::components::material::token_literals::AnimationTokenMapping
Animation token mapping entry.

Detailed Description

Animation Token to MotionSpec Mapping.

Author: Charliechen114514 (chengh1922@mails.jlu.edu.cn)

Version: 0.1

Date: 2026-02-28

Copyright: Copyright © 2026

Defines the mapping between animation tokens and their corresponding MotionSpec configurations. This enables the factory to resolve a token like "md.animation.fadeIn" to a complete AnimationDescriptor with animation type, motion spec, property, and default values.

The mapping follows Material Design 3 motion principles:

  • Fade: 200ms enter, 150ms exit
  • Slide: 300ms enter, 250ms exit
  • Scale: 200ms enter, 150ms exit
  • Rotate: 300ms enter, 250ms exit

Source code

#pragma once

#include "animation_token_literals.h"
#include <cstring>

namespace cf::ui::components::material::token_literals {

// =============================================================================
// Animation Token → MotionSpec Mapping Structure
// =============================================================================

struct AnimationTokenMapping {
    const char* animationToken;

    const char* animationType;

    const char* motionToken;

    const char* property;

    float defaultFrom;

    float defaultTo;

    bool matches(const char* token) const {
        return animationToken && token && std::strcmp(animationToken, token) == 0;
    }
};

// =============================================================================
// Animation Token Mapping Table
// =============================================================================

inline constexpr AnimationTokenMapping TOKEN_MAPPINGS[] = {
    // =========================================================================
    // Fade Animations
    // =========================================================================
    {
        ANIMATION_FADE_IN,      // "md.animation.fadeIn"
        "fade",                 // Animation type
        "md.motion.shortEnter", // Motion spec (200ms, EmphasizedDecelerate)
        "opacity",              // Property to animate
        0.0f,                   // Start value (transparent)
        1.0f                    // End value (fully visible)
    },
    {
        ANIMATION_FADE_OUT,    // "md.animation.fadeOut"
        "fade",                // Animation type
        "md.motion.shortExit", // Motion spec (150ms, EmphasizedAccelerate)
        "opacity",             // Property to animate
        1.0f,                  // Start value (fully visible)
        0.0f                   // End value (transparent)
    },

    // =========================================================================
    // Slide Animations
    // =========================================================================
    {
        ANIMATION_SLIDE_UP,      // "md.animation.slideUp"
        "slide",                 // Animation type
        "md.motion.mediumEnter", // Motion spec (300ms, EmphasizedDecelerate)
        "positionY",             // Property to animate
        100.0f,                  // Start value (offset downward)
        0.0f                     // End value (normal position)
    },
    {
        ANIMATION_SLIDE_DOWN,   // "md.animation.slideDown"
        "slide",                // Animation type
        "md.motion.mediumExit", // Motion spec (250ms, EmphasizedAccelerate)
        "positionY",            // Property to animate
        0.0f,                   // Start value (normal position)
        100.0f                  // End value (offset downward)
    },
    {
        ANIMATION_SLIDE_LEFT,    // "md.animation.slideLeft"
        "slide",                 // Animation type
        "md.motion.mediumEnter", // Motion spec (300ms, EmphasizedDecelerate)
        "positionX",             // Property to animate
        100.0f,                  // Start value (offset right)
        0.0f                     // End value (normal position)
    },
    {
        ANIMATION_SLIDE_RIGHT,   // "md.animation.slideRight"
        "slide",                 // Animation type
        "md.motion.mediumEnter", // Motion spec (300ms, EmphasizedDecelerate)
        "positionX",             // Property to animate
        -100.0f,                 // Start value (offset left)
        0.0f                     // End value (normal position)
    },

    // =========================================================================
    // Scale Animations
    // =========================================================================
    {
        ANIMATION_SCALE_UP,     // "md.animation.scaleUp"
        "scale",                // Animation type
        "md.motion.shortEnter", // Motion spec (200ms, EmphasizedDecelerate)
        "scale",                // Property to animate
        0.8f,                   // Start value (smaller)
        1.0f                    // End value (normal size)
    },
    {
        ANIMATION_SCALE_DOWN,  // "md.animation.scaleDown"
        "scale",               // Animation type
        "md.motion.shortExit", // Motion spec (150ms, EmphasizedAccelerate)
        "scale",               // Property to animate
        1.0f,                  // Start value (normal size)
        0.8f                   // End value (smaller)
    },

    // =========================================================================
    // Rotate Animations
    // =========================================================================
    {
        ANIMATION_ROTATE_IN,     // "md.animation.rotateIn"
        "rotate",                // Animation type
        "md.motion.mediumEnter", // Motion spec (300ms, EmphasizedDecelerate)
        "rotation",              // Property to animate
        -45.0f,                  // Start value (rotated counter-clockwise)
        0.0f                     // End value (normal rotation)
    },
    {
        ANIMATION_ROTATE_OUT,   // "md.animation.rotateOut"
        "rotate",               // Animation type
        "md.motion.mediumExit", // Motion spec (250ms, EmphasizedAccelerate)
        "rotation",             // Property to animate
        0.0f,                   // Start value (normal rotation)
        45.0f                   // End value (rotated clockwise)
    },

    // =========================================================================
    // Ripple Animations
    // =========================================================================
    {
        ANIMATION_RIPPLE_EXPAND, // "md.animation.rippleExpand"
        "fade",                  // Animation type (uses progress for radius)
        "rippleExpand",          // Motion spec (400ms, Standard)
        "progress",              // Property to animate (used as radius multiplier)
        0.0f,                    // Start value (no ripple)
        1.0f                     // End value (full radius)
    },
    {
        ANIMATION_RIPPLE_FADE,  // "md.animation.rippleFade"
        "fade",                 // Animation type
        "rippleFade",           // Motion spec (150ms, Linear)
        "opacity",              // Property to animate
        1.0f,                   // Start value (fully visible)
        0.0f                    // End value (invisible)
    },
};

inline constexpr size_t TOKEN_MAPPING_COUNT =
    sizeof(TOKEN_MAPPINGS) / sizeof(AnimationTokenMapping);

// =============================================================================
// Token Resolution Functions
// =============================================================================

inline const AnimationTokenMapping* findTokenMapping(const char* token) {
    for (size_t i = 0; i < TOKEN_MAPPING_COUNT; ++i) {
        if (TOKEN_MAPPINGS[i].matches(token)) {
            return &TOKEN_MAPPINGS[i];
        }
    }
    return nullptr;
}

inline bool hasTokenMapping(const char* token) {
    return findTokenMapping(token) != nullptr;
}

} // namespace cf::ui::components::material::token_literals

Updated on 2026-03-09 at 10:14:01 +0000