From 45e322bdd6a7a5d1a5f6d9be4df46e2055e57953 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期三, 13 三月 2024 16:38:41 +0800
Subject: [PATCH] #

---
 zy-asrs-flow/src/pages/map/index.jsx |  400 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 324 insertions(+), 76 deletions(-)

diff --git a/zy-asrs-flow/src/pages/map/index.jsx b/zy-asrs-flow/src/pages/map/index.jsx
index bbda2ef..8e2a225 100644
--- a/zy-asrs-flow/src/pages/map/index.jsx
+++ b/zy-asrs-flow/src/pages/map/index.jsx
@@ -1,93 +1,341 @@
 import * as React from 'react'
 import * as PIXI from 'pixi.js';
-import './index.css'
-import {
-    PageContainer,
-} from '@ant-design/pro-components';
 import { FormattedMessage, useIntl, useModel } from '@umijs/max';
-import { Layout, Flex } from 'antd';
-const { Header, Footer, Sider, Content } = Layout;
+import { Layout, Button, Flex, Row, Col, FloatButton, Select, Spin } 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 Settings from './components/settings'
+import * as Utils from './utils'
+import Player from './player';
+import MapDrawer from './drawer';
 
+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)'
+        },
+        select: {
+            color: 'red',
+            fontWeight: 'bold',
+        }
+    };
+});
+
+export const MapModel = Object.freeze({
+    OBSERVER_MODEL: "1",
+    MOVABLE_MODEL: "2",
+    SETTINGS_MODEL: "3",
+})
+
+let player;
 
 const Map = () => {
-    // const { initialState, setInitialState } = useModel('@@initialState');
-    // console.log(initialState);
-    // const mapRef = React.useRef();
-    // const [app, setApp] = React.useState(() => {
-    //     return new PIXI.Application({
-    //         background: '#f5f6fa',
-    //         antialias: true,
-    //     })
-    // })
-
-    // React.useEffect(() => {
-
-    //     // resize
-    //     const onResize = () => {
-    //         if (mapRef) {
-    //             const width = mapRef.current.offsetWidth;
-    //             const height = window.innerHeight - 92;
-    //             app.renderer.resize(width, height);
-    //         }
-    //     }
-    //     window.addEventListener('resize', onResize);
-    //     onResize();
-
-    //     // app init
-    //     app.stage.interactive = true;
-    //     app.stage.hitArea = app.screen;
-    //     globalThis.__PIXI_APP__ = app;
-    //     mapRef.current.appendChild(app.view);
-
-    // }, []);
-
+    const intl = useIntl();
+    const { initialState, setInitialState } = useModel('@@initialState');
+    const { styles } = useStyles();
+    const mapRef = React.useRef();
     const contentRef = React.useRef();
 
+    const [model, setModel] = React.useState(() => MapModel.OBSERVER_MODEL);
+    const [deviceVisible, setDeviceVisible] = React.useState(false);
+    const [settingsVisible, setSettingsVisible] = 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 [didClickSprite, setDidClickSprite] = React.useState(false);
+    const [spriteBySettings, setSpriteBySettings] = React.useState(null);
+    const prevSpriteBySettingsRef = React.useRef();
+
+    // init func
     React.useEffect(() => {
-        console.log(contentRef.current);
-        console.log(contentRef.current.offsetHeight);
-    }, [])
+        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);
+        if (model !== MapModel.OBSERVER_MODEL) {
+            player.hideGridlines();
+            player.showGridlines();
+        }
+    }, [app, mapContainer, windowSize])
+
+    // model
+    React.useEffect(() => {
+        if (!mapContainer) {
+            return;
+        }
+        switch (model) {
+            case MapModel.OBSERVER_MODEL:
+
+                player.hideGridlines();
+                player.hideStarryBackground();
+
+                player.activateMapEvent(null);
+
+                Utils.removeSelectedEffect();
+                setDeviceVisible(false);
+                setSettingsVisible(false);
+
+                mapContainer.children.forEach(child => {
+                    child.off('pointerup');
+                    child.off('pointermove');
+                    child.off('pointerdown');
+                    child.off('click');
+                })
+                break
+            case MapModel.MOVABLE_MODEL:
+
+                player.showGridlines();
+                player.hideStarryBackground();
+
+                player.activateMapEvent(Utils.MapEvent.SELECTION_BOX);
+
+                Utils.removeSelectedEffect();
+                setSpriteBySettings(null);
+                setSettingsVisible(false);
+
+                mapContainer.children.forEach(child => {
+                    Utils.beMovable(child, setDidClickSprite);
+                })
+                break
+            case MapModel.SETTINGS_MODEL:
+
+                player.showGridlines();
+                player.showStarryBackground();
+
+                player.activateMapEvent(null);
+
+                setDeviceVisible(false);
+
+                mapContainer.children.forEach(child => {
+                    Utils.beSettings(child, setSpriteBySettings, setDidClickSprite);
+                })
+                break
+            default:
+                break
+        }
+    }, [model]);
+
+    // Add New Device
+    const onDrop = (sprite, type, x, y) => {
+        const { mapX, mapY } = Utils.getRealPosition(x, y, mapContainer);
+        sprite.x = mapX;
+        sprite.y = mapY;
+
+        Utils.initSprite(sprite, type);
+        mapContainer.addChild(sprite);
+        Utils.beMovable(sprite, setDidClickSprite);
+    };
+
+    // didClickSprite, stop triggers both sprite click and play's selection boxs
+    React.useEffect(() => {
+        player.updateDidClickSprite(didClickSprite);
+    }, [didClickSprite])
+
+    // watch spriteBySettings
+    React.useEffect(() => {
+        if (!mapContainer) {
+            return;
+        }
+        prevSpriteBySettingsRef.current = spriteBySettings;
+        if (spriteBySettings && prevSpriteBySettings !== spriteBySettings) {
+            Utils.removeSelectedEffect();
+        }
+        if (spriteBySettings) {
+            Utils.showSelectedEffect(spriteBySettings)
+            setSettingsVisible(true);
+        } else {
+            Utils.removeSelectedEffect();
+        }
+    }, [spriteBySettings])
+    const prevSpriteBySettings = prevSpriteBySettingsRef.current;
+
+    const settingsFinish = (values, fn) => {
+        fn();
+        // setSettingsVisible(false);
+        // setSpriteBySettings(null);
+    }
 
     return (
         <>
-            {/* <PageContainer
-                header={{
-                    title: false,
-                    subTitle: false,
-                    breadcrumb: {},
-                }}
-                style={{ height: '100%', padding: 0, backgroundColor:'blue' }} // Here
+            <Layout className={styles.layout}>
+                <Header className={styles.header}>
+                    <Row style={{ height: '100%' }}>
+                        <Col span={8} style={{ backgroundColor: '#dcdde1' }}>
 
-            >
-                <div
-                    style={{ width: '100%', height: '100%' }}
-                    ref={mapRef}
-                >
-                </div>
-            </PageContainer> */}
-            <Layout style={{
-                overflow: 'hidden',
-                height: 'calc(100vh - 360px)',
-                maxHeight: 'calc(100vh - 360px)'
-            }}>
-                <Header style={{
-                    textAlign: 'center',
-                    color: '#fff',
-                    height: 58,
-                    paddingInline: 48,
-                    lineHeight: '64px',
-                    backgroundColor: '#4096ff',
-                }}>Header</Header>
-                <Content ref={contentRef} style={{
-                    textAlign: 'center',
-                    minHeight: 120,
-                    lineHeight: '120px',
-                    color: '#fff',
-                    backgroundColor: '#0958d9',
-                    height: 'calc(100vh - 360px - 64px)', // <----- 杩欓噷璁剧疆Content鐨勯珮搴�
-       
-                }}>Content</Content>
+
+                            <Select
+                                defaultValue="agv"
+                                style={{
+                                    width: 120,
+                                }}
+                                size={'large'}
+                                onChange={(value, option) => {
+                                    console.log(value, option);
+                                }}
+                                options={[
+                                    {
+                                        value: 'agv',
+                                        label: 'agv',
+                                    },
+                                    {
+                                        value: 'crn',
+                                        label: 'crn',
+                                    },
+                                ]}
+                            />
+
+                            <Select
+
+                            // notFoundContent={loading ? <Spin size="small" /> : null}
+
+                            />
+
+
+                        </Col>
+                        <Col span={16} style={{ backgroundColor: '#3C40C6' }}>
+                            <Flex className={styles.flex} gap={'large'} justify={'flex-end'} align={'center'}>
+                                <Select
+                                    className={styles.select}
+                                    size={'large'}
+                                    defaultValue={MapModel.OBSERVER_MODEL}
+                                    style={{
+                                        width: 180,
+                                    }}
+                                    onChange={setModel}
+                                    options={[
+                                        {
+                                            value: MapModel.OBSERVER_MODEL,
+                                            label: intl.formatMessage({ id: 'map.model.observer', defaultMessage: '瑙傚療鑰呮ā寮�' }),
+                                        },
+                                        {
+                                            value: MapModel.MOVABLE_MODEL,
+                                            label: intl.formatMessage({ id: 'map.model.editor', defaultMessage: '缂栬緫鑰呮ā寮�' }),
+                                        },
+                                    ]}
+                                />
+                            </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={model === MapModel.OBSERVER_MODEL}
+                            style={{
+                                left: 35,
+                                bottom: window.innerHeight / 2
+                            }}
+                            icon={<AppstoreAddOutlined />}
+                        >
+                            <FloatButton
+                                hidden={model === MapModel.OBSERVER_MODEL}
+                                type={deviceVisible ? 'primary' : 'default'}
+                                tooltip={<div><FormattedMessage id='map.device.add' defaultMessage='娣诲姞璁惧' /></div>}
+                                icon={<FileAddOutlined />}
+                                onClick={() => {
+                                    if (deviceVisible) {
+                                        setDeviceVisible(false);
+                                    } else {
+                                        setDeviceVisible(true);
+                                        setModel(MapModel.MOVABLE_MODEL);
+                                    }
+                                }}
+                            />
+                            <FloatButton
+                                hidden={model === MapModel.OBSERVER_MODEL}
+                                type={model === MapModel.SETTINGS_MODEL ? 'primary' : 'default'}
+                                tooltip={<div><FormattedMessage id='map.device.oper' defaultMessage='鍙傛暟璁剧疆' /></div>}
+                                icon={<SettingOutlined />}
+                                onClick={() => {
+                                    setModel(model === MapModel.SETTINGS_MODEL ? MapModel.MOVABLE_MODEL : MapModel.SETTINGS_MODEL)
+                                }}
+                            />
+                        </FloatButton.Group>
+                    </div>
+                </Content>
             </Layout>
+
+            <Edit
+                open={deviceVisible}
+                onCancel={() => {
+                    setDeviceVisible(false);
+                }}
+                refCurr={mapRef.current}
+                onDrop={onDrop}
+            />
+
+            <Settings
+                open={settingsVisible}
+                curSprite={spriteBySettings}
+                onCancel={() => {
+                    setSettingsVisible(false);
+                    setSpriteBySettings(null);
+                }}
+                setSpriteBySettings={setSpriteBySettings}
+                setDidClickSprite={setDidClickSprite}
+                refCurr={mapRef.current}
+                onSubmit={settingsFinish}
+            />
         </>
     )
 }

--
Gitblit v1.9.1