| | |
| | | import * as React from 'react' |
| | | import * as PIXI from 'pixi.js'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { Layout, Button, Flex, } from 'antd'; |
| | | import { Layout, Button, Flex, Row, Col, FloatButton } from 'antd'; |
| | | const { Header, Content } = Layout; |
| | | import { |
| | | AppstoreAddOutlined, |
| | | FileAddOutlined, |
| | | CompressOutlined, |
| | | } from '@ant-design/icons'; |
| | | import './index.css' |
| | | import { createStyles } from 'antd-style'; |
| | | import Edit from './components/edit' |
| | | import Edit from './components/device' |
| | | import * as Utils from './utils' |
| | | import Player from './player'; |
| | | |
| | | const useStyles = createStyles(({ token }) => { |
| | | let dark = token.colorBgBase === '#000'; |
| | | return { |
| | | dark: dark, |
| | | layout: { |
| | | overflow: 'hidden', |
| | | }, |
| | |
| | | content: { |
| | | backgroundColor: '#F8FAFB', |
| | | height: 'calc(100vh - 120px)' |
| | | } |
| | | }, |
| | | }; |
| | | }); |
| | | |
| | | let player; |
| | | |
| | | const Map = () => { |
| | | const { initialState, setInitialState } = useModel('@@initialState'); |
| | |
| | | const mapRef = React.useRef(); |
| | | const contentRef = React.useRef(); |
| | | |
| | | const [editModalVisible, setEditModalVisible] = React.useState(false); |
| | | const [deviceVisible, setDeviceVisible] = React.useState(false); |
| | | const [windowSize, setWindowSize] = React.useState({ |
| | | width: window.innerWidth, |
| | | height: window.innerHeight, |
| | | }); |
| | | const [app, setApp] = React.useState(null) |
| | | const [mapContainer, setMapContainer] = React.useState(null) |
| | | const [app, setApp] = React.useState(null); |
| | | const [mapContainer, setMapContainer] = React.useState(null); |
| | | const [mapEditModel, setMapEditModel] = React.useState(false); |
| | | |
| | | React.useEffect(() => { |
| | | const player = new Player(mapRef.current); |
| | | player = new Player(mapRef.current, styles.dark); |
| | | setApp(player.app); |
| | | setMapContainer(player.mapContainer); |
| | | Utils.syncApp(player.app); |
| | |
| | | app.renderer.resize(width, height); |
| | | }, [app, mapContainer, windowSize]) |
| | | |
| | | const editHandle = () => { |
| | | setEditModalVisible(true); |
| | | } |
| | | React.useEffect(() => { |
| | | if (!mapContainer) { |
| | | return; |
| | | } |
| | | if (mapEditModel) { |
| | | player.showGridlines(); |
| | | } else { |
| | | player.hideGridlines(); |
| | | } |
| | | }, [mapEditModel]); |
| | | |
| | | const onDrop = (sprite, x, y) => { |
| | | const { mapX, mapY } = Utils.getRealPosition(x, y, mapContainer); |
| | |
| | | <> |
| | | <Layout className={styles.layout}> |
| | | <Header className={styles.header}> |
| | | <Flex className={styles.flex} gap={'large'} justify={'flex-end'} align={'center'}> |
| | | <Button onClick={editHandle} size={'large'}><FormattedMessage id='map.edit' defaultMessage='编辑地图' /></Button> |
| | | </Flex> |
| | | <Row style={{ height: '100%' }}> |
| | | <Col span={8} style={{ backgroundColor: '#3C40C6' }}></Col> |
| | | <Col span={16} style={{ backgroundColor: '#3C40C6' }}> |
| | | <Flex className={styles.flex} gap={'large'} justify={'flex-end'} align={'center'}> |
| | | <Button onClick={() => setMapEditModel(!mapEditModel)} size={'large'}> |
| | | {!mapEditModel |
| | | ? <span style={{ fontWeight: 'bold' }}><FormattedMessage id='map.edit' defaultMessage='编辑地图' /></span> |
| | | : <span style={{ color: 'red', fontWeight: 'bold' }}><FormattedMessage id='map.edit.close' defaultMessage='退出编辑' /></span> |
| | | } |
| | | </Button> |
| | | </Flex> |
| | | </Col> |
| | | </Row> |
| | | </Header> |
| | | <Content ref={contentRef} className={styles.content}> |
| | | <div ref={mapRef} style={{ position: "relative" }} /> |
| | | |
| | | <FloatButton.Group |
| | | shape="square" |
| | | style={{ |
| | | left: 35, |
| | | bottom: 35 |
| | | }} |
| | | > |
| | | <FloatButton |
| | | icon={<CompressOutlined />} |
| | | /> |
| | | <FloatButton.BackTop visibilityHeight={0} /> |
| | | </FloatButton.Group> |
| | | |
| | | <FloatButton.Group |
| | | hidden={!mapEditModel} |
| | | trigger="hover" |
| | | style={{ |
| | | right: 35, |
| | | bottom: 35 |
| | | }} |
| | | icon={<AppstoreAddOutlined />} |
| | | > |
| | | <FloatButton |
| | | tooltip={<div><FormattedMessage id='map.device.add' defaultMessage='添加设备' /></div>} |
| | | icon={<FileAddOutlined />} |
| | | onClick={() => { |
| | | setDeviceVisible(true); |
| | | }} |
| | | /> |
| | | </FloatButton.Group> |
| | | </Content> |
| | | </Layout> |
| | | |
| | | <Edit |
| | | open={editModalVisible} |
| | | open={deviceVisible} |
| | | onCancel={() => { |
| | | setEditModalVisible(false); |
| | | setDeviceVisible(false); |
| | | }} |
| | | refCurr={mapRef.current} |
| | | onDrop={onDrop} |