with one click
motion-to-code
将 UI/UX 动效视频或 GIF 逆向还原为可运行的动效代码(Web + Android Compose)
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
将 UI/UX 动效视频或 GIF 逆向还原为可运行的动效代码(Web + Android Compose)
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| 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() |