packages/storybook/stories/animation-basic.stories.tsx (70 lines of code) (raw):
import { DebugFlags, Point, Rect, RenderPath, RenderView, Size } from '@canvas-ui/core'
import { Canvas, Path, Text, View } from '@canvas-ui/react'
import { StoryObj } from '@storybook/react'
import { animate } from '@canvas-ui/animation'
import { spring } from 'motion'
import React from 'react'
const path = `M266.24 420.0448a30.8736 30.8736 0 0 1 52.736-21.8624L512 591.0016l192.9728-192.8192a30.8736 30.8736 0 1 1 43.7248 43.7248l-214.8352 214.6304a31.0272 31.0272 0 0 1-43.776 0L275.3024 441.9072a30.8736 30.8736 0 0 1-9.0624-21.8624z`
export const AnimationBasic: StoryObj<React.FC> = () => {
React.useEffect(() => {
DebugFlags.set(
0
| DebugFlags.NodeBounds
| DebugFlags.LayerBounds
| DebugFlags.RasterCacheWaterMark
| DebugFlags.PathBounds
)
}, [])
const viewRef = React.useRef<RenderView>(null)
const handleClickLeft = () => {
move(-100)
}
const handleClickRight = () => {
move(100)
}
const move = (delta: number) => {
animate(viewRef.current!, {
offset: Point.add(viewRef.current!.offset, Point.fromXY(delta, 0)),
}, {
duration: 0.8,
type: spring,
})
const pathEl = viewRef.current?.firstChild as RenderPath
pathEl.rotation = 0
animate(pathEl, {
rotation: 360 * Math.sign(delta),
}, {
duration: 1.333,
type: spring,
})
}
return (
<div style={{ height: '100px' }}>
<div>
<button onClick={handleClickLeft}>move left</button>
<button onClick={handleClickRight}>move right</button>
</div>
<Canvas>
<View ref={viewRef} size={Size.fromWH(200, 200)}>
<Path
fill={'#ff0000'}
path={path}
style={{ left: 0, top: 0, width: 100, height: 100 }}
pathBounds={Rect.fromLTWH(0, 0, 1024, 1024)}
rotation={0}
transformOrigin={Point.fromXY(0.5, 0.5)}
/>
<Text>
Monkey 🐒
</Text>
</View>
</Canvas>
</div>
)
}
AnimationBasic.storyName = 'AnimationBasic'
export default {
title: 'animation',
component: AnimationBasic,
decorators: [(Story: React.ComponentType) => <div style={{ backgroundColor: '#efefef', width: '100%', height: '100vh' }}><Story /></div>],
}