Replace rectangle button with rounded-rect Graphics to match pill styling
The old flat `Rectangle` background couldn't have rounded corners, so buttons visually clashed with the pill UI elements. Switching to a `Graphics` object lets us draw a rounded rect (using the shared `PILL_RADIUS`) while preserving the same fill/stroke colors and hover behavior. Key details: - Added `drawBg()` helper that clears and redraws the rounded rect + outline, reused for both normal and hover states. - Replaced `setFillStyle` hover handlers with re-draw calls since Graphics has no fill style API. - Defined an explicit hit area matching the drawn rounded rect; without it, `setInteractive()` on a Graphics uses the full 512x512 texture frame, causing clicks near other buttons to land on the wrong one.
This commit is contained in:
parent
ba3385ee19
commit
2e4b67db89
|
|
@ -1,20 +1,48 @@
|
|||
import Phaser from 'phaser';
|
||||
import { WORLD_SCALE } from '../config.js';
|
||||
import { PILL_RADIUS } from './pill.js';
|
||||
|
||||
// Rounded-rect blue button - same look as the old flat Rectangle button,
|
||||
// just with rounded corners matching the pills (PILL_RADIUS). Graphics
|
||||
// instead of a Rectangle because only Graphics can round corners; the
|
||||
// hover highlight re-draws the fill, keeping the dark outline.
|
||||
const FILL = 0x2255aa;
|
||||
const HOVER_FILL = 0x2f6ac0;
|
||||
const STROKE = 0x1a1f29;
|
||||
const STROKE_WIDTH = 2 * WORLD_SCALE;
|
||||
|
||||
function drawBg(g, width, height, fill) {
|
||||
g.clear();
|
||||
g.fillStyle(fill, 1);
|
||||
g.fillRoundedRect(-width / 2, -height / 2, width, height, PILL_RADIUS);
|
||||
g.lineStyle(STROKE_WIDTH, STROKE, 1);
|
||||
g.strokeRoundedRect(-width / 2, -height / 2, width, height, PILL_RADIUS);
|
||||
}
|
||||
|
||||
export function createButton(scene, x, y, label, onClick, options = {}) {
|
||||
const width = options.width || 220 * WORLD_SCALE;
|
||||
const height = options.height || 56 * WORLD_SCALE;
|
||||
const fontSize = options.fontSize || `${20 * WORLD_SCALE}px`;
|
||||
|
||||
const bg = scene.add.rectangle(x, y, width, height, 0x2255aa).setStrokeStyle(2 * WORLD_SCALE, 0x1a1f29);
|
||||
const bg = scene.add.graphics().setPosition(x, y);
|
||||
drawBg(bg, width, height, FILL);
|
||||
const text = scene.add.text(x, y, label, {
|
||||
fontFamily: 'monospace',
|
||||
fontSize,
|
||||
color: '#ffffff',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
bg.setInteractive({ useHandCursor: true });
|
||||
bg.on('pointerover', () => bg.setFillStyle(0x2f6ac0));
|
||||
bg.on('pointerout', () => bg.setFillStyle(0x2255aa));
|
||||
// Explicit hit rect - a default setInteractive() on a Graphics would use
|
||||
// its full 512x512 texture frame, making clicks near other buttons land
|
||||
// on the wrong one. Graphics hit areas live in its local drawing space
|
||||
// (displayOrigin 0,0), so the rect mirrors the drawn rounded rect.
|
||||
bg.setInteractive({
|
||||
hitArea: new Phaser.Geom.Rectangle(-width / 2, -height / 2, width, height),
|
||||
hitAreaCallback: Phaser.Geom.Rectangle.Contains,
|
||||
useHandCursor: true,
|
||||
});
|
||||
bg.on('pointerover', () => drawBg(bg, width, height, HOVER_FILL));
|
||||
bg.on('pointerout', () => drawBg(bg, width, height, FILL));
|
||||
bg.on('pointerdown', onClick);
|
||||
|
||||
return { bg, text };
|
||||
|
|
|
|||
Loading…
Reference in New Issue