mcpField
M
makepad-2.0-animation

makepad-2.0-animation

github.com/zhanghandong设计与 UI75251 次安装29 周前更新
代码仓库

关于 makepad-2.0-animation

面向 Makepad 2.0 界面开发者的动画参考技能,介绍 Animator 轨道、状态转换和着色器属性动画,并说明它与矢量 Tween 的区别。

主要功能

  1. 01独立动画组
  2. 02状态转换与循环模式
  3. 03缓动函数
  4. 04着色器 instance 属性动画
  5. 05控件 Animator 支持说明

适用场景

  1. 01制作按钮悬停动画
  2. 02创建切换和焦点状态转换
  3. 03构建基于着色器的加载动画
  4. 04选择 Animator 或矢量 Tween

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/zhanghandong/makepad-skills --skill makepad-2.0-animation

安装后在 Claude Code 中输入/makepad-2.0-animation确认已加载。

附带文件references/animator-reference.md

详细介绍

Makepad 2.0 动画技能

版本: makepad-widgets(dev 分支)| 最后更新: 2026-03-03

概述

Animator 系统可以随时间驱动 instance() 着色器变量,从而实现悬停效果、过渡和循环动画。它使用名为“组”的独立动画轨道,这些轨道会同时运行。

文档

详细文档请参阅本地文件:

  • ./references/animator-reference.md - 完整的 Animator API、播放类型、缓动函数和示例

重要:文档完整性检查

回答问题前,Claude 必须:

  1. 阅读上方列出的相关参考文件
  2. 如果文件读取失败或文件为空:
    • 告知用户:“参考文档不完整。仍将基于 SKILL.md 中的模式回答。”
    • 仍根据 SKILL.md 中的模式和内置知识作答
  3. 如果参考文件存在,则在回答中结合其内容

关键:控件对 Animator 的支持情况

并非所有控件都支持 animator! 将 animator: Animator{...} 添加到不支持它的控件上会被静默忽略——不会报错,也不会发生动画,什么都不会发生。

支持 Animator 的控件

View、SolidView、RoundedView、ScrollXView、ScrollYView、ScrollXYView、Button、ButtonFlat、ButtonFlatter、CheckBox、Toggle、RadioButton、LinkLabel、TextInput

不支持 Animator 的控件

Label、H1-H4、P、TextBox、Image、Icon、Markdown、Html、Slider、DropDown、Splitter、Hr、Filler

**要为 Label 添加动画:**将它放在带有 animator 的 View 中:

View{
    width: Fit height: Fit
    animator: Animator{
        hover: {
            default: @off
            off: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 0.0}} }
            on: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 1.0}} }
        }
    }
    label := Label{text: "Animated via parent"}
}

Animator 结构

animator: Animator{
    <group_name>: {
        default: @<state_name>
        <state_name>: AnimatorState{
            from: { ... }
            ease: <EaseFunction>
            redraw: true
            apply: { ... }
        }
        <state_name>: AnimatorState{ ... }
    }
    <group_name>: { ... }
}

组

每个组都是独立的动画轨道。常见的组:

组用途典型状态
hover鼠标悬停进入/移出off、on
focus键盘焦点off、on
active切换/选中状态off、on
disabled禁用状态off、on
time连续循环off、on

多个组可以同时运行动画,互不干扰。


from 块

控制过渡时序。键表示要从其过渡的状态,或使用 all 作为兜底项。

// From any state, animate over 0.2 seconds
from: {all: Forward {duration: 0.2}}

// Instant from any state
from: {all: Snap}

// Different timing depending on origin
from: {
    all: Forward {duration: 0.1}
    down: Forward {duration: 0.01}
}

播放类型

类型描述示例
Forward {duration: 0.2}单次正向播放悬停过渡
Snap立即跳转,不播放动画初始化默认状态
Loop {duration: 1.0}循环动画加载指示器
ReverseLoop {duration: 1.0}往返循环脉冲效果
BounceLoop {duration: 1.0}来回弹跳弹跳动画

缓动函数

函数描述
Linear匀速
InQuad / OutQuad / InOutQuad二次缓动
InCubic / OutCubic / InOutCubic三次缓动
InQuart / OutQuart / InOutQuart四次缓动
InQuint / OutQuint / InOutQuint五次缓动
InSine / OutSine / InOutSine正弦缓动
InExp / OutExp / InOutExp指数缓动
InCirc / OutCirc / InOutCirc圆形缓动
InElastic / OutElastic / InOutElastic弹性弹簧效果
InBack / OutBack / InOutBack超调
InBounce / OutBounce / InOutBounce弹跳

