make buttons html again

This commit is contained in:
Ryan Barlow
2026-01-03 20:52:49 +00:00
parent f7fc652026
commit 342a712ddc
5 changed files with 39 additions and 84 deletions
-10
View File
@@ -451,10 +451,6 @@ export class InputHandler {
}
private onPointerDown(event: PointerEvent) {
if (this.uiState.overGhostControls) {
return;
}
if (event.button === 1) {
event.preventDefault();
this.eventBus.emit(new AutoUpgradeEvent(event.clientX, event.clientY));
@@ -482,12 +478,6 @@ export class InputHandler {
}
onPointerUp(event: PointerEvent) {
if (this.uiState.overGhostControls) {
this.pointerDown = false;
this.pointers.clear();
return;
}
if (event.button === 1) {
event.preventDefault();
return;
-1
View File
@@ -55,7 +55,6 @@ export function createRenderer(
ghostStructure: null,
rocketDirectionUp: true,
lockedGhostTile: null,
overGhostControls: false,
} as UIState;
//hide when the game renders
-1
View File
@@ -6,5 +6,4 @@ export interface UIState {
ghostStructure: UnitType | null;
rocketDirectionUp: boolean;
lockedGhostTile: TileRef | null;
overGhostControls: boolean;
}
@@ -87,10 +87,10 @@ export class StructureIconsLayer implements Layer {
private renderSprites = true;
private factory: SpriteFactory;
private ghostControls: {
container: PIXI.Container;
confirm: PIXI.Graphics;
cancel: PIXI.Graphics;
flip: PIXI.Graphics;
container: HTMLDivElement;
confirm: HTMLButtonElement;
cancel: HTMLButtonElement;
flip: HTMLButtonElement;
} | null = null;
private readonly structures: Map<UnitType, { visible: boolean }> = new Map([
[UnitType.City, { visible: true }],
@@ -603,91 +603,63 @@ export class StructureIconsLayer implements Layer {
private ensureGhostControls() {
if (this.ghostControls) return;
const container = new PIXI.Container();
this.ghostStage.addChild(container);
const buttonSize = 48;
const gap = 8;
const buttonRadius = 6;
const container = document.createElement("div");
// Fixed positioning keeps controls anchored to the viewport even if the page scrolls
container.style.position = "fixed";
container.style.display = "flex";
container.style.gap = "8px";
container.style.transform = "translate(-50%, 0)";
container.style.pointerEvents = "auto";
container.style.zIndex = "5";
const makeButton = (
label: string,
color: number,
x: number,
background: string,
onClick: () => void,
): PIXI.Graphics => {
const button = new PIXI.Graphics();
button.beginFill(color);
button.drawRoundedRect(0, 0, buttonSize, buttonSize, buttonRadius);
button.endFill();
button.x = x;
button.y = 0;
button.eventMode = "static";
button.cursor = "pointer";
// Add text label
const text = new PIXI.Text(label, {
fontFamily: "Arial",
fontSize: 24,
fontWeight: "bold",
fill: 0xffffff,
});
text.anchor.set(0.5);
text.x = buttonSize / 2;
text.y = buttonSize / 2;
button.addChild(text);
// Hover effects
button.on("pointerover", () => {
this.uiState.overGhostControls = true;
button.tint = 0xdddddd;
});
button.on("pointerout", () => {
this.uiState.overGhostControls = false;
button.tint = 0xffffff;
});
button.on("pointerdown", () => {
this.uiState.overGhostControls = true;
button.tint = 0xaaaaaa;
});
button.on("pointerup", () => {
this.uiState.overGhostControls = false;
button.tint = 0xffffff;
});
button.on("pointertap", (e) => {
e.stopPropagation();
this.uiState.overGhostControls = false;
onClick();
});
): HTMLButtonElement => {
const button = document.createElement("button");
button.type = "button";
button.textContent = label;
button.style.minHeight = "48px";
button.style.minWidth = "48px";
button.style.padding = "8px 16px";
button.style.borderRadius = "6px";
button.style.border = "none";
button.style.fontWeight = "700";
button.style.fontSize = "13px";
button.style.color = "#ffffff";
button.style.background = background;
button.style.cursor = "pointer";
button.style.boxShadow = "0 2px 6px rgba(0,0,0,0.25)";
button.style.whiteSpace = "nowrap";
button.addEventListener("click", onClick);
return button;
};
const confirm = makeButton("✓", 0x2e7d32, 0, () => {
const confirm = makeButton("✓", "#2e7d32", () => {
if (this.uiState.lockedGhostTile) {
this.emitBuildIntent(this.uiState.lockedGhostTile);
}
});
const flip = makeButton("↕", 0x1565c0, buttonSize + gap, () => {
const flip = makeButton("↕", "#1565c0", () => {
const next = !this.uiState.rocketDirectionUp;
this.eventBus.emit(new SwapRocketDirectionEvent(next));
});
const cancel = makeButton("✕", 0xb71c1c, (buttonSize + gap) * 2, () =>
const cancel = makeButton("✕", "#b71c1c", () =>
this.removeGhostStructure(),
);
container.addChild(confirm, flip, cancel);
container.append(confirm, flip, cancel);
document.body.appendChild(container);
this.ghostControls = { container, confirm, cancel, flip };
}
private destroyGhostControls() {
if (!this.ghostControls) return;
this.uiState.overGhostControls = false;
this.ghostControls.container.destroy({ children: true });
this.ghostControls.container.remove();
this.ghostControls = null;
}
@@ -713,13 +685,9 @@ export class StructureIconsLayer implements Layer {
0.75,
Math.min(1.4, this.transformHandler.scale / 2),
);
// Position PIXI container in world coordinates
const buttonWidth = 48;
const totalWidth = buttonWidth * 3 + 8 * 2; // 3 buttons + 2 gaps
this.ghostControls!.container.x = localX - totalWidth / 2;
this.ghostControls!.container.y = localY + offsetY;
this.ghostControls!.container.scale.set(scale);
this.ghostControls!.container.style.left = `${rect.left + localX}px`;
this.ghostControls!.container.style.top = `${rect.top + localY + offsetY}px`;
this.ghostControls!.container.style.transform = `translate(-50%, 0) scale(${scale})`;
}
private resolveGhostRangeLevel(
-1
View File
@@ -39,7 +39,6 @@ describe("InputHandler AutoUpgrade", () => {
ghostStructure: null,
rocketDirectionUp: true,
lockedGhostTile: null,
overGhostControls: false,
},
mockCanvas,
eventBus,