en un clic
motion-to-code
将 UI/UX 动效视频或 GIF 逆向还原为可运行的动效代码(Web + Android Compose)
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
将 UI/UX 动效视频或 GIF 逆向还原为可运行的动效代码(Web + Android Compose)
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle SOC
| name | motion-to-code |
| description | 将 UI/UX 动效视频或 GIF 逆向还原为可运行的动效代码(Web + Android Compose) |
将 UI/UX 动效设计视频或 GIF 逆向还原为可运行的动画代码。你必须严格遵循以下交互与执行步骤:
/motion-to-code 或自然语言启用本技能时,你首先需要停下来询问用户:
.mp4, .gif 等)。⚠️ 此时进入等待状态,必须等待用户发送文件(或告知文件路径)并提供描述后再继续。
⚠️ 此时进入等待状态,必须等待用户确认目标尺寸后再继续。
bash .agents/skills/motion-to-code/scripts/extract_frames.sh <输入文件路径>(脚本自带有自适应帧率逻辑)。motion-output/tracking_data.md,并将视觉量化数据与用户第一步的自然语言描述进行交叉验证。motion-output/analysis.md。⚠️ 此时询问用户是否同意分析结果并继续生成代码。
motion-output/web/ 中生成基于 Vanilla CSS/JS 的还原代码。aspect-ratio: 16/9),构建一个主舞台容器包裹特效。% 百分比、vmin/vmax 或 flex/grid 进行响应式自适应布局。<input type="range"> 滑块,实时修改 CSS Variables,所见即所得。browser_subagent 录制并验证 file:///.../motion-output/web/ 的动效轨迹。验证无误后,向用户简短反馈。根据第三步判定的 Tier,选择对应的渲染引擎输出代码:
在分析阶段,你必须判定动效的渲染复杂度等级,并在 analysis.md 中明确标注:
| Tier | 判定条件 | Android 渲染引擎 | Web 渲染引擎 |
|---|---|---|---|
| T1 刚体动效 | 仅涉及 scale / translate / rotate / opacity / spring | Compose Animation API | CSS Transitions + Transforms |
| T2 网格形变 | 检测到非线性形变(鱼眼膨胀、边缘弯曲、柔性拉伸、非矩形变形) | Canvas.drawBitmapMesh() | Canvas 2D + Mesh Grid |
| T3 图像着色 | 检测到像素级后处理(径向模糊、热浪扭曲、色散、发光) | AGSL RuntimeShader (API 33+) | WebGL Fragment Shader |
| T4 算法流体/噪声的生成 🆕 | 分形维度算法生成(如流体动力学、Simplex 噪声纹理、Raymarching SDF 光影) | AGSL RuntimeShader | WebGL (原生 Boilerplate) |
判定方法:
motion-output/web/ 中生成基于 Vanilla CSS/JS 的还原代码。aspect-ratio: 16/9 容器中(高度或宽度自适应),非内容区域背景置灰。% 百分比、vmin/vmax 或 flex/grid 进行响应式自适应布局,确保骨架能随外框尺寸自动缩放。<input type="range"> 滑块<style> 的 :root 中用 CSS 变量定义所有魔法数字。<canvas> + JS 网格变形代替 CSS 动画。browser_subagent 录制并验证 file:///.../motion-output/web/ 的动效轨迹。根据 Step 2 判定的 Tier,选择对应的渲染引擎输出代码:
motion-output/android/MotionAnimation.ktanimateXAsState()、Animatable、spring() 等标准 APIdata class MotionConfig(...),集中管理所有可调参数(时长、位移量、旋转角、张力等)。@Composable fun MotionPreview() 中,利用 Compose 的 Slider 编写一个浮层侧滑调音台。motion-output/android/MotionAnimation.kt.agents/skills/motion-to-code/examples/MeshMorphRenderer.ktCanvas.drawBitmapMesh(bitmap, meshW, meshH, verts, ...)data class MeshMorphConfig(网格密度, 膨胀强度, 膨胀半径, ...) 配置对象createBaseMesh() 构建均匀网格applyBulgeMesh() 按当前动画进度计算形变顶点drawBitmapMesh() 输出到 Canvasmotion-output/android/MotionAnimation.kt.agents/skills/motion-to-code/examples/ShaderEffectRenderer.ktRuntimeShader(agslCode) + RenderEffect.createRuntimeShaderEffect()data class ShaderEffectConfig(...) 配置对象motion-output/android/...,基于 Compose RuntimeShader;Web 端写入 motion-output/web/...。.agents/skills/motion-to-code/examples/FluidNoiseRenderer.ktThree.js、Pixi.js 等庞大重量级 3D 库。必须手写一个少于 100 行代码的纯净 WebGL Boilerplate,将算法挂载并投影在一个全屏 Quad 三角面上。必须向下文传入 u_resolution、u_time 以及 u_mouse。为杜绝语言变元报错,当你跨端复现并改造社区已验证好的数学模型源码时,必须完全遵照以下数据类型强行映射替换准则:
RuntimeShader)AGSL 本质是 GLSL ES 1.0 的限制超集语言,对于传统 Web Shader 的语法,大模型你在翻译重写时必须使用以下的映射格式替代:
vec2, vec3, vec4 => float2, float3, float4 (在处理色彩或者 uv 值时更推荐其对应的 half2, half3, half4 半精度格式可提效)。mat2, mat3, mat4 => float2x2, float3x3, float4x4。void mainImage(out vec4 fragColor, in vec2 fragCoord)half4 main(float2 fragCoord) { ... return half4(r, g, b, a); }。gl_FragCoord 获取尺寸。所有入参全部借由 main 进来的参传入,并需要自主映射 UV:float2 uv = fragCoord.xy / resolution.xy;。uniform shader iChannel0; 而非纹理类型定义。拉取像素命令从 texture(iChannel0, uv)iChannel0.eval(uv * resolution.xy)。在生成配套的 Web HTML 等价文件时,所有 GLSL 必须遵循以下转换法配合原生挂载:
void main() { ... gl_FragColor = vec4(color, 1.0); },并挂载 varying vec2 vUv; 辅助接收前端定点传递。uniform vec2 u_resolution;、uniform float u_time; 和 uniform vec2 u_mouse; 三大神器数据位。对于所有渲染层级 (T1/T2/T3),你都必须在输出 Android 原生代码时遵守以下对齐策略:
data class MotionConfig(...),集中管理所有核心可调参数(曲线轨迹、弹性张力、形变强度、流密度等)。@Composable fun MotionPreview() 中,利用 Compose 编写一个悬浮或侧滑的调音台面板。Slider 滑块。Modifier.aspectRatio(16f / 9f) 来限制其渲染比例,成为统一的横版视窗界限。LocalConfiguration 或 BoxWithConstraints 注入的屏幕宽高按百分比映射,实现严丝合缝的自适应特性。remember) 或动画 (animate*AsState) 时,绝对禁止直接函数域调用。必须外包一层 @SuppressLint("ModifierFactoryUnreferencedReceiver") fun Modifier.ext() = composed { ... }!Modifier.drawWithCache 提取截帧或分配 FloatArray 时,必须做零界限检查 if (size.width <= 0f || size.height <= 0f) return@drawWithCache onDrawWithContent {} 防制 Native 层 Crash。Text 传递大小绝对禁止使用 xx.dp。fontSize 必经由 import androidx.compose.ui.unit.sp 限定强转为 .sp。@Composable fun Widget() 时,禁止在内部根节点绑死如 Modifier.align 等必须依赖父 BoxScope 的 API。应暴露 (modifier: Modifier = Modifier) 交由上层父容器指派对齐策略。核心原则: 禁止使用千篇一律的 linear 或单一 ease-in 曲线。必须根据交互语义和目标平台特性智能选择缓动参数,让动画具有生命力。
动画的每一个运动阶段都必须被归类为以下语义之一,然后查表选取推荐曲线:
| 交互语义 | 运动特征 | Web (CSS/JS) 推荐 | Android (Compose) 推荐 |
|---|---|---|---|
| 入场 (Enter) | 元素从无到有,由远及近 | cubic-bezier(0.0, 0.0, 0.2, 1) (Material decelerate) | FastOutSlowInEasing 或 spring(dampingRatio=0.7, stiffness=300) |
| 退场 (Exit) | 元素消失,由近及远 | cubic-bezier(0.4, 0.0, 1, 1) (accelerate) | FastOutLinearInEasing + tween(300) |
| 强调 (Emphasis) | 引起注意的脉冲/抖动 | cubic-bezier(0.175, 0.885, 0.32, 1.275) (overshoot) | spring(dampingRatio=0.4, stiffness=500)(明显弹跳) |
| 跟手 (Gesture Tracking) | 拖拽/滑动时实时跟随 | 无 transition,直接绑定 pointer 坐标 | Animatable.snapTo() 或直接赋值(零延迟) |
| 惯性释放 (Fling) | 手指松开后的惯性滑行 | cubic-bezier(0.4, 0.0, 0.0, 1) + 400ms | decay(absVelocityThreshold=..) 或 spring(stiffness=StiffnessLow) |
| 弹性回位 (Spring Back) | 越界后弹回原位 | cubic-bezier(0.175, 0.885, 0.32, 1.275) | spring(dampingRatio=DampingRatioMediumBouncy, stiffness=StiffnessMedium) |
| 连续流 (Continuous Flow) | 循环播放/粒子轨迹 | linear + requestAnimationFrame | infiniteRepeatable + LinearEasing(仅此场景允许 linear) |
| 级联交错 (Stagger) | 列表项依次入场 | stagger-delay: index * 50ms + decelerate | tween(delay = index * 60, easing = FastOutSlowInEasing) |
cubic-bezier 参数化曲线:CSS transition 引擎对贝塞尔曲线有硬件加速。cubic-bezier(0.175, 0.885, 0.32, 1.275) 产生轻微过冲(overshoot),而非依赖 JS 弹簧库。pointermove 事件直接赋值 transform,不加任何 transition。requestAnimationFrame 循环,每帧按衰减系数 velocity *= 0.95 递减速度。spring() 物理弹簧:Compose 的弹簧引擎利用了原生 API 的帧同步机制,天生比 tween 流畅。spring() 的 dampingRatio 和 stiffness 是灵魂参数,可以精确模拟从过阻尼到欠阻尼的全部物理特性。Animatable.snapTo() 达到无延迟追随。Animatable.animateDecay(initialVelocity, exponentialDecay())。LaunchedEffect(index) 中延迟 delay(index * 60L) 后再启动动画。在生成代码时,必须遵循以下判定流程:
spring() 而非 tween()。LinearEasing 或 linear。| Web (CSS) | Android (Compose) |
|---|---|
transition | animateXAsState() |
@keyframes | Animatable + animateTo() |
ease-in-out | FastOutSlowInEasing |
ease-out | FastOutLinearInEasing |
ease-in | LinearOutSlowInEasing |
linear | LinearEasing |
cubic-bezier(x1,y1,x2,y2) | CubicBezierEasing(x1,y1,x2,y2) |
spring | spring(dampingRatio, stiffness) |
canvas.bindTexture() (WebGL) | RuntimeShader.setInputShader() (AGSL) |
canvas drawBitmapMesh (2D) | Canvas.drawBitmapMesh() |