mcpField
S
slidev-magic-move

slidev-magic-move

github.com/yoanbernabeu文档处理41204 次安装39 周前更新
代码仓库

关于 slidev-magic-move

一项介绍在 Slidev 中使用 Shiki Magic Move 制作代码演示的技能,适合教程、重构演示和代码对比。它涵盖代码状态间的动画过渡及相关选项。

主要功能

  1. 01为不同代码状态添加动画过渡
  2. 02展示新增、删除和移动的代码标记
  3. 03结合行高亮展示代码
  4. 04设置动画时机和行号

适用场景

  1. 01逐步讲解代码变化
  2. 02演示重构过程
  3. 03对比修改前后的代码

安装

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

$npx skills add https://github.com/yoanbernabeu/slidev-skills --skill slidev-magic-move

安装后在 Claude Code 中输入/slidev-magic-move确认已加载。

详细介绍

Shiki Magic Move

这项技能介绍 Shiki Magic Move,这是一项强大的功能,可在不同代码状态之间创建流畅的动画过渡,类似于 Keynote 的 Magic Move 效果。

何时使用这项技能

  • 逐步展示代码演变
  • 演示重构
  • 对比代码修改前后的差异
  • 演示教程步骤
  • 展示代码转换动画

Magic Move 的工作原理

Magic Move 会分析两个代码块,并:

  1. 识别未更改的令牌
  2. 查找移动或重命名的令牌
  3. 检测新增或删除的令牌
  4. 流畅地为过渡添加动画

基本语法

使用 4 个反引号和 md magic-move:

````md magic-move
```js
console.log('Hello')
```
```js
console.log('Hello, World!')
```
````

每个代码块代表一个步骤,点击后会播放动画。

分步示例

重构之旅
````md magic-move
```js
// Step 1: Original code
function add(a, b) {
  return a + b
}
```

```js
// Step 2: Add types
function add(a: number, b: number) {
  return a + b
}
```

```js
// Step 3: Add return type
function add(a: number, b: number): number {
  return a + b
}
```

```ts
// Step 4: Convert to arrow function
const add = (a: number, b: number): number => a + b
```
````

多个步骤

````md magic-move
```js
const name = 'world'
```
```js
const name = 'world'
const greeting = 'Hello'
```
```js
const name = 'world'
const greeting = 'Hello'
console.log(`${greeting}, ${name}!`)
```
```js
const name = 'world'
const greeting = 'Hello'
console.log(`${greeting}, ${name}!`)
// Output: Hello, world!
```
````

与行高亮结合使用

在 Magic Move 中添加高亮:

````md magic-move {lines: true}
```js {*|1|2|3}
const a = 1
const b = 2
const c = 3
```
```js {*}
const sum = 1 + 2 + 3
```
````

高级选项

控制动画时长
````md magic-move {at: 3}
```js
// Starts at click 3
const x = 1
```
```js
const x = 1
const y = 2
```
````
禁用行号
````md magic-move {lines: false}
```js
const x = 1
```
```js
const x = 2
```
````
组合选项
````md magic-move {at: 2, lines: true}
```js {*|1|2}
const first = 1
const second = 2
```
```js {*}
const result = first + second
```
````

实际示例

React Hook 的演变
````md magic-move
```jsx
// Class component state
class Counter extends React.Component {
  state = { count: 0 }

  increment = () => {
    this.setState({ count: this.state.count + 1 })
  }

  render() {
    return (
      <button onClick={this.increment}>
        {this.state.count}
      </button>
    )
  }
}
```

```jsx
// Function component with useState
function Counter() {
  const [count, setCount] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }

  return (
    <button onClick={increment}>
      {count}
    </button>
  )
}
```

```jsx
// Simplified with inline handler
function Counter() {
  const [count, setCount] = useState(0)

  return (
    <button onClick={() => setCount(c => c + 1)}>
      {count}
    </button>
  )
}
```
````
API 的演变
````md magic-move
```js
// Callbacks
function fetchUser(id, callback) {
  fetch(`/api/users/${id}`)
    .then(res => res.json())
    .then(data => callback(null, data))
    .catch(err => callback(err, null))
}

fetchUser(1, (err, user) => {
  if (err) console.error(err)
  else console.log(user)
})
```

