import {RenderTexture} from '@pixi/core'; import {Container} from '@pixi/display'; import {BlurFilter} from '@pixi/filter-blur'; import {Graphics} from '@pixi/graphics'; import {PixiComponent, useApp} from '@pixi/react'; import {Sprite} from '@pixi/sprite'; import {useEffect, useState} from 'react'; const tileSize = {x: 16, y: 16}; const radius = 11; function makeFade(renderer) { const fade = new Graphics(); fade.beginFill(0xffffff); fade.alpha = 0.35; fade.drawCircle( tileSize.x * (radius / 2), tileSize.y * (radius / 2), ((tileSize.x + tileSize.y) / 2) * (radius * 0.35), ) fade.filters = [new BlurFilter(((tileSize.x + tileSize.y) / 2) * 1.25)]; const renderTexture = RenderTexture.create({ width: tileSize.x * radius, height: tileSize.y * radius, }); renderer.render(fade, {renderTexture}); return new Sprite(renderTexture); } const TargetingGhostInternal = PixiComponent('TargetingGhost', { create: ({app}) => { const fade = makeFade(app.renderer); const grid = new Graphics(); const lineWidth = 1; grid.lineStyle(lineWidth, 0xffffff); for (let y = 0; y < radius; ++y) { for (let x = 0; x < radius; ++x) { grid.drawRect( (x * tileSize.x) + (lineWidth / 2), (y * tileSize.y) + (lineWidth / 2), tileSize.x, tileSize.y, ); } } grid.mask = fade; const innerGrid = new Graphics(); innerGrid.lineStyle(lineWidth, 0x777777); for (let y = 0; y < radius; ++y) { for (let x = 0; x < radius; ++x) { innerGrid.drawRect( (x * tileSize.x) + (lineWidth / 2) + 1, (y * tileSize.y) + (lineWidth / 2) + 1, tileSize.x - 2, tileSize.y - 2, ); } } innerGrid.mask = fade; const container = new Container(); container.addChild(fade, grid, innerGrid); return container; }, applyProps: (container, oldProps, {cx, cy, px, py, tint}) => { container.x = px - (px % tileSize.x) - cx + (tileSize.x / 2) - (tileSize.x * (radius / 2)); container.y = py - (py % tileSize.y) - cy + (tileSize.y / 2) - (tileSize.y * (radius / 2)); container.children[0].x = px % tileSize.x - (tileSize.x / 2) ; container.children[0].y = py % tileSize.y - (tileSize.y / 2) ; const color = Math.round(255 - (tint * 255)); container.children[2].tint = `rgb(${color}, ${color}, ${color})`; }, }) export default function TargetingGhost({cx, cy, px, py}) { const app = useApp(); const [radians, setRadians] = useState(0); useEffect(() => { const handle = setInterval(() => { setRadians((radians) => (radians + 0.2) % (Math.PI * 2)) }, 50); return () => { clearInterval(handle); }; }, []); return ( ); }