zy-acs-flow/src/map/MapPage.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-flow/src/map/player.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-flow/src/map/tool.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
zy-acs-flow/src/map/MapPage.jsx
@@ -28,10 +28,10 @@ let player; const Map = () => { const theme = useTheme(); const themeMode = theme.palette.mode; const notify = useNotification(); const translate = useTranslate(); const theme = useTheme(); const themeMode = theme.palette.mode; const mapRef = useRef(); const contentRef = useRef(); @@ -39,8 +39,11 @@ const [mapContainer, setMapContainer] = useState(null); const [mode, setMode] = useState(MapMode.OBSERVER_MODE); const [deviceVisible, setDeviceVisible] = React.useState(false); const [deviceVisible, setDeviceVisible] = useState(false); const [settingsVisible, setSettingsVisible] = useState(false); const [spriteSettings, setSpriteSettings] = useState(null); const prevSpriteSettingsRef = React.useRef(); useEffect(() => { Tool.patchRaLayout('0px'); @@ -50,6 +53,7 @@ setMapContainer(player.mapContainer); Tool.setApp(player.app); Tool.setMapContainer(player.mapContainer); Tool.setThemeMode(themeMode); Http.setNotify(notify); await Http.fetchMapData(0); @@ -103,6 +107,10 @@ player.activateMapMultiSelect((selectedSprites, restartFn) => { console.log(selectedSprites); }); mapContainer.children.forEach(child => { Tool.beSettings(child, setSpriteSettings); }) break default: break @@ -126,6 +134,26 @@ Tool.beMovable(sprite); }; // watch spriteSettings useEffect(() => { if (!mapContainer) { return; } console.log(spriteSettings); prevSpriteSettingsRef.current = spriteSettings; if (spriteSettings && prevSpriteSettings !== spriteSettings) { Tool.removeSelectedEffect(); } if (spriteSettings) { Tool.showSelectedEffect(spriteSettings) setSettingsVisible(true); } else { Tool.removeSelectedEffect(); } }, [spriteSettings, mapContainer]) const prevSpriteSettings = prevSpriteSettingsRef.current; const actions = [ { icon: <FileCopyIcon />, name: '复制' }, { icon: <SaveIcon />, name: '保存' }, zy-acs-flow/src/map/player.js
@@ -17,6 +17,7 @@ this.activateMapScale(); this.activateMapPan(); this.showCoordinates(); this.startupTicker(); const bunny = PIXI.Sprite.from('https://pixijs.com/assets/bunny.png'); @@ -226,6 +227,25 @@ }, 200).start(); } showCoordinates = () => { const coordinatesText = new PIXI.Text('{ x: 0, y: 0 }', { fill: this.themeMode === 'dark' ? 0xffffff : 0x000000, fontSize: 13, fontFamily: 'MicrosoftYaHei', fontWeight: 'bold', }); coordinatesText.name = 'xyStr' coordinatesText.position.set(10, 10); this.app.stage.addChild(coordinatesText); const mouseMoveInfoTextHandler = (event) => { const mouseX = (event.clientX - this.mapContainer.position.x) / this.scale; const mouseY = (event.clientY - this.mapContainer.position.y) / this.scale; coordinatesText.text = `{ x: ${mouseX.toFixed(2)}, y: ${mouseY.toFixed(2)} }`; }; this.app.view.addEventListener('mousemove', mouseMoveInfoTextHandler); } showGridLines = () => { this.hideGridLines(); if (!this.gridLineContainer) { @@ -264,7 +284,6 @@ this.gridLineContainer = null; } } startupTicker = () => { this.app.ticker.add((delta) => { zy-acs-flow/src/map/tool.js
@@ -10,23 +10,33 @@ import station from '/map/station.svg'; import direction from '/map/direction.svg'; let app, mapContainer; let app, mapContainer, themeMode; let selectedSprite, effectTick, effectHalfCircle, effectRectangle; export function getApp() { return app; } export function setApp(param) { app = param; } export function getMapContainer() { return mapContainer; } export function setMapContainer(param) { mapContainer = param; } export function getApp() { return app; export function getThemeMode() { return themeMode; } export function getMapContainer() { return mapContainer; export function setThemeMode(param) { themeMode = param; } export const getRealPosition = (x, y) => { const rect = app.view.getBoundingClientRect(); @@ -189,6 +199,19 @@ && spriteBounds.y < boxBounds.y + boxBounds.height; } export const beSettings = (sprite, setSpriteSettings) => { sprite.off('pointerup'); sprite.off('pointermove'); sprite.off('pointerdown'); sprite.off('click'); sprite.on("click", onClick); function onClick(event) { setSpriteSettings(sprite); } } export const clearMapData = () => { if (!mapContainer) { return; @@ -212,6 +235,82 @@ } export const showSelectedEffect = (sprite) => { const { width, height } = sprite; const scale = sprite.scale.x; const sideLen = (Math.max(width, height) + 10) * scale; const color = themeMode === 'light' ? 0x273c75 : 0xffffff; effectHalfCircle = new PIXI.Graphics(); effectHalfCircle.beginFill(color); effectHalfCircle.lineStyle(2 * scale, color); effectHalfCircle.arc(0, 0, sideLen, 0, Math.PI); effectHalfCircle.endFill(); effectHalfCircle.position.set(sprite.x, sprite.y); effectHalfCircle.scale.set(1 / scale); effectHalfCircle.zIndex = 9999; effectRectangle = new PIXI.Graphics(); effectRectangle.lineStyle(5 * scale, color, 1); effectRectangle.drawRoundedRect(0, 0, sideLen, sideLen, 16 * scale); effectRectangle.endFill(); effectRectangle.mask = effectHalfCircle; effectRectangle.zIndex = 9999; const scaledWidth = sideLen * (1 / scale); const scaledHeight = sideLen * (1 / scale); effectRectangle.scale.set(1 / scale); effectRectangle.position.set(sprite.x - scaledWidth / 2, sprite.y - scaledHeight / 2); mapContainer.addChild(effectRectangle); mapContainer.addChild(effectHalfCircle); selectedSprite = sprite; let phase = 0; effectTick = (delta) => { phase += delta / 10; phase %= (Math.PI * 2); if (effectHalfCircle) { effectHalfCircle.rotation = phase; } }; app.ticker.add(effectTick); } export const removeSelectedEffect = () => { if (effectTick) { app.ticker.remove(effectTick); } if (effectHalfCircle) { mapContainer.removeChild(effectHalfCircle); effectHalfCircle = null; } if (effectRectangle) { mapContainer.removeChild(effectRectangle); effectRectangle = null; } selectedSprite = null; } export const updateEffect = (sprite) => { if (!sprite || sprite !== selectedSprite || !effectRectangle || !effectHalfCircle) { return } const { width, height } = sprite; const scale = sprite?.scale.x; const sideLen = (Math.max(width, height) + 10) * scale; const scaledWidth = sideLen * (1 / scale); const scaledHeight = sideLen * (1 / scale); effectRectangle.position.set(sprite.x - scaledWidth / 2, sprite.y - scaledHeight / 2); effectHalfCircle.position.set(sprite.x, sprite.y); } export const generateID = () => { return Date.now().toString(36) + Math.random().toString(36).substring(2); }