Merge remote-tracking branch 'origin/master'
| | |
| | | export const layout = ({ initialState, setInitialState }) => { |
| | | const [darkMode, setDarkMode] = React.useState(() => { |
| | | const storedValue = localStorage.getItem('darkMode'); |
| | | return storedValue !== null ? JSON.parse(storedValue) : true; |
| | | return storedValue !== null ? JSON.parse(storedValue) : false; |
| | | }); |
| | | |
| | | const [layoutMode, setLayoutMode] = React.useState(() => { |
| | |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | 'map.settings.more': 'More', |
| | | 'map.settings.delete': 'Delete', |
| | | 'map.settings.type': 'Type', |
| | | 'map.settings.uuid': 'Uuid', |
| | | 'map.settings.component': 'Component', |
| | | 'map.settings.name': 'Name', |
| | | 'map.settings.position': 'Position', |
| | | 'map.settings.scale': 'Scale', |
| | | 'map.settings.rotation': 'Rotation', |
| | |
| | | 'map.settings.right': 'Right', |
| | | 'map.settings.top': 'Top', |
| | | 'map.settings.bottom': 'Bottom', |
| | | 'map.settings.map.param': 'Map Parameters', |
| | | 'map.settings.config.param': 'Config Parameters', |
| | | '': '', |
| | | '': '', |
| | | 'map.settings.shelf.no': 'Shelf No', |
| | | 'map.settings.shelf.row': 'Row', |
| | | 'map.settings.shelf.bay': 'Bay', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | 'map.settings.sub.copy.reverse': 'Reverse', |
| | | 'map.settings.sub.copy.rule': 'Copy Rule', |
| | | 'map.settings.sub.copy.dire': 'Direction', |
| | | 'map.settings.sub.copy.count': 'Count', |
| | | 'map.settings.sub.copy.gap': 'Gap', |
| | | 'map.settings.sub.copy.id': 'ID', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
New file |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Col, Form, Input, Row, Checkbox, Slider, Select, Drawer, Space, Button, InputNumber, Card } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import * as PIXI from 'pixi.js'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | |
| | | }) |
| | | |
| | | const ConfigSettings = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { curSprite, configForm: form } = props; |
| | | |
| | | useEffect(() => { |
| | | }, []); |
| | | |
| | | const formValuesChange = (changeList) => { |
| | | if (curSprite && changeList && changeList.length > 0) { |
| | | changeList.forEach(change => { |
| | | const { name: nameList, value } = change; |
| | | nameList.forEach(name => { |
| | | switch (name) { |
| | | case 'row': |
| | | const bay = form.getFieldValue('bay') |
| | | if (value && bay) { |
| | | form.setFieldsValue({ |
| | | shelfNo: Utils.pureNumStr(value) + '-' + Utils.pureNumStr(bay) |
| | | }); |
| | | } else { |
| | | form.setFieldsValue({ |
| | | shelfNo: '' |
| | | }); |
| | | } |
| | | break; |
| | | case 'bay': |
| | | const row = form.getFieldValue('row') |
| | | if (value && row) { |
| | | form.setFieldsValue({ |
| | | shelfNo: Utils.pureNumStr(row) + '-' + Utils.pureNumStr(value) |
| | | }); |
| | | } else { |
| | | form.setFieldsValue({ |
| | | shelfNo: '' |
| | | }); |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | Utils.removeSelectedEffect(); |
| | | Utils.showSelectedEffect(curSprite); |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const onFinishFailed = (errorInfo) => { |
| | | }; |
| | | |
| | | const handleFinish = async (values) => { |
| | | props.onSubmit({ ...values }); |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Form |
| | | form={form} |
| | | onFieldsChange={formValuesChange} |
| | | initialValues={{ |
| | | }} |
| | | onFinish={handleFinish} |
| | | onFinishFailed={onFinishFailed} |
| | | autoComplete="off" |
| | | style={{ |
| | | maxWidth: 600, |
| | | }} |
| | | size='defalargeult' |
| | | variant='filled' |
| | | labelWrap |
| | | disabled={false} |
| | | layout='horizontal' |
| | | labelCol={{ |
| | | span: 4, |
| | | }} |
| | | wrapperCol={{ |
| | | span: 20, |
| | | }} |
| | | > |
| | | <br /> |
| | | |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.type', defaultMessage: '类型' })} |
| | | > |
| | | <span>{curSprite?.data?.type}</span> |
| | | </Form.Item> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.uuid', defaultMessage: '编号' })} |
| | | > |
| | | <span>{curSprite?.data?.uuid}</span> |
| | | </Form.Item> |
| | | |
| | | {curSprite?.data?.type === Utils.SENSOR_TYPE.AGV && ( |
| | | <> |
| | | |
| | | </> |
| | | )} |
| | | |
| | | {curSprite?.data?.type === Utils.SENSOR_TYPE.SHELF && ( |
| | | <> |
| | | <Form.Item |
| | | name='row' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.row', defaultMessage: '排' })} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='bay' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.bay', defaultMessage: '列' })} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='shelfNo' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.no', defaultMessage: '货架号' })} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <Input |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </> |
| | | )} |
| | | |
| | | <Form.Item |
| | | wrapperCol={{ |
| | | offset: 4, |
| | | span: 16, |
| | | }}> |
| | | <Button type="primary" onClick={handleFinish}> |
| | | <FormattedMessage id='common.submit' defaultMessage='保存' /> |
| | | </Button> |
| | | </Form.Item> |
| | | </Form > |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default ConfigSettings; |
| | |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import * as PIXI from 'pixi.js'; |
| | | import { createStyles } from 'antd-style'; |
| | | import './index.css' |
| | | import * as Utils from '../utils' |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | let dark = token.colorBgBase === '#000'; |
| | |
| | | transition: all 0.3s ease !important; |
| | | } |
| | | `, |
| | | color: dark ? '#303030' : '#f0f0f0' |
| | | color: dark ? '#303030' : '#f0f0f0', |
| | | title: { |
| | | color: dark ? '#f0f0f0' : '#303030' |
| | | } |
| | | }; |
| | | }); |
| | | |
| | | import agv from '/public/img/map/agv.svg' |
| | | import { set } from 'lodash'; |
| | | import shelf from '/public/img/map/shelf.png' |
| | | import { Util } from '@antv/g6'; |
| | | |
| | | const Device = (props) => { |
| | | const { styles } = useStyles(); |
| | |
| | | const onDragStart = (e, type) => { |
| | | setDragging(true); |
| | | setDragSpriteType(type); |
| | | const sprite = PIXI.Sprite.from(agv); |
| | | const sprite = PIXI.Sprite.from(e.target); |
| | | setDragSprite(sprite); |
| | | }; |
| | | |
| | |
| | | </Space> |
| | | } |
| | | > |
| | | <Card className={styles.mapCard}> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | </Card> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, Utils.SENSOR_TYPE.AGV)} |
| | | /> |
| | | <div className={styles.title}>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={shelf} |
| | | width='35px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, Utils.SENSOR_TYPE.SHELF)} |
| | | /> |
| | | <div className={styles.title}>SHELF</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | <Row className={styles.mapRow}> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | <Col className={styles.mapCol} span={8} > |
| | | <Image |
| | | src={agv} |
| | | width='50px' |
| | | preview={false} |
| | | draggable="true" |
| | | onDragStart={(e) => onDragStart(e, 'AGV')} |
| | | /> |
| | | <div>AGV</div> |
| | | </Col> |
| | | </Row> |
| | | </Drawer> |
| | | </> |
| | | ) |
New file |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Col, Form, Input, Row, Checkbox, Slider, Select, Drawer, Space, Button, InputNumber, Switch } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import * as PIXI from 'pixi.js'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | |
| | | }) |
| | | |
| | | const MapCopySettings = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { curSprite } = props; |
| | | const [form] = Form.useForm(); |
| | | |
| | | useEffect(() => { |
| | | form.resetFields(); |
| | | if (curSprite && props) { |
| | | form.setFieldsValue({ |
| | | ...props.values, |
| | | copyGap: 0 |
| | | }); |
| | | } |
| | | }, [form, props]); |
| | | |
| | | const handleCancel = () => { |
| | | props.onClose(); |
| | | } |
| | | |
| | | const handleOk = () => { |
| | | form.submit(); |
| | | } |
| | | |
| | | const handleFinish = (values) => { |
| | | props.submit({ ...values, ...props.values }) |
| | | } |
| | | |
| | | const formValuesChange = () => { |
| | | |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Drawer |
| | | title={intl.formatMessage({ id: 'map.settings.sub.copy.rule', defaultMessage: '复制规则' })} |
| | | width={350} |
| | | closable={false} |
| | | open={props.open} |
| | | getContainer={props.refCurr} |
| | | rootStyle={{ position: "absolute" }} |
| | | onClose={handleCancel} |
| | | extra={ |
| | | <Space> |
| | | <Button onClick={handleCancel}> |
| | | <FormattedMessage id='common.cancel' defaultMessage='取消' /> |
| | | </Button> |
| | | <Button onClick={handleOk} type="primary"> |
| | | <FormattedMessage id='common.submit' defaultMessage='确定' /> |
| | | </Button> |
| | | </Space> |
| | | } |
| | | > |
| | | <Form |
| | | form={form} |
| | | onFieldsChange={formValuesChange} |
| | | initialValues={{ |
| | | }} |
| | | onFinish={handleFinish} |
| | | autoComplete="off" |
| | | style={{ |
| | | maxWidth: 300, |
| | | }} |
| | | size='default' |
| | | variant='filled' |
| | | labelWrap |
| | | disabled={false} |
| | | layout='horizontal' |
| | | > |
| | | <Row gutter={[16, 0]}> |
| | | |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.sub.copy.dire', defaultMessage: '方向' })} |
| | | labelCol={{ span: 8 }} |
| | | > |
| | | <span>{props?.values?.copyDire}</span> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.sub.copy.count', defaultMessage: '数量' })} |
| | | labelCol={{ span: 8 }} |
| | | > |
| | | <span>{props?.values?.copyCount}</span> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | <Col span={24}> |
| | | <Form.Item |
| | | name='copyGap' |
| | | label={intl.formatMessage({ id: 'map.settings.sub.copy.gap', defaultMessage: '间距' })} |
| | | labelCol={{ span: 8 }} |
| | | > |
| | | <InputNumber |
| | | style={{ |
| | | width: '60%', |
| | | }} |
| | | // min={0} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | {curSprite?.data?.type === 'AGV' && ( |
| | | <Col span={24}> |
| | | <Form.Item |
| | | name='id' |
| | | label={intl.formatMessage({ id: 'map.settings.sub.copy.id', defaultMessage: '序号' })} |
| | | labelCol={{ span: 8 }} |
| | | > |
| | | <InputNumber |
| | | style={{ |
| | | width: '60%', |
| | | }} |
| | | min={0} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | )} |
| | | |
| | | </Row> |
| | | </Form> |
| | | </Drawer> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default MapCopySettings; |
New file |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Col, Form, Input, Row, Checkbox, Slider, Select, Drawer, Space, Button, InputNumber, Card } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import * as PIXI from 'pixi.js'; |
| | | import MapCopySettings from './mapCopySettings'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | |
| | | }) |
| | | |
| | | const MapSettings = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { curSprite, mapForm: form } = props; |
| | | |
| | | const [childrenDrawer, setChildrenDrawer] = useState(false); |
| | | const [lastCopiedSprites, setLastCopiedSprites] = useState([]); |
| | | |
| | | useEffect(() => { |
| | | |
| | | }, []); |
| | | |
| | | useEffect(() => { |
| | | form.resetFields(); |
| | | if (curSprite) { |
| | | form.setFieldsValue({ |
| | | x: curSprite.position.x, |
| | | y: curSprite.position.y, |
| | | scale: Math.max(curSprite.scale.x, curSprite.scale.y), |
| | | scaleSlider: Math.max(curSprite.scale.x, curSprite.scale.y), |
| | | rotation: curSprite.rotation * 180 / Math.PI, |
| | | rotationSlider: curSprite.rotation * 180 / Math.PI, |
| | | |
| | | copyDire: 'right', |
| | | copyCount: 1, |
| | | }) |
| | | } |
| | | }, [form, props]) |
| | | |
| | | const handleFinish = async (values) => { |
| | | props.onSubmit({ ...values }); |
| | | } |
| | | |
| | | const formValuesChange = (changeList) => { |
| | | if (curSprite && changeList && changeList.length > 0) { |
| | | changeList.forEach(change => { |
| | | const { name: nameList, value } = change; |
| | | nameList.forEach(name => { |
| | | switch (name) { |
| | | case 'x': |
| | | curSprite.position.x = value; |
| | | break; |
| | | case 'y': |
| | | curSprite.position.y = value; |
| | | break; |
| | | case 'scaleSlider': |
| | | form.setFieldsValue({ |
| | | scale: value |
| | | }) |
| | | curSprite.scale.set(value); |
| | | break; |
| | | case 'scale': |
| | | form.setFieldsValue({ |
| | | scaleSlider: value |
| | | }) |
| | | curSprite.scale.set(value); |
| | | break; |
| | | case 'rotationSlider': |
| | | form.setFieldsValue({ |
| | | rotation: value |
| | | }) |
| | | curSprite.rotation = value * Math.PI / 180; |
| | | break; |
| | | case 'rotation': |
| | | form.setFieldsValue({ |
| | | rotationSlider: value |
| | | }) |
| | | curSprite.rotation = value * Math.PI / 180; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | Utils.removeSelectedEffect(); |
| | | Utils.showSelectedEffect(curSprite); |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const onFinishFailed = (errorInfo) => { |
| | | }; |
| | | |
| | | const handleOnCopy = (values) => { |
| | | if (!curSprite) { |
| | | return; |
| | | } |
| | | setLastCopiedSprites([]); |
| | | for (let i = 0; i < values.copyCount; i++) { |
| | | const copiedSprite = Utils.copySprite(curSprite); |
| | | switch (values.copyDire) { |
| | | case 'left': |
| | | copiedSprite.position.x -= (i + 1) * (values.copyGap + copiedSprite.width); |
| | | break; |
| | | case 'right': |
| | | copiedSprite.position.x += (i + 1) * (values.copyGap + copiedSprite.width); |
| | | break; |
| | | case 'top': |
| | | copiedSprite.position.y -= (i + 1) * (values.copyGap + copiedSprite.height); |
| | | break; |
| | | case 'bottom': |
| | | copiedSprite.position.y += (i + 1) * (values.copyGap + copiedSprite.height); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | Utils.getMapContainer().addChild(copiedSprite); |
| | | Utils.beSettings(copiedSprite, props.setSpriteBySettings, props.setDidClickSprite); |
| | | |
| | | setLastCopiedSprites(prevArr => [...prevArr, copiedSprite]); |
| | | } |
| | | setChildrenDrawer(false); |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Form |
| | | form={form} |
| | | onFieldsChange={formValuesChange} |
| | | onFinish={handleFinish} |
| | | onFinishFailed={onFinishFailed} |
| | | autoComplete="off" |
| | | style={{ |
| | | maxWidth: 600, |
| | | }} |
| | | size='default' // small | default | large |
| | | variant='filled' // outlined | borderless | filled |
| | | labelWrap // label 换行 |
| | | disabled={false} |
| | | layout='horizontal' |
| | | labelCol={{ |
| | | span: 4, |
| | | }} |
| | | wrapperCol={{ |
| | | span: 20, |
| | | }} |
| | | initialValues={{ |
| | | scale: 1, |
| | | rotation: 1 |
| | | }} |
| | | > |
| | | <Row gutter={[24, 16]}> |
| | | <Col span={24} /> |
| | | |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.component', defaultMessage: '组件' })} |
| | | > |
| | | <span>{curSprite?.data?.type}-{curSprite?.data?.uuid}</span> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | {/* position */} |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.position', defaultMessage: '坐标' })} |
| | | > |
| | | <Space.Compact> |
| | | <Form.Item |
| | | name='x' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact>x</Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='y' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact>y</Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Space.Compact> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | {/* scale */} |
| | | <Col span={18}> |
| | | <Form.Item |
| | | name="scaleSlider" |
| | | label={intl.formatMessage({ id: 'map.settings.scale', defaultMessage: '缩放' })} |
| | | labelCol={{ span: 5 }} |
| | | > |
| | | <Slider |
| | | min={0.1} |
| | | max={10} |
| | | step={0.1} |
| | | marks={{ |
| | | 0.1: '0.1', |
| | | 1: '1', |
| | | 10: '10', |
| | | }} |
| | | style={{ |
| | | width: '100%' |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6}> |
| | | <Form.Item |
| | | name="scale" |
| | | > |
| | | <InputNumber |
| | | min={0.1} max={10} step={0.1} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | {/* rotation */} |
| | | <Col span={18}> |
| | | <Form.Item |
| | | name="rotationSlider" |
| | | label={intl.formatMessage({ id: 'map.settings.rotation', defaultMessage: '角度' })} |
| | | labelCol={{ span: 5 }} |
| | | > |
| | | <Slider |
| | | min={0} |
| | | max={360} |
| | | step={1} |
| | | marks={{ |
| | | 0: '0°', |
| | | 90: '90°', |
| | | 180: '180°', |
| | | 270: '270°', |
| | | 360: '360°', |
| | | }} |
| | | style={{ |
| | | width: '100%' |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6}> |
| | | <Form.Item |
| | | name="rotation" |
| | | > |
| | | <InputNumber |
| | | min={0} max={360} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | {/* copy */} |
| | | <Col span={24}> |
| | | <Row gutter={0}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.copy', defaultMessage: '复制' })} |
| | | > |
| | | <Space.Compact> |
| | | <Form.Item |
| | | noStyle |
| | | name="copyDire" |
| | | > |
| | | <Select |
| | | style={{ width: 100 }} |
| | | options={[ |
| | | { value: 'left', label: intl.formatMessage({ id: 'map.settings.left', defaultMessage: '左' }) }, |
| | | { value: 'right', label: intl.formatMessage({ id: 'map.settings.right', defaultMessage: '右' }) }, |
| | | { value: 'top', label: intl.formatMessage({ id: 'map.settings.top', defaultMessage: '上' }) }, |
| | | { value: 'bottom', label: intl.formatMessage({ id: 'map.settings.bottom', defaultMessage: '下' }) }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='copyCount' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | min={1} |
| | | step={1} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item> |
| | | <Button |
| | | onClick={() => { |
| | | setChildrenDrawer(true); |
| | | }} |
| | | > |
| | | <FormattedMessage id='common.execute' defaultMessage='执行' /> |
| | | </Button> |
| | | <MapCopySettings |
| | | open={childrenDrawer} |
| | | refCurr={props.refCurr} |
| | | curSprite={props.curSprite} |
| | | values={form.getFieldsValue()} |
| | | submit={handleOnCopy} |
| | | onClose={() => { |
| | | setChildrenDrawer(false) |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item> |
| | | <Button |
| | | type="dashed" |
| | | onClick={() => { |
| | | if (lastCopiedSprites) { |
| | | lastCopiedSprites.forEach(copiedSprite => { |
| | | Utils.getMapContainer().removeChild(copiedSprite); |
| | | }) |
| | | setLastCopiedSprites([]); |
| | | } |
| | | }} |
| | | > |
| | | <FormattedMessage id='map.settings.sub.copy.reverse' defaultMessage='撤销' /> |
| | | </Button> |
| | | </Form.Item> |
| | | </Space.Compact> |
| | | </Form.Item> |
| | | </Row> |
| | | </Col> |
| | | |
| | | {/* more */} |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.more', defaultMessage: '更多' })} |
| | | > |
| | | <Button |
| | | type="dashed" |
| | | danger |
| | | onClick={() => { |
| | | Utils.getMapContainer().removeChild(curSprite); |
| | | props.setSpriteBySettings(null); |
| | | Utils.removeSelectedEffect(); |
| | | form.resetFields(); |
| | | }} |
| | | > |
| | | <FormattedMessage id='map.settings.delete' defaultMessage='删除' /> |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | |
| | | </Row> |
| | | </Form> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default MapSettings; |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Col, Form, Input, Row, Checkbox, Slider, Select, Drawer, Space, Button, InputNumber, Switch } from 'antd'; |
| | | import { Col, Form, Input, Row, Checkbox, Slider, Select, Drawer, Space, Button, InputNumber, Card } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { |
| | | BranchesOutlined, |
| | | BorderOuterOutlined, |
| | | } from '@ant-design/icons'; |
| | | import { createStyles } from 'antd-style'; |
| | | import './index.css'; |
| | | import * as Utils from '../utils' |
| | | import * as PIXI from 'pixi.js'; |
| | | import moment from 'moment'; |
| | | import Http from '@/utils/http'; |
| | | import MapSettings from './mapSettings'; |
| | | import ConfigSettings from './configSettings'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | |
| | | }) |
| | | |
| | | const SpriteSettings = (props) => { |
| | | const Settings = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { curSprite } = props; |
| | | const [form] = Form.useForm(); |
| | | const [activeTabKey, setActiveTabKey] = useState('map'); |
| | | |
| | | useEffect(() => { |
| | | const [mapForm] = Form.useForm(); |
| | | const [configForm] = Form.useForm(); |
| | | |
| | | }, []); |
| | | |
| | | useEffect(() => { |
| | | form.resetFields(); |
| | | if (curSprite) { |
| | | form.setFieldsValue({ |
| | | x: curSprite.position.x, |
| | | y: curSprite.position.y, |
| | | scale: Math.max(curSprite.scale.x, curSprite.scale.y), |
| | | scaleSlider: Math.max(curSprite.scale.x, curSprite.scale.y), |
| | | rotation: curSprite.rotation * 180 / Math.PI, |
| | | rotationSlider: curSprite.rotation * 180 / Math.PI, |
| | | }) |
| | | } |
| | | }, [form, props]) |
| | | const contentList = { |
| | | map: ( |
| | | <MapSettings |
| | | refCurr={props.refCurr} |
| | | curSprite={props.curSprite} |
| | | setSpriteBySettings={props.setSpriteBySettings} |
| | | setDidClickSprite={props.setDidClickSprite} |
| | | onSubmit={props.onSubmit} |
| | | mapForm={mapForm} |
| | | /> |
| | | ), |
| | | config: ( |
| | | <ConfigSettings |
| | | refCurr={props.refCurr} |
| | | curSprite={props.curSprite} |
| | | setSpriteBySettings={props.setSpriteBySettings} |
| | | setDidClickSprite={props.setDidClickSprite} |
| | | onSubmit={props.onSubmit} |
| | | configForm={configForm} |
| | | /> |
| | | ), |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | props.onCancel(); |
| | | }; |
| | | |
| | | const handleOk = () => { |
| | | form.submit(); |
| | | } |
| | | |
| | | const handleFinish = async (values) => { |
| | | props.onSubmit({ ...values }); |
| | | } |
| | | |
| | | const formValuesChange = (changeList) => { |
| | | if (changeList && changeList.length > 0) { |
| | | changeList.forEach(change => { |
| | | const { name: nameList, value } = change; |
| | | nameList.forEach(name => { |
| | | switch (name) { |
| | | case 'x': |
| | | curSprite.position.x = value; |
| | | break; |
| | | case 'y': |
| | | curSprite.position.x = value; |
| | | break; |
| | | case 'scaleSlider': |
| | | form.setFieldsValue({ |
| | | scale: value |
| | | }) |
| | | curSprite.scale.set(value); |
| | | break; |
| | | case 'scale': |
| | | form.setFieldsValue({ |
| | | scaleSlider: value |
| | | }) |
| | | curSprite.scale.set(value); |
| | | break; |
| | | case 'rotationSlider': |
| | | form.setFieldsValue({ |
| | | rotation: value |
| | | }) |
| | | curSprite.rotation = value * Math.PI / 180; |
| | | break; |
| | | case 'rotation': |
| | | form.setFieldsValue({ |
| | | rotationSlider: value |
| | | }) |
| | | curSprite.rotation = value * Math.PI / 180; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | Utils.removeSelectedEffect(); |
| | | Utils.showSelectedEffect(curSprite); |
| | | }) |
| | | }) |
| | | if (activeTabKey === 'map') { |
| | | mapForm.submit(); |
| | | } |
| | | if (activeTabKey === 'config') { |
| | | configForm.submit(); |
| | | } |
| | | } |
| | | |
| | | const onFinishFailed = (errorInfo) => { |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | |
| | | <Button onClick={handleCancel}> |
| | | <FormattedMessage id='common.cancel' defaultMessage='取消' /> |
| | | </Button> |
| | | <Button onClick={handleOk} type="primary"> |
| | | <Button hidden={activeTabKey === 'map'} onClick={handleOk} type="primary"> |
| | | <FormattedMessage id='common.submit' defaultMessage='保存' /> |
| | | </Button> |
| | | </Space> |
| | | } |
| | | > |
| | | <Form |
| | | form={form} |
| | | onFieldsChange={formValuesChange} |
| | | initialValues={{ |
| | | <Card |
| | | hoverable |
| | | bordered={false} |
| | | type='inner' |
| | | tabList={[ |
| | | { |
| | | key: 'map', |
| | | tab: intl.formatMessage({ id: 'map.settings.map.param', defaultMessage: '地图参数' }), |
| | | icon: <BorderOuterOutlined /> |
| | | |
| | | }, |
| | | { |
| | | key: 'config', |
| | | tab: intl.formatMessage({ id: 'map.settings.config.param', defaultMessage: '系统参数' }), |
| | | icon: <BranchesOutlined /> |
| | | }, |
| | | ]} |
| | | activeTabKey={activeTabKey} |
| | | onTabChange={(key) => { |
| | | setActiveTabKey(key) |
| | | }} |
| | | onFinish={handleFinish} |
| | | onFinishFailed={onFinishFailed} |
| | | autoComplete="off" |
| | | style={{ |
| | | maxWidth: 600, |
| | | tabProps={{ |
| | | centered: true, |
| | | size: 'large', |
| | | type: "card", |
| | | style: { |
| | | } |
| | | }} |
| | | size='default' // small | default | large |
| | | variant='filled' // outlined | borderless | filled |
| | | labelWrap // label 换行 |
| | | disabled={false} |
| | | layout='horizontal' |
| | | > |
| | | <Row gutter={[24, 16]}> |
| | | {contentList[activeTabKey]} |
| | | </Card> |
| | | |
| | | {/* */} |
| | | <Col span={24}> |
| | | <Row gutter={24}> |
| | | <Col span={18}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.type', defaultMessage: '类型' })} |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <span className="ant-form-text">China</span> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Col> |
| | | |
| | | {/* position */} |
| | | <Col span={24}> |
| | | <Row gutter={24}> |
| | | <Col span={18}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.position', defaultMessage: '坐标' })} |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <Space.Compact> |
| | | <Form.Item |
| | | name='x' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact>x</Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='y' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact>y</Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Space.Compact> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Col> |
| | | |
| | | {/* scale */} |
| | | <Col span={24}> |
| | | <Row gutter={24}> |
| | | <Col span={18}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.scale', defaultMessage: '缩放' })} |
| | | name="scaleSlider" |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <Slider |
| | | min={0.1} |
| | | max={10} |
| | | step={0.1} |
| | | marks={{ |
| | | 0.1: '0.1', |
| | | 1: '1', |
| | | 10: '10', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6}> |
| | | <Form.Item |
| | | name="scale" |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <InputNumber |
| | | changeOnWheel |
| | | min={0.1} max={10} defaultValue={1} step={0.1} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Col> |
| | | |
| | | {/* rotation */} |
| | | <Col span={24}> |
| | | <Row gutter={24}> |
| | | <Col span={18}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.rotation', defaultMessage: '角度' })} |
| | | name="rotationSlider" |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <Slider |
| | | min={0} |
| | | max={360} |
| | | step={1} |
| | | marks={{ |
| | | 0: '0°', |
| | | 90: '90°', |
| | | 180: '180°', |
| | | 270: '270°', |
| | | 360: '360°', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6}> |
| | | <Form.Item |
| | | name="rotation" |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <InputNumber |
| | | changeOnWheel |
| | | min={0} max={360} defaultValue={0} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Col> |
| | | |
| | | {/* 复制 */} |
| | | <Col span={24}> |
| | | <Row gutter={24}> |
| | | <Col span={18}> |
| | | <Form.Item |
| | | label={intl.formatMessage({ id: 'map.settings.copy', defaultMessage: '复制' })} |
| | | labelCol={{ span: 4 }} |
| | | > |
| | | <Space.Compact> |
| | | <Form.Item |
| | | name="copyDire" |
| | | > |
| | | <Select |
| | | defaultValue="left" |
| | | style={{ width: 80 }} |
| | | options={[ |
| | | { value: 'left', label: intl.formatMessage({ id: 'map.settings.left', defaultMessage: '左' }) }, |
| | | { value: 'right', label: intl.formatMessage({ id: 'map.settings.right', defaultMessage: '右' }) }, |
| | | { value: 'top', label: intl.formatMessage({ id: 'map.settings.top', defaultMessage: '上' }) }, |
| | | { value: 'bottom', label: intl.formatMessage({ id: 'map.settings.bottom', defaultMessage: '下' }) }, |
| | | ]} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name='copyCount' |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | min={1} defaultValue={1} step={1} |
| | | /> |
| | | </Form.Item> |
| | | <Form.Item> |
| | | <Button> |
| | | <FormattedMessage id='common.execute' defaultMessage='执行' /> |
| | | </Button> |
| | | </Form.Item> |
| | | </Space.Compact> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Col> |
| | | |
| | | |
| | | {/* <Col span={12}> |
| | | <Form.Item |
| | | label="Username" |
| | | name="username" |
| | | hasFeedback |
| | | validateTrigger="onBlur" |
| | | validateDebounce={1000} |
| | | rules={[ |
| | | { |
| | | required: false, |
| | | } |
| | | ]} |
| | | > |
| | | <Input disabled={false} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | label="Switch" |
| | | valuePropName="checked" |
| | | > |
| | | <Switch /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item label="Memo"> |
| | | <Input.TextArea /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item label="Address"> |
| | | <Space.Compact> |
| | | <Form.Item |
| | | name={['address', 'province']} |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: false, |
| | | message: 'Province is required', |
| | | }, |
| | | ]} |
| | | > |
| | | <Select placeholder="Select province"> |
| | | <Option value="Zhejiang">Zhejiang</Option> |
| | | <Option value="Jiangsu">Jiangsu</Option> |
| | | </Select> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name={['address', 'street']} |
| | | noStyle |
| | | rules={[ |
| | | { |
| | | required: false, |
| | | message: 'Street is required', |
| | | }, |
| | | ]} |
| | | > |
| | | <Input |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | placeholder="Input street" |
| | | /> |
| | | </Form.Item> |
| | | </Space.Compact> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | name="phone" |
| | | label="Phone Number" |
| | | rules={[ |
| | | { |
| | | required: false, |
| | | message: 'Please input your phone number!', |
| | | }, |
| | | ]} |
| | | > |
| | | <Input |
| | | addonBefore={prefixSelector} |
| | | style={{ |
| | | width: '100%', |
| | | }} |
| | | /> |
| | | </Form.Item> |
| | | </Col> */} |
| | | |
| | | |
| | | |
| | | </Row> |
| | | </Form> |
| | | </Drawer > |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default SpriteSettings; |
| | | export default Settings; |
New file |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Drawer } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import Http from '@/utils/http'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | |
| | | }) |
| | | |
| | | const MapDrawer = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | |
| | | return ( |
| | | <> |
| | | <Drawer |
| | | |
| | | /> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default MapDrawer; |
| | |
| | | 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, Select } from 'antd'; |
| | | import { Layout, Button, Flex, Row, Col, FloatButton, Select, Spin } from 'antd'; |
| | | const { Header, Content } = Layout; |
| | | import { |
| | | AppstoreAddOutlined, |
| | |
| | | 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'; |
| | |
| | | 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 |
| | |
| | | <Layout className={styles.layout}> |
| | | <Header className={styles.header}> |
| | | <Row style={{ height: '100%' }}> |
| | | <Col span={8} style={{ backgroundColor: '#3C40C6' }}></Col> |
| | | <Col span={8} style={{ backgroundColor: '#dcdde1' }}> |
| | | |
| | | |
| | | <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 |
| | |
| | | setSettingsVisible(false); |
| | | setSpriteBySettings(null); |
| | | }} |
| | | setSpriteBySettings={setSpriteBySettings} |
| | | setDidClickSprite={setDidClickSprite} |
| | | refCurr={mapRef.current} |
| | | onSubmit={settingsFinish} |
| | | /> |
| | |
| | | mapContainer = param; |
| | | } |
| | | |
| | | export function getMapContainer() { |
| | | return mapContainer; |
| | | } |
| | | |
| | | export const MapEvent = Object.freeze({ |
| | | SELECTION_BOX: Symbol.for(0), |
| | | }) |
| | | |
| | | export const SENSOR_TYPE = Object.freeze({ |
| | | AGV: "AGV", |
| | | SHELF: "SHELF", |
| | | }) |
| | | |
| | | export const getRealPosition = (x, y, mapContainer) => { |
| | |
| | | sprite.cursor = 'pointer'; |
| | | sprite.eventMode = 'static'; |
| | | sprite.data = { |
| | | type: type |
| | | type: type, |
| | | uuid: generateID() |
| | | }; |
| | | } |
| | | |
| | |
| | | effectTick = (delta) => { |
| | | phase += delta / 10; |
| | | phase %= (Math.PI * 2); |
| | | effectHalfCircle.rotation = phase; |
| | | if (effectHalfCircle) { |
| | | effectHalfCircle.rotation = phase; |
| | | } |
| | | }; |
| | | |
| | | app.ticker.add(effectTick); |
| | |
| | | } |
| | | } |
| | | |
| | | export const copySprite = (sprite) => { |
| | | const copiedSprite = new PIXI.Sprite(sprite.texture); |
| | | initSprite(copiedSprite); |
| | | copiedSprite.position.set(sprite.position.x, sprite.position.y); |
| | | copiedSprite.scale.set(sprite.scale.x, sprite.scale.y); |
| | | copiedSprite.rotation = sprite.rotation; |
| | | copiedSprite.data = deepCopy(sprite.data); |
| | | copiedSprite.data.uuid = generateID(); |
| | | return copiedSprite; |
| | | } |
| | | |
| | | export const markSprite = (sprite) => { |
| | | sprite.alpha = 0.5; |
| | | } |
| | | |
| | | export const unMarkSprite = (sprite) => { |
| | | sprite.alpha = 1; |
| | | } |
| | | |
| | | export const generateID = () => { |
| | | return Date.now().toString(36) + Math.random().toString(36).substring(2); |
| | | } |
| | | |
| | | export const deepCopy = (data) => { |
| | | return JSON.parse(JSON.stringify(data)); |
| | | } |
| | | |
| | | export const pureNumStr = (param) => { |
| | | if (param) { |
| | | return Number(param); |
| | | } else { |
| | | return ''; |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } catch (ExpiredJwtException e) { |
| | | e.printStackTrace(); |
| | | // e.printStackTrace(); |
| | | HttpUtils.responseError(response, Constants.TOKEN_EXPIRED_CODE, Constants.TOKEN_EXPIRED_MSG, |
| | | e.getMessage()); |
| | | return; |