slidev-magic-move
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseShiki Magic Move
Shiki Magic Move
This skill covers Shiki Magic Move, a powerful feature that creates smooth animated transitions between different code states, similar to Keynote's Magic Move effect.
本技能介绍Shiki Magic Move,这是一个强大的功能,可在不同代码状态间创建流畅的动画过渡效果,类似Keynote的Magic Move效果。
When to Use This Skill
何时使用本技能
- Showing code evolution step by step
- Refactoring demonstrations
- Before/after code comparisons
- Tutorial walkthroughs
- Animated code transformations
- 逐步展示代码演进过程
- 重构演示
- 代码前后对比
- 教程步骤讲解
- 代码转换动画
How Magic Move Works
Magic Move的工作原理
Magic Move analyzes two code blocks and:
- Identifies unchanged tokens
- Finds moved/renamed tokens
- Detects added/removed tokens
- Animates the transition smoothly
Magic Move会分析两段代码块并:
- 识别未更改的代码标记
- 查找移动/重命名的代码标记
- 检测新增/删除的代码标记
- 流畅地为过渡过程添加动画
Basic Syntax
基本语法
Use 4 backticks with :
md magic-movemarkdown
````md magic-move
```js
console.log('Hello')
```
```js
console.log('Hello, World!')
```
````Each code block represents a step, animated on click.
使用4个反引号并加上:
md magic-movemarkdown
````md magic-move
```js
console.log('Hello')
```
```js
console.log('Hello, World!')
```
````每个代码块代表一个步骤,点击时会播放动画。
Step-by-Step Example
分步示例
Refactoring Journey
重构过程演示
markdown
````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
```
````markdown
````md magic-move
```js
// Step 1: 原始代码
function add(a, b) {
return a + b
}
```
```js
// Step 2: 添加类型注解
function add(a: number, b: number) {
return a + b
}
```
```js
// Step 3: 添加返回值类型
function add(a: number, b: number): number {
return a + b
}
```
```ts
// Step 4: 转换为箭头函数
const add = (a: number, b: number): number => a + b
```
````Multiple Steps
多步骤演示
markdown
````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!
```
````markdown
````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!
```
````Combining with Line Highlighting
结合行高亮功能
Add highlights within Magic Move:
markdown
````md magic-move {lines: true}
```js {*|1|2|3}
const a = 1
const b = 2
const c = 3
```
```js {*}
const sum = 1 + 2 + 3
```
````在Magic Move中添加高亮效果:
markdown
````md magic-move {lines: true}
```js {*|1|2|3}
const a = 1
const b = 2
const c = 3
```
```js {*}
const sum = 1 + 2 + 3
```
````Advanced Options
高级选项
Control Animation Timing
控制动画触发时机
markdown
````md magic-move {at: 3}
```js
// Starts at click 3
const x = 1
```
```js
const x = 1
const y = 2
```
````markdown
````md magic-move {at: 3}
```js
// 第3次点击时开始
const x = 1
```
```js
const x = 1
const y = 2
```
````Disable Line Numbers
禁用行号
markdown
````md magic-move {lines: false}
```js
const x = 1
```
```js
const x = 2
```
````markdown
````md magic-move {lines: false}
```js
const x = 1
```
```js
const x = 2
```
````Combined Options
组合选项
markdown
````md magic-move {at: 2, lines: true}
```js {*|1|2}
const first = 1
const second = 2
```
```js {*}
const result = first + second
```
````markdown
````md magic-move {at: 2, lines: true}
```js {*|1|2}
const first = 1
const second = 2
```
```js {*}
const result = first + second
```
````Real-World Examples
实际场景示例
React Hook Evolution
React Hook演进
markdown
````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>
)
}
```
````markdown
````md magic-move
```jsx
// 类组件状态
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
// 函数组件结合useState
function Counter() {
const [count, setCount] = useState(0)
const increment = () => {
setCount(count + 1)
}
return (
<button onClick={increment}>
{count}
</button>
)
}
```
```jsx
// 内联处理函数简化版
function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(c => c + 1)}>
{count}
</button>
)
}
```
````API Evolution
API演进
markdown
````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)
}
```
````markdown
````md magic-move
```js
// 回调函数方式
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
// Promise方式
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)
}
```
````Building a Function
函数构建过程
markdown
````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))
}
```
````markdown
````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 Query Building
SQL查询构建
markdown
````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
```
````markdown
````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
```
````Patterns and Tips
模式与技巧
Start Simple, Add Complexity
从简到繁,逐步添加复杂度
markdown
````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)
```
````markdown
````md magic-move
```js
// 先展示最终目标
const result = processData(input)
```
```js
// 展示实现过程
function processData(input) {
return input
}
const result = processData(input)
```
```js
// 添加细节
function processData(input) {
return input
.filter(x => x != null)
.map(x => transform(x))
}
const result = processData(input)
```
````Show Problem Then Solution
先展示问题,再给出解决方案
markdown
````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!
})
```
````markdown
````md magic-move
```js
// 问题:回调地狱
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
getMoreData(c, function(d) {
// 终于完成了
})
})
})
})
```
```js
// 解决方案:Promise
getData()
.then(a => getMoreData(a))
.then(b => getMoreData(b))
.then(c => getMoreData(c))
.then(d => {
// 简洁又清晰!
})
```
````Highlight Changes with Comments
用注释高亮变更点
markdown
````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!
}
```
````markdown
````md magic-move
```js
const config = {
debug: true,
timeout: 1000
}
```
```js
const config = {
debug: false, // 已修改!
timeout: 1000
}
```
```js
const config = {
debug: false,
timeout: 5000 // 已延长!
}
```
````Best Practices
最佳实践
- Small Steps: Each transition should show one logical change
- Maintain Context: Keep surrounding code visible when possible
- Use Comments: Add comments to explain what's changing
- Consistent Style: Keep formatting consistent across steps
- Test the Animation: Verify smooth transitions before presenting
- 小步迭代:每次过渡只展示一个逻辑变更
- 保留上下文:尽可能保留周边代码的可见性
- 使用注释:添加注释解释变更内容
- 风格一致:确保各步骤的代码格式一致
- 测试动画:在展示前验证过渡效果是否流畅
Common Mistakes
常见错误
❌ Too many changes at once
Step 1: Original code
Step 2: Completely different code✓ Incremental changes
Step 1: Original
Step 2: Add one feature
Step 3: Add another feature
Step 4: Refactor❌ Lost context
Step 1: function foo() { ... }
Step 2: const bar = ... // Where did foo go?✓ Preserved context
Step 1: function foo() { ... }
Step 2: function foo() { const bar = ... }❌ 单次变更过多
步骤1:原始代码
步骤2:完全不同的代码✓ 增量式变更
步骤1:原始代码
步骤2:添加一个功能
步骤3:添加另一个功能
步骤4:重构代码❌ 丢失上下文
步骤1:function foo() { ... }
步骤2:const bar = ... // foo去哪了?✓ 保留上下文
步骤1:function foo() { ... }
步骤2:function foo() { const bar = ... }Interactive Playground
交互式体验 playground
Try Magic Move at: https://shiki-magic-move.netlify.app/
访问以下地址体验Magic Move:https://shiki-magic-move.netlify.app/
Output Format
输出格式
When creating Magic Move animations:
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]
```创建Magic Move动画时的参考格式:
ANIMATION GOAL: [你要展示的转换效果是什么?]
STEPS:
1. [初始状态 - 描述]
2. [变更1 - 描述]
3. [变更2 - 描述]
...
CODE:
````md magic-move {[选项]}
```[语言]
[步骤1代码][步骤2代码]...
SPEAKER NOTES:
- Step 1: [讲解内容]
- Step 2: [讲解内容]
```