```js
// Promises
function fetchUser(id) {
  return fetch(`/api/users/${id}`)
    .then(res => res.json())
}

fetchUser(1)
  .then(user => console.log(user))
  .catch(err => console.error(err))
```

```js
// Async/Await
async function fetchUser(id) {
  const res = await fetch(`/api/users/${id}`)
  return res.json()
}

try {
  const user = await fetchUser(1)
  console.log(user)
} catch (err) {
  console.error(err)
}
```
````
构建函数
````md magic-move
```typescript
function processData() {

}
```

```typescript
function processData(data) {

}
```

```typescript
function processData(data: string[]) {

}
```

```typescript
function processData(data: string[]): string[] {
  return data
}
```

```typescript
function processData(data: string[]): string[] {
  return data
    .filter(item => item.length > 0)
}
```

```typescript
function processData(data: string[]): string[] {
  return data
    .filter(item => item.length > 0)
    .map(item => item.trim())
}
```

```typescript
function processData(data: string[]): string[] {
  return data
    .filter(item => item.length > 0)
    .map(item => item.trim())
    .sort((a, b) => a.localeCompare(b))
}
```
````
构建 SQL 查询
````md magic-move
```sql
SELECT * FROM users
```

```sql
SELECT id, name, email FROM users
```

```sql
SELECT id, name, email FROM users
WHERE active = true
```

```sql
SELECT id, name, email FROM users
WHERE active = true
ORDER BY created_at DESC
```

```sql
SELECT id, name, email FROM users
WHERE active = true
ORDER BY created_at DESC
LIMIT 10
```
````

模式与技巧

从简单开始,逐步增加复杂度
````md magic-move
```js
// Start with the goal
const result = processData(input)
```

```js
// Show the implementation
function processData(input) {
  return input
}

const result = processData(input)
```

```js
// Add details
function processData(input) {
  return input
    .filter(x => x != null)
    .map(x => transform(x))
}

const result = processData(input)
```
````
先展示问题,再展示解决方案
````md magic-move
```js
// Problem: Callback hell
getData(function(a) {
  getMoreData(a, function(b) {
    getMoreData(b, function(c) {
      getMoreData(c, function(d) {
        // Finally done
      })
    })
  })
})
```

```js
// Solution: Promises
getData()
  .then(a => getMoreData(a))
  .then(b => getMoreData(b))
  .then(c => getMoreData(c))
  .then(d => {
    // Clean and flat!
  })
```
````
使用注释突出变化
````md magic-move
```js
const config = {
  debug: true,
  timeout: 1000
}
```

```js
const config = {
  debug: false,    // Changed!
  timeout: 1000
}
```

```js
const config = {
  debug: false,
  timeout: 5000    // Increased!
}
```
````

最佳实践

  1. 小步推进:每次过渡只展示一个逻辑上的变化
  2. 保持上下文:尽可能保留周围的代码
  3. 使用注释:添加注释,解释发生了什么变化
  4. 保持风格一致:确保各个步骤的格式一致
  5. 测试动画:演示前确认过渡流畅

常见错误

❌ 一次更改太多

Step 1: Original code
Step 2: Completely different code

✓ 逐步更改

Step 1: Original
Step 2: Add one feature
Step 3: Add another feature
Step 4: Refactor

❌ 上下文丢失

Step 1: function foo() { ... }
Step 2: const bar = ...  // Where did foo go?

✓ 保留上下文

Step 1: function foo() { ... }
Step 2: function foo() { const bar = ... }

互动体验

在此试用 Magic Move:https://shiki-magic-move.netlify.app/

输出格式

创建 Magic Move 动画时:

ANIMATION GOAL: [What transformation are you showing?]

STEPS:
1. [Initial state - describe]
2. [Change 1 - describe]
3. [Change 2 - describe]
...

CODE:
````md magic-move {[options]}
```[lang]
[Step 1 code]
[Step 2 code]

...


SPEAKER NOTES:
- Step 1: [What to say]
- Step 2: [What to say]
```

评论

支持 Markdown