| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // export const showSelectedEffect = (sprite) => { |
| | | // if (!sprite?.texture || !sprite?.texture?.valid) { |
| | | // return; |
| | | // } |
| | | // 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); |
| | | // } |
| | | |
| | | let effectCircle = null; |
| | | let effectTicker = null; |
| | | |
| | | export const showSelectedEffect = (sprite) => { |
| | | if (!sprite?.texture || !sprite?.texture?.valid) { |
| | | return; |
| | | } |
| | | |
| | | // 如果已经有特效,先移除 |
| | | removeSelectedEffect(); |
| | | |
| | | const { width, height } = sprite; |
| | | const scale = sprite.scale.x; |
| | | const sideLen = (Math.max(width, height) + 10) * scale; |
| | | const maxDimension = Math.max(width, height); |
| | | const radius = (maxDimension / 2) * scale * 1.2; // 放大1.2倍,使圆稍大于sprite |
| | | |
| | | 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; |
| | | // 创建圆形特效 |
| | | effectCircle = new PIXI.Graphics(); |
| | | effectCircle.lineStyle(2 * scale, color, 1); |
| | | effectCircle.drawCircle(0, 0, radius); |
| | | effectCircle.endFill(); |
| | | effectCircle.position.set(sprite.x, sprite.y); |
| | | effectCircle.zIndex = sprite.zIndex - 1; // 确保不遮挡sprite |
| | | |
| | | 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); |
| | | // 将特效添加到容器中 |
| | | mapContainer.addChild(effectCircle); |
| | | |
| | | selectedSprite = sprite; |
| | | |
| | | let phase = 0; |
| | | effectTick = (delta) => { |
| | | phase += delta / 10; |
| | | phase %= (Math.PI * 2); |
| | | if (effectHalfCircle) { |
| | | effectHalfCircle.rotation = phase; |
| | | // 实现脉冲效果 |
| | | let pulseScale = 1; |
| | | let scalingUp = true; |
| | | effectTicker = (delta) => { |
| | | const pulseSpeed = 0.005 * delta; |
| | | if (scalingUp) { |
| | | pulseScale += pulseSpeed; |
| | | if (pulseScale >= 1.2) { |
| | | scalingUp = false; |
| | | } |
| | | } else { |
| | | pulseScale -= pulseSpeed; |
| | | if (pulseScale <= 1) { |
| | | scalingUp = true; |
| | | } |
| | | } |
| | | effectCircle.scale.set(pulseScale); |
| | | // 始终跟随sprite的位置 |
| | | effectCircle.position.set(selectedSprite.x, selectedSprite.y); |
| | | }; |
| | | |
| | | app.ticker.add(effectTick); |
| | | } |
| | | app.ticker.add(effectTicker); |
| | | }; |
| | | |
| | | export const removeSelectedEffect = () => { |
| | | if (effectTick) { |
| | | app.ticker.remove(effectTick); |
| | | if (effectTicker) { |
| | | app.ticker.remove(effectTicker); |
| | | effectTicker = null; |
| | | } |
| | | if (effectHalfCircle) { |
| | | mapContainer.removeChild(effectHalfCircle); |
| | | effectHalfCircle = null; |
| | | } |
| | | if (effectRectangle) { |
| | | mapContainer.removeChild(effectRectangle); |
| | | effectRectangle = null; |
| | | if (effectCircle) { |
| | | mapContainer.removeChild(effectCircle); |
| | | effectCircle.destroy(); |
| | | effectCircle = null; |
| | | } |
| | | selectedSprite = null; |
| | | } |
| | | }; |
| | | |
| | | export const updateEffect = (sprite) => { |
| | | if (!sprite || sprite !== selectedSprite || !effectRectangle || !effectHalfCircle) { |
| | | return |
| | | export const updateEffect = () => { |
| | | if (!selectedSprite || !effectCircle) { |
| | | 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); |
| | | } |
| | | // 更新圆的位置,确保跟随sprite |
| | | effectCircle.position.set(selectedSprite.x, selectedSprite.y); |
| | | }; |
| | | |
| | | export const multipleSelectEnhancer = (selectedSprites, setCurSprite, setBatchSprites) => { |
| | | selectedSprites = selectedSprites.filter(sprite => sprite.data?.type); |