用法:在 AnimatorState 中设置 ease: OutCubic(可选,默认为 Linear)。


apply 块

要过渡到的目标值。其结构与控件的着色器属性一致。

// Animate single properties
apply: {
    draw_bg: {hover: 1.0}
}

// Animate multiple properties
apply: {
    draw_bg: {hover: 1.0 color: #f00}
    draw_text: {color: #fff}
}

**重要:**只有 instance() 着色器变量可以添加动画。uniform() 变量不能添加动画。


完整的悬停按钮示例

use mod.prelude.widgets.*

let HoverCard = RoundedView{
    width: Fill height: Fit
    padding: 16
    new_batch: true
    cursor: Hand
    draw_bg +: {
        instance hover: 0.0
        color: mix(#2a2a3d, #3a3a5d, self.hover)
        border_radius: 8.0
    }
    animator: Animator{
        hover: {
            default: @off
            off: AnimatorState{
                from: {all: Forward {duration: 0.15}}
                apply: {draw_bg: {hover: 0.0}}
            }
            on: AnimatorState{
                from: {all: Forward {duration: 0.15}}
                apply: {draw_bg: {hover: 1.0}}
            }
        }
    }
    title := Label{text: "Hover me" draw_text.color: #fff}
}

要点:

  • 带背景且支持悬停的项目必须设置 new_batch: true
  • cursor: Hand 会在悬停时显示指针光标
  • instance hover: 0.0 用于声明可添加动画的变量
  • mix(color1, color2, self.hover) 会在颜色之间插值

时间线动画(关键帧)

对于多步动画,请使用 timeline():

animator: Animator{
    time: {
        default: @off
        on: AnimatorState{
            from: {all: Loop {duration: 2.0}}
            apply: {
                draw_bg: {
                    rotation: timeline(){
                        snap(0.0)
                        snap(6.28)
                    }
                }
            }
        }
    }
}

加载旋转动画模式

let Spinner = View{
    width: 40 height: 40
    draw_bg +: {
        instance rotation: 0.0
        pixel: fn() {
            let sdf = Sdf2d.viewport(self.pos * self.rect_size)
            let cx = self.rect_size.x * 0.5
            let cy = self.rect_size.y * 0.5
            let r = min(cx, cy) * 0.8
            sdf.arc(cx, cy, r, self.rotation, self.rotation + 4.5, 3.0)
            sdf.stroke(#4488ff, 2.5)
            return sdf.result
        }
    }
    animator: Animator{
        time: {
            default: @on
            on: AnimatorState{
                from: {all: Loop {duration: 1.0}}
                apply: {
                    draw_bg: {
                        rotation: timeline(){
                            snap(0.0)
                            snap(6.28318)
                        }
                    }
                }
            }
        }
    }
}

Animator 与 Vector Tween 的区别

Makepad 有两套独立的动画系统:

特性Animator(本技能)Tween(参见 makepad-2.0-vector)
目标Widget 着色器的 instance 变量SVG 形状属性(fill、cx、opacity...)
语法animator: Animator{...} 块属性值:opacity:Tween{...}
触发方式状态转换(悬停、焦点)渲染时自动触发
循环from 中的 Loop {duration: 1.0}loop_:true(布尔值,不是字符串!)
用途UI 交互(悬停、点击)SVG/Vector 图形动画

使用 Animator 的场景: 按钮悬停效果、切换状态、加载旋转动画(基于着色器) 使用 Vector Tween 的场景: SVG 路径动画、脉冲指示器、移动圆点、颜色过渡

Tween 的详细信息请参见 makepad-2.0-vector 技能。


最佳实践

  1. 始终为带有背景且具有悬停动画的 View 添加 new_batch: true
  2. 需要动画的内容都使用 instance 变量
  3. 组名应与语义用途相匹配(悬停、焦点、活动状态)
  4. 状态转换使用 Forward,瞬时状态变化使用 Snap
  5. 对于初始处于非活动状态的状态,设置 default: @off
  6. Label 无法添加动画——如果需要为文本添加动画,请将其包裹在 View 中
  7. 保持动画时长较短:悬停动画为 0.1-0.3s,基于时间的动画则为 0.5-2.0s

评论

支持 Markdown