ecspresso
Version:
A minimal Entity-Component-System library for typescript and javascript.
115 lines (114 loc) • 4.25 kB
TypeScript
/**
* Selection Plugin for ECSpresso
*
* Provides pointer-driven entity selection via box-drag and click.
* Entities with a `selectable` component can be selected by the user.
* Selected entities receive a `selected` component that other systems
* can query for.
*
* Requires the input plugin (for pointer state) and the renderer2D plugin
* (for graphics rendering of the selection box).
*
* Camera-aware: when a `cameraState` resource is present (from the camera
* plugin), pointer coordinates are automatically converted to world space
* for hit-testing. The selection box overlay remains in screen space.
*/
import { type BasePluginOptions } from 'ecspresso';
import type { ComponentsConfig, ResourcesConfig } from 'ecspresso';
import type { InputResourceTypes } from './input';
import type { Renderer2DComponentTypes, Renderer2DResourceTypes } from '../rendering/renderer2D';
/**
* Component types provided by the selection plugin.
*/
export interface SelectionComponentTypes {
/** Tag marking an entity as eligible for selection */
selectable: true;
/** Tag marking an entity as currently selected (added/removed dynamically) */
selected: true;
}
/**
* Internal state tracking the current drag selection.
*/
export interface SelectionState {
dragStart: {
x: number;
y: number;
};
boxEntityId: number | null;
}
/**
* Resource types provided by the selection plugin.
*/
export interface SelectionResourceTypes {
selectionState: SelectionState;
}
/**
* WorldConfig representing the selection plugin's provided types.
*/
export type SelectionWorldConfig = ComponentsConfig<SelectionComponentTypes> & ResourcesConfig<SelectionResourceTypes>;
type SelectionRequires = ComponentsConfig<Renderer2DComponentTypes> & ResourcesConfig<InputResourceTypes & Renderer2DResourceTypes>;
/**
* Configuration options for the selection plugin.
*/
export interface SelectionPluginOptions<G extends string = 'selection'> extends BasePluginOptions<G> {
/** Minimum drag distance (px) to trigger box select vs click select (default: 5) */
clickThreshold?: number;
/** Selection box fill color (default: 0x00FF00) */
boxFillColor?: number;
/** Selection box fill alpha (default: 0.15) */
boxFillAlpha?: number;
/** Selection box stroke color (default: 0x00FF00) */
boxStrokeColor?: number;
/** Selection box stroke alpha (default: 0.8) */
boxStrokeAlpha?: number;
/** Tint applied to selected entities' sprites (default: 0x44FF44) */
selectedTint?: number;
/** Render layer for the selection box entity (default: undefined) */
renderLayer?: string;
}
/**
* Create a selectable component.
*
* @returns Component object suitable for spreading into spawn()
*
* @example
* ```typescript
* ecs.spawn({
* ...createTransform(100, 200),
* sprite,
* ...createSelectable(),
* });
* ```
*/
export declare function createSelectable(): Pick<SelectionComponentTypes, 'selectable'>;
/**
* Create a selection plugin for ECSpresso.
*
* Provides:
* - Box-drag selection (left-click drag to select multiple entities)
* - Click selection (left-click to select a single entity)
* - Visual feedback (configurable sprite tint for selected entities)
* - Selection box overlay (rendered as a PixiJS Graphics entity)
* - Automatic camera-awareness when cameraState resource is present
*
* Requires the input plugin and renderer2D plugin to be installed.
*
* @example
* ```typescript
* const ecs = ECSpresso.create()
* .withPlugin(createRenderer2DPlugin({ renderLayers: ['game', 'ui'] }))
* .withPlugin(createInputPlugin())
* .withPlugin(createSelectionPlugin({ renderLayer: 'ui' }))
* .build();
*
* await ecs.initialize();
*
* ecs.spawn({
* sprite,
* ...createTransform(100, 200),
* ...createSelectable(),
* });
* ```
*/
export declare function createSelectionPlugin<G extends string = 'selection'>(options?: SelectionPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithResources<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, SelectionComponentTypes>, SelectionResourceTypes>, SelectionRequires, "selection-input" | "selection-visual", G, never, never>;
export {};