|  |  | 
 |  |  |     MenuItem, | 
 |  |  |     InputLabel, | 
 |  |  |     FormControl, | 
 |  |  |     FormHelperText, | 
 |  |  |     Checkbox, | 
 |  |  |     FormControlLabel, | 
 |  |  |     Stack, | 
 |  |  |     Divider, | 
 |  |  | } from '@mui/material'; | 
 |  |  | import MuiInput from '@mui/material/Input'; | 
 |  |  | import { useTranslate } from 'react-admin'; | 
 |  |  | import * as Tool from '../tool'; | 
 |  |  | import ConfirmButton from '../../page/components/ConfirmButton'; | 
 |  |  |  | 
 |  |  | const MapSettings = (props) => { | 
 |  |  |     const { sprite, onSubmit } = props; | 
 |  |  |     const { sprite, setSpriteSettings, onSubmit } = props; | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |  | 
 |  |  |     const { control, handleSubmit, reset, watch, setValue } = useForm({ | 
 |  |  |     const { control, handleSubmit, reset, watch } = useForm({ | 
 |  |  |         defaultValues: { | 
 |  |  |             x: sprite?.position.x || 0, | 
 |  |  |             y: sprite?.position.y || 0, | 
 |  |  | 
 |  |  |             rotation: (sprite?.rotation * 180) / Math.PI || 0, | 
 |  |  |             copyDirection: 'right', | 
 |  |  |             copyCount: 1, | 
 |  |  |             // 其他默认值... | 
 |  |  |         }, | 
 |  |  |     }); | 
 |  |  |  | 
 |  |  |     // 监听表单值的变化 | 
 |  |  |     const watchAllFields = watch(); | 
 |  |  |  | 
 |  |  |     useEffect(() => { | 
 |  |  | 
 |  |  |                 scaleX: sprite.scale.x, | 
 |  |  |                 scaleY: sprite.scale.y, | 
 |  |  |                 rotation: (sprite.rotation * 180) / Math.PI, | 
 |  |  |                 // 设置其他字段的初始值 | 
 |  |  |             }); | 
 |  |  |         } | 
 |  |  |     }, [sprite, reset]); | 
 |  |  |  | 
 |  |  |     // 更新精灵属性的函数 | 
 |  |  |     const updateSprite = (data) => { | 
 |  |  |         if (sprite) { | 
 |  |  |             sprite.position.x = data.x; | 
 |  |  | 
 |  |  |             sprite.scale.x = data.scaleX; | 
 |  |  |             sprite.scale.y = data.scaleY; | 
 |  |  |             sprite.rotation = (data.rotation * Math.PI) / 180; | 
 |  |  |             // 更新其他属性... | 
 |  |  |         } | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     // 处理表单提交 | 
 |  |  |     const onFormSubmit = (data) => { | 
 |  |  |         updateSprite(data); | 
 |  |  |         if (onSubmit) { | 
 |  |  | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <Box component="form" onSubmit={handleSubmit(onFormSubmit)} noValidate sx={{ mt: 2 }}> | 
 |  |  |             <Grid container spacing={2}> | 
 |  |  |                 {/* 位置 */} | 
 |  |  |         <Box component="form" onSubmit={handleSubmit(onFormSubmit)} noValidate sx={{ mt: 0 }}> | 
 |  |  |             <Grid container spacing={1.4}> | 
 |  |  |                 {/* position */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="h6">{translate('map.settings.position')}</Typography> | 
 |  |  |                     <Typography variant="inherit"> | 
 |  |  |                         {translate('page.map.settings.map.base.position')} | 
 |  |  |                     </Typography> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |                 <Grid item xs={6} pt={0} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="x" | 
 |  |  |                         control={control} | 
 |  |  | 
 |  |  |                                 type="number" | 
 |  |  |                                 fullWidth | 
 |  |  |                                 onChange={(e) => { | 
 |  |  |                                     const value = parseFloat(e.target.value); | 
 |  |  |                                     field.onChange(e); | 
 |  |  |                                     updateSprite({ ...watchAllFields, x: parseFloat(e.target.value) }); | 
 |  |  |                                     if (!isNaN(value)) { | 
 |  |  |                                         updateSprite({ ...watchAllFields, x: value }); | 
 |  |  |                                     } | 
 |  |  |                                 }} | 
 |  |  |                             /> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |                 <Grid item xs={6} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="y" | 
 |  |  |                         control={control} | 
 |  |  | 
 |  |  |                                 type="number" | 
 |  |  |                                 fullWidth | 
 |  |  |                                 onChange={(e) => { | 
 |  |  |                                     const value = parseFloat(e.target.value); | 
 |  |  |                                     field.onChange(e); | 
 |  |  |                                     updateSprite({ ...watchAllFields, y: parseFloat(e.target.value) }); | 
 |  |  |                                     if (!isNaN(value)) { | 
 |  |  |                                         updateSprite({ ...watchAllFields, y: value }); | 
 |  |  |                                     } | 
 |  |  |                                 }} | 
 |  |  |                             /> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 {/* 缩放 */} | 
 |  |  |                 {/* scale */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="h6">{translate('map.settings.scale')}</Typography> | 
 |  |  |                     <Typography variant="inherit"> | 
 |  |  |                         {translate('page.map.settings.map.base.scale')} | 
 |  |  |                     </Typography> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |                 <Grid item xs={6} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="scaleX" | 
 |  |  |                         control={control} | 
 |  |  |                         render={({ field }) => ( | 
 |  |  |                             <TextField | 
 |  |  |                                 {...field} | 
 |  |  |                                 label="Scale X" | 
 |  |  |                                 label="X" | 
 |  |  |                                 type="number" | 
 |  |  |                                 fullWidth | 
 |  |  |                                 inputProps={{ step: 0.1, min: 0.1, max: 10 }} | 
 |  |  |                                 onChange={(e) => { | 
 |  |  |                                     const value = parseFloat(e.target.value); | 
 |  |  |                                     field.onChange(e); | 
 |  |  |                                     updateSprite({ ...watchAllFields, scaleX: parseFloat(e.target.value) }); | 
 |  |  |                                     if (!isNaN(value)) { | 
 |  |  |                                         updateSprite({ ...watchAllFields, scaleX: value }); | 
 |  |  |                                     } | 
 |  |  |                                 }} | 
 |  |  |                             /> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |                 <Grid item xs={6} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="scaleY" | 
 |  |  |                         control={control} | 
 |  |  |                         render={({ field }) => ( | 
 |  |  |                             <TextField | 
 |  |  |                                 {...field} | 
 |  |  |                                 label="Scale Y" | 
 |  |  |                                 label="Y" | 
 |  |  |                                 type="number" | 
 |  |  |                                 fullWidth | 
 |  |  |                                 inputProps={{ step: 0.1, min: 0.1, max: 10 }} | 
 |  |  |                                 onChange={(e) => { | 
 |  |  |                                     const value = parseFloat(e.target.value); | 
 |  |  |                                     field.onChange(e); | 
 |  |  |                                     updateSprite({ ...watchAllFields, scaleY: parseFloat(e.target.value) }); | 
 |  |  |                                     if (!isNaN(value)) { | 
 |  |  |                                         updateSprite({ ...watchAllFields, scaleY: value }); | 
 |  |  |                                     } | 
 |  |  |                                 }} | 
 |  |  |                             /> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 {/* 旋转 */} | 
 |  |  |                 {/* rotation */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="h6">{translate('map.settings.rotation')}</Typography> | 
 |  |  |                     <Typography variant="inherit"> | 
 |  |  |                         {translate('page.map.settings.map.base.rotation')} | 
 |  |  |                     </Typography> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="rotation" | 
 |  |  |                         control={control} | 
 |  |  |                         render={({ field }) => ( | 
 |  |  |                             <Slider | 
 |  |  |                                 {...field} | 
 |  |  |                                 min={0} | 
 |  |  |                                 max={360} | 
 |  |  |                                 step={1} | 
 |  |  |                                 valueLabelDisplay="auto" | 
 |  |  |                                 onChange={(e, value) => { | 
 |  |  |                                     field.onChange(value); | 
 |  |  |                                     updateSprite({ ...watchAllFields, rotation: value }); | 
 |  |  |                                 }} | 
 |  |  |                     <Box display="flex" alignItems="center"> | 
 |  |  |                         <Box flex={1} mr={3}> | 
 |  |  |                             <Controller | 
 |  |  |                                 name="rotation" | 
 |  |  |                                 control={control} | 
 |  |  |                                 render={({ field }) => ( | 
 |  |  |                                     <Slider | 
 |  |  |                                         {...field} | 
 |  |  |                                         // size="small" | 
 |  |  |                                         min={0} | 
 |  |  |                                         max={360} | 
 |  |  |                                         step={1} | 
 |  |  |                                         valueLabelDisplay="auto" | 
 |  |  |                                         valueLabelFormat={(value) => `${value}°`} | 
 |  |  |                                         onChange={(e, value) => { | 
 |  |  |                                             field.onChange(value); | 
 |  |  |                                             updateSprite({ ...watchAllFields, rotation: value }); | 
 |  |  |                                         }} | 
 |  |  |                                     /> | 
 |  |  |                                 )} | 
 |  |  |                             /> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                         </Box> | 
 |  |  |                         <Box > | 
 |  |  |                             <Controller | 
 |  |  |                                 name="rotation" | 
 |  |  |                                 control={control} | 
 |  |  |                                 render={({ field }) => ( | 
 |  |  |                                     <MuiInput | 
 |  |  |                                         {...field} | 
 |  |  |                                         size="small" | 
 |  |  |                                         value={field.value} | 
 |  |  |                                         onChange={(e) => { | 
 |  |  |                                             const value = e.target.value === '' ? 0 : Number(e.target.value); | 
 |  |  |                                             if (!isNaN(value)) { | 
 |  |  |                                                 field.onChange(value); | 
 |  |  |                                                 updateSprite({ ...watchAllFields, rotation: value }); | 
 |  |  |                                             } | 
 |  |  |                                         }} | 
 |  |  |                                         onBlur={() => { | 
 |  |  |                                             if (field.value < 0) { | 
 |  |  |                                                 field.onChange(0); | 
 |  |  |                                             } else if (field.value > 360) { | 
 |  |  |                                                 field.onChange(360); | 
 |  |  |                                             } | 
 |  |  |                                         }} | 
 |  |  |                                         inputProps={{ | 
 |  |  |                                             step: 1, | 
 |  |  |                                             min: 0, | 
 |  |  |                                             max: 360, | 
 |  |  |                                             type: 'number', | 
 |  |  |                                             'aria-labelledby': 'input-slider', | 
 |  |  |                                         }} | 
 |  |  |                                     /> | 
 |  |  |                                 )} | 
 |  |  |                             /> | 
 |  |  |                         </Box> | 
 |  |  |                     </Box> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 {/* 复制 */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="h6">{translate('map.settings.copy')}</Typography> | 
 |  |  |                     <Divider /> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |  | 
 |  |  |                 {/* copy */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="inherit"> | 
 |  |  |                         {translate('page.map.settings.map.copy.title')} | 
 |  |  |                     </Typography> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="copyDirection" | 
 |  |  |                         control={control} | 
 |  |  |                         render={({ field }) => ( | 
 |  |  |                             <FormControl fullWidth> | 
 |  |  |                                 <InputLabel>{translate('map.settings.copyDirection')}</InputLabel> | 
 |  |  |                                 <Select {...field} label={translate('map.settings.copyDirection')}> | 
 |  |  |                                     <MenuItem value="left">{translate('map.settings.left')}</MenuItem> | 
 |  |  |                                     <MenuItem value="right">{translate('map.settings.right')}</MenuItem> | 
 |  |  |                                     <MenuItem value="up">{translate('map.settings.up')}</MenuItem> | 
 |  |  |                                     <MenuItem value="down">{translate('map.settings.down')}</MenuItem> | 
 |  |  |                                 <InputLabel> | 
 |  |  |                                     {translate('page.map.settings.map.copy.direction')} | 
 |  |  |                                 </InputLabel> | 
 |  |  |                                 <Select | 
 |  |  |                                     {...field} | 
 |  |  |                                     label={translate('page.map.settings.map.copy.direction')} | 
 |  |  |                                 > | 
 |  |  |                                     <MenuItem value="left"> | 
 |  |  |                                         {translate('page.map.settings.map.copy.left')} | 
 |  |  |                                     </MenuItem> | 
 |  |  |                                     <MenuItem value="right"> | 
 |  |  |                                         {translate('page.map.settings.map.copy.right')} | 
 |  |  |                                     </MenuItem> | 
 |  |  |                                     <MenuItem value="up"> | 
 |  |  |                                         {translate('page.map.settings.map.copy.up')} | 
 |  |  |                                     </MenuItem> | 
 |  |  |                                     <MenuItem value="down"> | 
 |  |  |                                         {translate('page.map.settings.map.copy.down')} | 
 |  |  |                                     </MenuItem> | 
 |  |  |                                 </Select> | 
 |  |  |                             </FormControl> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={6}> | 
 |  |  |                 <Grid item xs={6} sx={{ | 
 |  |  |                     paddingTop: '8px !important', | 
 |  |  |                 }}> | 
 |  |  |                     <Controller | 
 |  |  |                         name="copyCount" | 
 |  |  |                         control={control} | 
 |  |  |                         render={({ field }) => ( | 
 |  |  |                             <TextField | 
 |  |  |                                 {...field} | 
 |  |  |                                 label={translate('map.settings.copyCount')} | 
 |  |  |                                 label={translate('page.map.settings.map.copy.count')} | 
 |  |  |                                 type="number" | 
 |  |  |                                 fullWidth | 
 |  |  |                                 inputProps={{ min: 1 }} | 
 |  |  | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 {/* 提交按钮 */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Stack direction="row" spacing={2}> | 
 |  |  |                         <Button type="submit" variant="contained" color="primary"> | 
 |  |  |                             {translate('common.submit')} | 
 |  |  |                         <Button variant="contained" color="primary"> | 
 |  |  |                             {translate('page.map.settings.map.copy.execute')} | 
 |  |  |                         </Button> | 
 |  |  |                         <Button variant="outlined" color="secondary" onClick={() => reset()}> | 
 |  |  |                             {translate('common.reset')} | 
 |  |  |                         <Button variant="text" color="primary"> | 
 |  |  |                             {translate('page.map.settings.map.copy.reverse')} | 
 |  |  |                         </Button> | 
 |  |  |                     </Stack> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Divider /> | 
 |  |  |                 </Grid> | 
 |  |  |  | 
 |  |  |                 {/* more */} | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Typography variant="inherit"> | 
 |  |  |                         {translate('page.map.settings.map.more.title')} | 
 |  |  |                     </Typography> | 
 |  |  |                 </Grid> | 
 |  |  |                 <Grid item xs={12}> | 
 |  |  |                     <Stack direction="row" spacing={2}> | 
 |  |  |                         <Button variant="outlined" color="error" onClick={() => { | 
 |  |  |                             Tool.getMapContainer().removeChild(sprite); | 
 |  |  |                             setSpriteSettings(null); | 
 |  |  |                             Tool.removeSelectedEffect(); | 
 |  |  |                             reset(); | 
 |  |  |                         }}> | 
 |  |  |                             {translate('ra.action.delete')} | 
 |  |  |                         </Button> | 
 |  |  |                         {/* <ConfirmButton /> */} | 
 |  |  |                     </Stack> | 
 |  |  |                 </Grid> | 
 |  |  |             </Grid> | 
 |  |  |         </Box> | 
 |  |  |     ); |