From 99cc3bb108a9ced40b126778da8bbd34963549b5 Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期四, 10 十月 2024 10:52:10 +0800 Subject: [PATCH] # --- zy-acs-flow/src/map/tool.js | 109 ++++++++++++++++++++++++++++++++++- zy-acs-flow/src/map/player.js | 21 ++++++ zy-acs-flow/src/map/MapPage.jsx | 34 ++++++++++- 3 files changed, 155 insertions(+), 9 deletions(-) diff --git a/zy-acs-flow/src/map/MapPage.jsx b/zy-acs-flow/src/map/MapPage.jsx index 2093fdc..a2335b3 100644 --- a/zy-acs-flow/src/map/MapPage.jsx +++ b/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: '淇濆瓨' }, diff --git a/zy-acs-flow/src/map/player.js b/zy-acs-flow/src/map/player.js index 9b2124b..bb27b88 100644 --- a/zy-acs-flow/src/map/player.js +++ b/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) => { diff --git a/zy-acs-flow/src/map/tool.js b/zy-acs-flow/src/map/tool.js index 4d3a804..fa64cbe 100644 --- a/zy-acs-flow/src/map/tool.js +++ b/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); } -- Gitblit v1.9.1