mcpField
P
popmotion

popmotion

github.com/dylantarre设计与 UI132493 次安装43 周前更新
代码仓库

关于 popmotion

这项技能通过 Popmotion 的可组合动画函数实现迪士尼 12 条动画原则,适用于制作界面动效或其他动画内容的开发者。

主要功能

  1. 01涵盖 12 条动画原则的示例
  2. 02补间、弹簧与关键帧动画
  3. 03衰减与缓动函数
  4. 04可组合且不依赖框架的函数

适用场景

  1. 01制作挤压与拉伸动效
  2. 02创建多阶段动画序列
  3. 03加入惯性或弹簧运动

安装

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

$npx skills add https://github.com/dylantarre/animation-principles --skill popmotion

安装后在 Claude Code 中输入/popmotion确认已加载。

详细介绍

Popmotion 动画原则

使用 Popmotion 可组合的动画函数实现迪士尼动画的全部 12 条原则。

1. 挤压与拉伸

import { animate } from "popmotion";

animate({
  from: { scaleX: 1, scaleY: 1 },
  to: { scaleX: 1.2, scaleY: 0.8 },
  duration: 150,
  onUpdate: ({ scaleX, scaleY }) => {
    element.style.transform = `scaleX(${scaleX}) scaleY(${scaleY})`;
  }
});

2. 预备动作

// Wind up then action
animate({
  from: 0,
  to: 10,
  duration: 200,
  onUpdate: v => element.style.transform = `translateY(${v}px) scaleY(0.9)`,
  onComplete: () => {
    animate({
      from: 10,
      to: -200,
      duration: 400,
      ease: easeOut,
      onUpdate: v => element.style.transform = `translateY(${v}px)`
    });
  }
});

3. 演出布局

animate({
  from: 1,
  to: 0.6,
  onUpdate: v => bg.style.opacity = v
});
animate({
  from: 1,
  to: 1.1,
  onUpdate: v => hero.style.transform = `scale(${v})`
});

4. 直线运动/姿势到姿势

import { keyframes } from "popmotion";

keyframes({
  values: [
    { x: 0, y: 0 },
    { x: 100, y: -50 },
    { x: 200, y: 0 },
    { x: 300, y: -30 }
  ],
  duration: 1000,
  onUpdate: ({ x, y }) => {
    element.style.transform = `translate(${x}px, ${y}px)`;
  }
});

5. 跟随动作与重叠动作

animate({ from: 0, to: 200, duration: 500,
  onUpdate: v => body.style.transform = `translateX(${v}px)` });

animate({ from: 0, to: 200, duration: 500, elapsed: -50, // delay
  onUpdate: v => hair.style.transform = `translateX(${v}px)` });

animate({ from: 0, to: 200, duration: 600, elapsed: -100,
  onUpdate: v => cape.style.transform = `translateX(${v}px)` });

6. 慢入与慢出

import { animate, easeInOut, easeIn, easeOut } from "popmotion";

animate({
  from: 0,
  to: 300,
  duration: 600,
  ease: easeInOut,
  onUpdate: v => element.style.transform = `translateX(${v}px)`
});

7. 弧线运动

keyframes({
  values: [
    { x: 0, y: 0 },
    { x: 100, y: -100 },
    { x: 200, y: 0 }
  ],
  duration: 1000,
  ease: easeInOut,
  onUpdate: ({ x, y }) => {
    element.style.transform = `translate(${x}px, ${y}px)`;
  }
});

8. 次要动作

// Primary action triggers secondary
animate({
  from: 1, to: 1.1, duration: 200,
  onUpdate: v => button.style.transform = `scale(${v})`,
  onComplete: () => {
    animate({
      from: 0, to: 15, duration: 150,
      onUpdate: v => icon.style.transform = `rotate(${v}deg)`
    });
  }
});

9. 时间控制

import { spring } from "popmotion";

// Fast
animate({ from: 0, to: 100, duration: 150 });

// Spring physics
spring({
  from: 0,
  to: 100,
  stiffness: 300,
  damping: 20,
  onUpdate: v => element.style.transform = `translateX(${v}px)`
});

// Slow
animate({ from: 0, to: 100, duration: 800, ease: easeOut });

10. 夸张

spring({
  from: { scale: 1, rotate: 0 },
  to: { scale: 1.5, rotate: 720 },
  stiffness: 200,
  damping: 10, // low = overshoot
  onUpdate: ({ scale, rotate }) => {
    element.style.transform = `scale(${scale}) rotate(${rotate}deg)`;
  }
});

11. 扎实绘制

animate({
  from: { rotateX: 0, rotateY: 0 },
  to: { rotateX: 45, rotateY: 30 },
  duration: 500,
  onUpdate: ({ rotateX, rotateY }) => {
    box.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
  }
});

12. 吸引力

animate({
  from: 1,
  to: 1.02,
  duration: 300,
  ease: easeOut,
  onUpdate: v => {
    card.style.transform = `scale(${v})`;
    card.style.boxShadow = `0 ${20*v}px 40px rgba(0,0,0,${0.2*v})`;
  }
});

Popmotion 的主要特性

  • animate() - 补间动画
  • spring() - 基于物理的弹簧动画
  • keyframes() - 多步骤动画
  • decay() - 动量/惯性
  • easeIn、easeOut、easeInOut - 缓动函数
  • 可组合函数 - 混合与管道连接
  • 与框架无关
  • 在底层为 Framer Motion 提供支持

评论

支持 Markdown