committed by
拾邑
12 changed files with 274 additions and 12 deletions
@ -0,0 +1,72 @@ |
|||||
|
import * as React from 'react'; |
||||
|
import styled from '@emotion/styled'; |
||||
|
import { Graph, UndoManager } from '@antv/x6'; |
||||
|
import { Tooltip } from 'antd'; |
||||
|
import { bindKey } from '../utils/tool'; |
||||
|
import getCommands from '../data/commands'; |
||||
|
import 'antd/lib/tooltip/style'; |
||||
|
|
||||
|
export interface ToolbarProps { |
||||
|
graph: Graph; |
||||
|
} |
||||
|
|
||||
|
const Group = styled.div` |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
box-sizing: border-box; |
||||
|
padding: 5px; |
||||
|
line-height: 25px; |
||||
|
|
||||
|
:first-of-type { |
||||
|
:before { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
:before { |
||||
|
content: ''; |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
width: 1px; |
||||
|
height: 12px; |
||||
|
background: #d2d2d2; |
||||
|
top: 50%; |
||||
|
left: 0; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
`;
|
||||
|
|
||||
|
const Item = styled.span` |
||||
|
display: inline-block; |
||||
|
margin: 0 2px; |
||||
|
padding: 0 5px; |
||||
|
border-radius: 3px; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
:hover { |
||||
|
background: #ddd; |
||||
|
} |
||||
|
`;
|
||||
|
|
||||
|
const Toolbar = ({ graph }: ToolbarProps): JSX.Element => { |
||||
|
const undoManager = UndoManager.create(graph); |
||||
|
const commands = getCommands(graph, undoManager); |
||||
|
|
||||
|
bindKey(commands, graph); |
||||
|
|
||||
|
return ( |
||||
|
<div> |
||||
|
{commands.map((items) => ( |
||||
|
<Group key={items.map((i) => i.name).join('-')}> |
||||
|
{items.map((item) => ( |
||||
|
<Tooltip title={item.tooltip} key={item.name}> |
||||
|
<Item onClick={item.handler}>{item.icon}</Item> |
||||
|
</Tooltip> |
||||
|
))} |
||||
|
</Group> |
||||
|
))} |
||||
|
</div> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default Toolbar; |
@ -0,0 +1,88 @@ |
|||||
|
import * as React from 'react'; |
||||
|
import { |
||||
|
UndoOutlined, |
||||
|
RedoOutlined, |
||||
|
ZoomInOutlined, |
||||
|
ZoomOutOutlined, |
||||
|
RetweetOutlined, |
||||
|
FullscreenOutlined, |
||||
|
DeleteOutlined, |
||||
|
SaveOutlined, |
||||
|
} from '@ant-design/icons'; |
||||
|
import { Graph, UndoManager } from '@antv/x6'; |
||||
|
import * as Tool from '../utils/tool'; |
||||
|
import { Commands } from '../model'; |
||||
|
|
||||
|
export default function getCommands(graph: Graph, undoManager: UndoManager): Commands { |
||||
|
return [ |
||||
|
[ |
||||
|
{ |
||||
|
name: 'undo', |
||||
|
icon: <UndoOutlined />, |
||||
|
tooltip: '撤销', |
||||
|
shortcut: 'Cmd + Z', |
||||
|
handler: (): void => undoManager.undo(), |
||||
|
}, |
||||
|
{ |
||||
|
name: 'redo', |
||||
|
icon: <RedoOutlined />, |
||||
|
tooltip: '重做', |
||||
|
shortcut: 'Cmd + Shift + Z', |
||||
|
handler: (): void => undoManager.redo(), |
||||
|
}, |
||||
|
], |
||||
|
[ |
||||
|
{ |
||||
|
name: 'zoomIn', |
||||
|
icon: <ZoomInOutlined />, |
||||
|
tooltip: '放大', |
||||
|
handler: Tool.zoomIn(graph), |
||||
|
}, |
||||
|
{ |
||||
|
name: 'zoomOut', |
||||
|
icon: <ZoomOutOutlined />, |
||||
|
tooltip: '缩小', |
||||
|
handler: Tool.zoomOut(graph), |
||||
|
}, |
||||
|
], |
||||
|
[ |
||||
|
{ |
||||
|
name: 'resetView', |
||||
|
icon: <RetweetOutlined />, |
||||
|
tooltip: '重置视口', |
||||
|
handler: (): void => { |
||||
|
graph.zoomTo(1); |
||||
|
graph.center(); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'fitWindow', |
||||
|
icon: <FullscreenOutlined />, |
||||
|
tooltip: '适应窗口', |
||||
|
handler: (): void => { |
||||
|
graph.fit(8); |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
[ |
||||
|
{ |
||||
|
name: 'delete', |
||||
|
icon: <DeleteOutlined />, |
||||
|
tooltip: '删除', |
||||
|
shortcut: 'Delete', |
||||
|
handler: (): void => graph.deleteCells(), |
||||
|
}, |
||||
|
], |
||||
|
[ |
||||
|
{ |
||||
|
name: 'save', |
||||
|
icon: <SaveOutlined />, |
||||
|
tooltip: '保存', |
||||
|
shortcut: 'Cmd + S', |
||||
|
handler: (): void => { |
||||
|
// code
|
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
]; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
interface Command { |
||||
|
name: string; |
||||
|
icon: JSX.Element; |
||||
|
tooltip: string; |
||||
|
shortcut?: string; |
||||
|
handler: () => void; |
||||
|
} |
||||
|
|
||||
|
export type Commands = Command[][]; |
@ -0,0 +1 @@ |
|||||
|
export * from './commands'; |
@ -0,0 +1,68 @@ |
|||||
|
import { Graph } from '@antv/x6'; |
||||
|
import { Commands } from '../model'; |
||||
|
|
||||
|
export function zoomIn(graph: Graph) { |
||||
|
return (): void => { |
||||
|
let { scale } = graph.view; |
||||
|
if (scale >= 8) { |
||||
|
scale += 8; |
||||
|
} else if (scale >= 4) { |
||||
|
scale += 4; |
||||
|
} else if (scale >= 2) { |
||||
|
scale += 1; |
||||
|
} else if (scale >= 1.5) { |
||||
|
scale += 0.5; |
||||
|
} else if (scale >= 1) { |
||||
|
scale += 0.25; |
||||
|
} else if (scale >= 0.7) { |
||||
|
scale += 0.15; |
||||
|
} else if (scale >= 0.4) { |
||||
|
scale += 0.1; |
||||
|
} else if (scale >= 0.15) { |
||||
|
scale += 0.05; |
||||
|
} else if (scale >= 0.01) { |
||||
|
scale += 0.01; |
||||
|
} |
||||
|
graph.zoomTo(scale); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export function zoomOut(graph: Graph) { |
||||
|
return (): void => { |
||||
|
let { scale } = graph.view; |
||||
|
if (scale <= 0.15) { |
||||
|
scale -= 0.01; |
||||
|
} else if (scale <= 0.4) { |
||||
|
scale -= 0.05; |
||||
|
} else if (scale <= 0.7) { |
||||
|
scale -= 0.1; |
||||
|
} else if (scale <= 1) { |
||||
|
scale -= 0.15; |
||||
|
} else if (scale <= 1.5) { |
||||
|
scale -= 0.25; |
||||
|
} else if (scale <= 2) { |
||||
|
scale -= 0.5; |
||||
|
} else if (scale <= 4) { |
||||
|
scale -= 1; |
||||
|
} else if (scale <= 8) { |
||||
|
scale -= 4; |
||||
|
} else if (scale <= 16) { |
||||
|
scale -= 8; |
||||
|
} |
||||
|
graph.zoomTo(scale); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export function bindKey(commands: Commands, graph: Graph): void { |
||||
|
commands.forEach((items) => |
||||
|
items.forEach((item) => { |
||||
|
if (item.shortcut) { |
||||
|
if (item.shortcut === 'Delete') { |
||||
|
graph.bindKey(['del', 'backspace'], item.handler); |
||||
|
} else { |
||||
|
graph.bindKey(item.shortcut, item.handler); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
); |
||||
|
} |
Loading…
Reference in new issue