Skip to content

Commit 86294d0

Browse files
author
heshenglei
committed
feat: Enhance transition api
1 parent 0f0f5f5 commit 86294d0

File tree

13 files changed

+487
-76
lines changed

13 files changed

+487
-76
lines changed

__tests__/model/animation.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ describe('Animation', () => {
8080
delay: 0,
8181
duration: 100,
8282
timing: 'linear',
83+
fill: 'forwards',
8384
start: startCb,
8485
progress: progressCb,
8586
complete: completeCb,
@@ -262,6 +263,7 @@ describe('Animation', () => {
262263
anim.start('v', 'end', {
263264
delay: 0,
264265
duration: 50,
266+
fill: 'forwards',
265267
interp: interpFactory,
266268
progress: progressCb,
267269
})

examples/src/App.tsx

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
1-
import { Routes, Route } from 'react-router-dom'
1+
import { Route, Routes } from 'react-router-dom'
22
import { ExampleList } from './pages'
3-
import { GraphExample } from './pages/graph/index'
4-
import { PositionExample } from './pages/position/position'
5-
import { CoordExample } from './pages/position/coord'
3+
import { AnimateElementExample } from './pages/animation/animateElement'
4+
import { ComplexTransitionExample } from './pages/animation/complexTransition'
5+
import { EdgeTransitionExample } from './pages/animation/edgeTransition'
6+
import { TransitionConfExample } from './pages/animation/transitionConf'
67
import { AutoResizeExample } from './pages/auto-resize'
7-
import { HtmlExample } from './pages/html'
8-
import { CustomNodeExample } from './pages/shape/custom-node'
9-
import { GroupExample } from './pages/group'
10-
import { EmbedDndExample } from './pages/embed/dnd'
11-
import { ReactExample } from './pages/react/index'
12-
import { ReactPortalExample } from './pages/react/portal'
13-
import { PortsDefaultsExample } from './pages/ports/defaults'
14-
import { PortsConnectedExample } from './pages/ports/connected'
15-
import { EdgeExample } from './pages/edge'
16-
import { RouterExample } from './pages/router'
17-
import { ToolArrowheadExample } from './pages/edge/tool/arrowhead'
18-
import { ToolButtonExample } from './pages/edge/tool/button'
19-
import { CustomConnectorExample } from './pages/edge/custom-connector'
20-
import { CustomRouterExample } from './pages/edge/custom-router'
21-
import { NativeMarkerExample } from './pages/edge/native-marker'
22-
import { CustomMarkerExample } from './pages/edge/custom-marker'
23-
import { EdgeEditorExample } from './pages/edge/edge-editor'
24-
import { OffsetRoundedExample } from './pages/connector/offset-rounded'
25-
import { XmindCurveExample } from './pages/connector/xmind-curve'
26-
import { ToolsCleanExample } from './pages/tools/clean'
278
import { CaseBpmnExample } from './pages/case/bpmn'
289
import { CaseClassExample } from './pages/case/class'
2910
import { CaseDagExample } from './pages/case/dag'
3011
import { CaseElkExample } from './pages/case/elk'
3112
import { CaseErExample } from './pages/case/er'
3213
import { CaseMindExample } from './pages/case/mind'
3314
import { CaseSwimlaneExample } from './pages/case/swimlane'
15+
import { OffsetRoundedExample } from './pages/connector/offset-rounded'
16+
import { XmindCurveExample } from './pages/connector/xmind-curve'
17+
import { EdgeExample } from './pages/edge'
18+
import { CustomConnectorExample } from './pages/edge/custom-connector'
19+
import { CustomMarkerExample } from './pages/edge/custom-marker'
20+
import { CustomRouterExample } from './pages/edge/custom-router'
21+
import { EdgeEditorExample } from './pages/edge/edge-editor'
22+
import { NativeMarkerExample } from './pages/edge/native-marker'
23+
import { ToolArrowheadExample } from './pages/edge/tool/arrowhead'
24+
import { ToolButtonExample } from './pages/edge/tool/button'
25+
import { SegmentsExample } from './pages/edge/tool/segments'
26+
import { EmbedDndExample } from './pages/embed/dnd'
27+
import { GraphFromJSONExample } from './pages/graph/from-json'
28+
import { GraphExample } from './pages/graph/index'
29+
import { GroupExample } from './pages/group'
30+
import { HistoryExample } from './pages/history'
31+
import { HtmlExample } from './pages/html'
3432
import { OrgExample } from './pages/org'
35-
import { SnaplineExample } from './pages/plugins/snapline'
3633
import { ClipboardExample } from './pages/plugins/clipboard'
37-
import { KeyboardExample } from './pages/plugins/keyboard'
3834
import { DndExample } from './pages/plugins/dnd'
35+
import { ExportExample } from './pages/plugins/export'
36+
import { KeyboardExample } from './pages/plugins/keyboard'
3937
import { ScrollerExample } from './pages/plugins/scroller'
4038
import { SelectionExample } from './pages/plugins/selection'
39+
import { SnaplineExample } from './pages/plugins/snapline'
4140
import { StencilExample } from './pages/plugins/stencil'
4241
import { TransformExample } from './pages/plugins/transform'
4342
import { UndoExample } from './pages/plugins/undo'
44-
import { ExportExample } from './pages/plugins/export'
45-
import { TransitionExample } from './pages/animation/transition'
46-
import { HistoryExample } from './pages/history'
47-
import { SegmentsExample } from './pages/edge/tool/segments'
48-
import { GraphFromJSONExample } from './pages/graph/from-json'
43+
import { PortsConnectedExample } from './pages/ports/connected'
44+
import { PortsDefaultsExample } from './pages/ports/defaults'
45+
import { CoordExample } from './pages/position/coord'
46+
import { PositionExample } from './pages/position/position'
47+
import { ReactExample } from './pages/react/index'
48+
import { ReactPortalExample } from './pages/react/portal'
49+
import { RouterExample } from './pages/router'
50+
import { CustomNodeExample } from './pages/shape/custom-node'
51+
import { ToolsCleanExample } from './pages/tools/clean'
4952
import { VirtualRenderExample } from './pages/virtual-render'
5053
import './App.less'
5154

@@ -106,7 +109,22 @@ function App() {
106109
<Route path="/plugins/undo" element={<UndoExample />} />
107110
<Route path="/plugins/export" element={<ExportExample />} />
108111

109-
<Route path="/animation/transition" element={<TransitionExample />} />
112+
<Route
113+
path="/animation/complexTransition"
114+
element={<ComplexTransitionExample />}
115+
/>
116+
<Route
117+
path="/animation/transitionConf"
118+
element={<TransitionConfExample />}
119+
/>
120+
<Route
121+
path="/animation/animateElement"
122+
element={<AnimateElementExample />}
123+
/>
124+
<Route
125+
path="/animation/edgeTransition"
126+
element={<EdgeTransitionExample />}
127+
/>
110128
<Route path="/history" element={<HistoryExample />} />
111129
<Route path="/virtual-render" element={<VirtualRenderExample />} />
112130
</Routes>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { Graph } from '@antv/x6'
2+
import React from 'react'
3+
import '../index.less'
4+
5+
export class AnimateElementExample extends React.Component {
6+
private container!: HTMLDivElement
7+
8+
componentDidMount() {
9+
const graph = new Graph({
10+
container: this.container,
11+
width: 650,
12+
height: 400,
13+
background: {
14+
color: '#F2F7FA',
15+
},
16+
})
17+
18+
const node1 = graph.addNode({
19+
shape: 'rect',
20+
x: 10,
21+
y: 10,
22+
width: 80,
23+
height: 40,
24+
label: 'rect',
25+
})
26+
const view1 = graph.findViewByCell(node1)
27+
28+
view1?.once('view:render', ({ view }) => {
29+
// 可使用 animate、animateMotion、animateTransform 等原生svg动画元素来实现动画
30+
// 元素相关API可参考:https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/animateMotion
31+
const animateEle = document.createElementNS(
32+
'http://www.w3.org/2000/svg',
33+
'animate',
34+
)
35+
animateEle.setAttribute('attributeType', 'CSS')
36+
animateEle.setAttribute('attributeName', 'fill')
37+
animateEle.setAttribute('from', 'red')
38+
animateEle.setAttribute('to', 'green')
39+
animateEle.setAttribute('dur', '2s')
40+
animateEle.setAttribute('repeatCount', 'indefinite')
41+
42+
view?.container?.querySelector('rect')?.appendChild(animateEle)
43+
})
44+
45+
const node2 = graph.addNode({
46+
shape: 'rect',
47+
x: 80,
48+
y: 120,
49+
width: 40,
50+
height: 40,
51+
})
52+
const view2 = graph.findViewByCell(node2)
53+
54+
view2?.once('view:render', ({ view }) => {
55+
const animateEle = document.createElementNS(
56+
'http://www.w3.org/2000/svg',
57+
'animateTransform',
58+
)
59+
animateEle.setAttribute('attributeType', 'XML')
60+
animateEle.setAttribute('attributeName', 'transform')
61+
animateEle.setAttribute('type', 'rotate')
62+
animateEle.setAttribute('from', '0 0 0')
63+
animateEle.setAttribute('to', '360 0 0')
64+
animateEle.setAttribute('dur', '3s')
65+
animateEle.setAttribute('repeatCount', 'indefinite')
66+
67+
view?.container?.querySelector('rect')?.appendChild(animateEle)
68+
})
69+
}
70+
71+
refContainer = (container: HTMLDivElement) => {
72+
this.container = container
73+
}
74+
75+
render() {
76+
return (
77+
<div className="x6-graph-wrap">
78+
<div ref={this.refContainer} className="x6-graph" />
79+
</div>
80+
)
81+
}
82+
}

examples/src/pages/animation/transition.tsx renamed to examples/src/pages/animation/complexTransition.tsx

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { Graph, Interp, type Point, Timing } from '@antv/x6'
12
import React from 'react'
2-
import { Graph, Cell, Point, Timing, Interp } from '@antv/x6'
33
import '../index.less'
44

5-
export class TransitionExample extends React.Component {
5+
export class ComplexTransitionExample extends React.Component {
66
private container!: HTMLDivElement
77

88
componentDidMount() {
@@ -68,12 +68,10 @@ export class TransitionExample extends React.Component {
6868
start: { text: string; fontSize: number },
6969
end: { text: string; fontSize: number },
7070
) => {
71-
return function (time: number) {
72-
return {
73-
text: end.text.substr(0, Math.ceil(end.text.length * time)),
74-
fontSize: start.fontSize + (end.fontSize - start.fontSize) * time,
75-
}
76-
}
71+
return (time: number) => ({
72+
text: end.text.substr(0, Math.ceil(end.text.length * time)),
73+
fontSize: start.fontSize + (end.fontSize - start.fontSize) * time,
74+
})
7775
},
7876
},
7977
)
@@ -98,24 +96,15 @@ export class TransitionExample extends React.Component {
9896
},
9997
})
10098

101-
function fly(cell: Cell) {
102-
cell.transition('position', 20, {
103-
delay: 0,
104-
duration: 5000,
105-
interp: function (a: Point.PointLike, b: number) {
106-
return function (t: number) {
107-
return {
108-
x: a.x + 10 * b * (Math.cos(t * 2 * Math.PI) - 1),
109-
y: a.y - b * Math.sin(t * 2 * Math.PI),
110-
}
111-
}
112-
},
113-
})
114-
}
115-
116-
fly(ufo)
117-
118-
ufo.on('transition:complete', ({ cell }) => fly(cell))
99+
ufo.transition('position', 20, {
100+
delay: 0,
101+
duration: 5000,
102+
iterations: Infinity,
103+
interp: (a: Point.PointLike, b: number) => (t: number) => ({
104+
x: a.x + 10 * b * (Math.cos(t * 2 * Math.PI) - 1),
105+
y: a.y - b * Math.sin(t * 2 * Math.PI),
106+
}),
107+
})
119108
}
120109

121110
refContainer = (container: HTMLDivElement) => {

0 commit comments

Comments
 (0)