标记过渡
在标记级别为代码块之间的过渡添加动画效果。
content.md
```scalaobject Main {def factorial(n: Int): Int = {if (n == 0) {return 1} else {return n * factorial(n - 1)}}}``````pythondef factorial(n):if n == 0:return 1else:return n * factorial(n - 1)```
object Main {def factorial(n: Int): Int = {if (n == 0) {return 1} else {return n * factorial(n - 1)}}}
Implementation
我们将使用来自 codehike/utils/token-transitions 的一些工具函数。使用它们最简单的方式是在类组件内部:
smooth-pre.tsx
"use client"import { CustomPreProps, InnerPre, getPreRef } from "codehike/code"import {TokenTransitionsSnapshot,calculateTransitions,getStartingSnapshot,} from "codehike/utils/token-transitions"import React from "react"const MAX_TRANSITION_DURATION = 900 // millisecondsexport class SmoothPre extends React.Component<CustomPreProps> {ref: React.RefObject<HTMLPreElement>constructor(props: CustomPreProps) {super(props)this.ref = getPreRef(this.props)}render() {return <InnerPre merge={this.props} style={{ position: "relative" }} />}getSnapshotBeforeUpdate() {return getStartingSnapshot(this.ref.current!)}componentDidUpdate(prevProps: never,prevState: never,snapshot: TokenTransitionsSnapshot,) {const transitions = calculateTransitions(this.ref.current!, snapshot)transitions.forEach(({ element, keyframes, options }) => {const { translateX, translateY, ...kf } = keyframes as anyif (translateX && translateY) {kf.translate = [`${translateX[0]}px ${translateY[0]}px`,`${translateX[1]}px ${translateY[1]}px`,]}element.animate(kf, {duration: options.duration * MAX_TRANSITION_DURATION,delay: options.delay * MAX_TRANSITION_DURATION,easing: options.easing,fill: "both",})})}}
然后我们创建注释处理器:
code.tsx
import { AnnotationHandler, InnerToken } from "codehike/code"import { SmoothPre } from "./smooth-pre"export const tokenTransitions: AnnotationHandler = {name: "token-transitions",PreWithRef: SmoothPre,Token: (props) => (<InnerToken merge={props} style={{ display: "inline-block" }} />),}
然后将处理器传递给 Pre 组件:
page.tsx
async function Code({ codeblock }: { codeblock: RawCode }) {const highlighted = await highlight(codeblock, "github-dark")return <Pre code={highlighted} handlers={[tokenTransitions]} />}
当 codeblock 发生变化时,Code 组件将为旧代码块和新代码块之间的过渡添加动画效果。