| import * as React from 'react' | 
| import * as PIXI from 'pixi.js'; | 
| import { FormattedMessage, useIntl, useModel } from '@umijs/max'; | 
| import { Layout, Button, Flex, Row, Col, FloatButton } from 'antd'; | 
| const { Header, Content } = Layout; | 
| import { | 
|     AppstoreAddOutlined, | 
|     FileAddOutlined, | 
|     CompressOutlined, | 
|     SettingOutlined, | 
| } from '@ant-design/icons'; | 
| import './index.css' | 
| import { createStyles } from 'antd-style'; | 
| 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', | 
|         }, | 
|         header: { | 
|             height: 64, | 
|             paddingInline: 48, | 
|             lineHeight: '64px', | 
|             padding: 0, | 
|         }, | 
|         flex: { | 
|             width: '100%', | 
|             height: '100%', | 
|             padding: '0 30px', | 
|         }, | 
|         content: { | 
|             backgroundColor: '#F8FAFB', | 
|             height: 'calc(100vh - 120px)' | 
|         }, | 
|     }; | 
| }); | 
|   | 
| let player; | 
|   | 
| const Map = () => { | 
|     const { initialState, setInitialState } = useModel('@@initialState'); | 
|     const { styles } = useStyles(); | 
|     const mapRef = React.useRef(); | 
|     const contentRef = React.useRef(); | 
|   | 
|     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 [mapEditModel, setMapEditModel] = React.useState(false); | 
|     const [deviceSettingModel, setDeviceSettingModel] = React.useState(false); | 
|     const [didClickSprite, setDidClickSprite] = React.useState(false); | 
|   | 
|     // init func | 
|     React.useEffect(() => { | 
|         player = new Player(mapRef.current, styles.dark, didClickSprite); | 
|         setApp(player.app); | 
|         setMapContainer(player.mapContainer); | 
|         Utils.syncApp(player.app); | 
|         Utils.syncMapContainer(player.mapContainer); | 
|   | 
|         const handleResize = () => { | 
|             setWindowSize({ | 
|                 width: window.innerWidth, | 
|                 height: window.innerHeight, | 
|             }); | 
|         }; | 
|         window.addEventListener('resize', handleResize); | 
|     }, []); | 
|   | 
|     // resize | 
|     React.useEffect(() => { | 
|         if (!app) { | 
|             return; | 
|         } | 
|         const width = contentRef.current.offsetWidth; | 
|         const height = contentRef.current.offsetHeight; | 
|         app.renderer.resize(width, height); | 
|     }, [app, mapContainer, windowSize]) | 
|   | 
|     // Edit Model | 
|     React.useEffect(() => { | 
|         if (!mapContainer) { | 
|             return; | 
|         } | 
|         if (mapEditModel) { | 
|             player.showGridlines(); | 
|             player.activateMapEvent(Utils.MapEvent.SELECTION_BOX); | 
|             mapContainer.children.forEach(child => { | 
|                 Utils.beMovable(child, setDidClickSprite); | 
|             }) | 
|         } else { | 
|             player.hideGridlines(); | 
|             player.activateMapEvent(null); | 
|             mapContainer.children.forEach(child => { | 
|                 child.off('pointerup'); | 
|                 child.off('pointerdown'); | 
|                 child.off('click'); | 
|             }) | 
|         } | 
|     }, [mapEditModel]); | 
|   | 
|     // Settings Model | 
|     React.useEffect(() => { | 
|         if (!mapContainer) { | 
|             return; | 
|         } | 
|         if (deviceSettingModel) { | 
|   | 
|         } else { | 
|   | 
|         } | 
|     }, [deviceSettingModel]); | 
|   | 
|     // Add New Device | 
|     const onDrop = (sprite, x, y) => { | 
|         const { mapX, mapY } = Utils.getRealPosition(x, y, mapContainer); | 
|         sprite.x = mapX; | 
|         sprite.y = mapY; | 
|   | 
|         Utils.initSprite(sprite); | 
|         mapContainer.addChild(sprite); | 
|         Utils.beMovable(sprite, setDidClickSprite); | 
|     }; | 
|   | 
|     // didClickSprite, stop triggers both sprite click and play's selection boxs | 
|     React.useEffect(() => { | 
|         player.updateDidClickSprite(didClickSprite); | 
|     }, [didClickSprite]) | 
|   | 
|     return ( | 
|         <> | 
|             <Layout className={styles.layout}> | 
|                 <Header className={styles.header}> | 
|                     <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 | 
|                             tooltip={<div><FormattedMessage id='map.device.oper' defaultMessage='参数设置' /></div>} | 
|                             icon={<SettingOutlined />} | 
|                             onClick={() => { | 
|                                 setDeviceSettingModel(true); | 
|                             }} | 
|                         /> | 
|                     </FloatButton.Group> | 
|                 </Content> | 
|             </Layout> | 
|   | 
|             <Edit | 
|                 open={deviceVisible} | 
|                 onCancel={() => { | 
|                     setDeviceVisible(false); | 
|                 }} | 
|                 refCurr={mapRef.current} | 
|                 onDrop={onDrop} | 
|             /> | 
|         </> | 
|     ) | 
| } | 
|   | 
| export default Map; |