Button Changes

This commit is contained in:
Brian Fertig 2026-08-10 23:06:42 -06:00
parent 167fdd6e3f
commit f150737004
1 changed files with 46 additions and 7 deletions

View File

@ -37,6 +37,16 @@ const TEXT = '#e8f4ff';
// visibly lighter/less final than a solid button.
const GHOST_ALPHA = 0.85;
// A disabled button used to rely entirely on Container-level alpha (0.5) to
// read as "off" — which left the scheme's own vivid border glow (and its
// postFX bloom, which doesn't necessarily fade in proportion to container
// alpha) still doing most of the talking, so a disabled button could still
// look lit up. Disabled now swaps the glow/stroke and text to this flat,
// desaturated steel color instead of just dimming the scheme color, so
// "disabled" is unambiguous regardless of which scheme the button uses.
const DISABLED_GLOW = 0x3a4a5c;
const DISABLED_TEXT = '#5a6b80';
export class Button extends Phaser.GameObjects.Container {
constructor(scene, x, y, label, onClick, options = {}) {
super(scene, x, y);
@ -57,11 +67,15 @@ export class Button extends Phaser.GameObjects.Container {
// (_perimeterPoint) doesn't recompute the polygon's arc-length table
// on every animation frame.
this._perimeter = this._computePerimeter();
this._enabled = true;
const isGhost = variant === 'ghost';
this.bgRect = scene.add.graphics();
this.bgRect.postFX.addGlow(scm.glow, 3, 0, false, 0.1, 10);
// Captured so setEnabled can retint it directly (DISABLED_GLOW) rather
// than rely on container alpha to dim a bloom effect that doesn't
// necessarily fade in proportion to it.
this._glowFx = this.bgRect.postFX.addGlow(scm.glow, 3, 0, false, 0.1, 10);
// Shimmer + corner-bracket overlays, chamfer-clipped so they never
// spill past the panel outline. Created before the first _drawBg() call
@ -109,7 +123,12 @@ export class Button extends Phaser.GameObjects.Container {
});
const onOver = () => {
if (this._active) return;
// The _enabled guard is defensive: disableInteractive() (setEnabled)
// should already stop pointerover from firing at all, but it doesn't
// retroactively fire a pointerout for a button disabled mid-hover, so
// this also covers that case if Phaser's input plugin ever does
// still dispatch here regardless.
if (this._active || this._enabled === false) return;
const { scheme: s, variant: v } = this.options;
if (v === 'ghost') {
this._drawBg(s.glow, 0.22);
@ -123,7 +142,7 @@ export class Button extends Phaser.GameObjects.Container {
this._drawBrackets(true);
};
const onOut = () => {
if (this._active) return;
if (this._active || this._enabled === false) return;
const { bg: b, textColor: tc, variant: v } = this.options;
this._drawBg(b, v === 'ghost' ? GHOST_ALPHA : 1);
this.text.setColor(tc);
@ -167,13 +186,14 @@ export class Button extends Phaser.GameObjects.Container {
_drawBg(fillColor, fillAlpha) {
const { scheme } = this.options;
const strokeColor = this._enabled === false ? DISABLED_GLOW : scheme.glow;
const pts = this._chamferPoints();
this.bgRect.clear();
if (fillAlpha > 0) {
this.bgRect.fillStyle(fillColor, fillAlpha);
this.bgRect.fillPoints(pts, true);
}
this.bgRect.lineStyle(2, scheme.glow, 1);
this.bgRect.lineStyle(2, strokeColor, 1);
this.bgRect.strokePoints(pts, true);
this.fxMaskShape.clear();
@ -335,9 +355,28 @@ export class Button extends Phaser.GameObjects.Container {
}
setEnabled(enabled) {
this.setAlpha(enabled ? 1 : 0.5);
if (enabled) this.setInteractive({ useHandCursor: true });
else this.disableInteractive();
this._enabled = enabled;
if (!enabled) {
// Force out of any in-progress hover animation rather than trust
// that disableInteractive() alone will — it stops FUTURE pointer
// events, but a button disabled mid-hover never gets a pointerout
// to unwind whatever onOver already started.
this._stopShimmer();
this._stopBorderLights();
this._drawBrackets(false);
this._glowFx.color = DISABLED_GLOW;
const { bg, variant } = this.options;
this._drawBg(bg, variant === 'ghost' ? GHOST_ALPHA : 1);
this.text.setColor(DISABLED_TEXT);
this.disableInteractive();
} else {
this._glowFx.color = this.options.scheme.glow;
const { bg, textColor, variant } = this.options;
this._drawBg(bg, variant === 'ghost' ? GHOST_ALPHA : 1);
this.text.setColor(textColor);
this.setInteractive({ useHandCursor: true });
}
this.setAlpha(enabled ? 1 : 0.65);
return this;
}
}