Files
Foundry-VTT-Docker/resources/app/client/pixi/layers/grid/layer.js

302 lines
9.0 KiB
JavaScript
Raw Normal View History

2025-01-04 00:34:03 +01:00
/**
* A CanvasLayer responsible for drawing a square grid
*/
class GridLayer extends CanvasLayer {
/**
* The grid mesh.
* @type {GridMesh}
*/
mesh;
/**
* The Grid Highlight container
* @type {PIXI.Container}
*/
highlight;
/**
* Map named highlight layers
* @type {Record<string, GridHighlight>}
*/
highlightLayers = {};
/* -------------------------------------------- */
/** @inheritdoc */
static get layerOptions() {
return foundry.utils.mergeObject(super.layerOptions, {name: "grid"});
}
/* -------------------------------------------- */
/** @override */
async _draw(options) {
// Draw the highlight layer
this.highlightLayers = {};
this.highlight = this.addChild(new PIXI.Container());
this.highlight.sortableChildren = true;
// Draw the grid
this.mesh = this.addChild(await this._drawMesh());
// Initialize the mesh appeareance
this.initializeMesh(canvas.grid);
}
/* -------------------------------------------- */
/**
* Creates the grid mesh.
* @returns {Promise<GridMesh>}
* @protected
*/
async _drawMesh() {
return new GridMesh().initialize({
type: canvas.grid.type,
width: canvas.dimensions.width,
height: canvas.dimensions.height,
size: canvas.dimensions.size
});
}
/* -------------------------------------------- */
/**
* Initialize the grid mesh appearance and configure the grid shader.
* @param {object} options
* @param {string} [options.style] The grid style
* @param {number} [options.thickness] The grid thickness
* @param {string} [options.color] The grid color
* @param {number} [options.alpha] The grid alpha
*/
initializeMesh({style, thickness, color, alpha}) {
const {shaderClass, shaderOptions} = CONFIG.Canvas.gridStyles[style] ?? {};
this.mesh.initialize({thickness, color, alpha});
this.mesh.setShaderClass(shaderClass ?? GridShader);
this.mesh.shader.configure(shaderOptions ?? {});
}
/* -------------------------------------------- */
/* Grid Highlighting Methods
/* -------------------------------------------- */
/**
* Define a new Highlight graphic
* @param {string} name The name for the referenced highlight layer
*/
addHighlightLayer(name) {
const layer = this.highlightLayers[name];
if ( !layer || layer._destroyed ) {
this.highlightLayers[name] = this.highlight.addChild(new GridHighlight(name));
}
return this.highlightLayers[name];
}
/* -------------------------------------------- */
/**
* Clear a specific Highlight graphic
* @param {string} name The name for the referenced highlight layer
*/
clearHighlightLayer(name) {
const layer = this.highlightLayers[name];
if ( layer ) layer.clear();
}
/* -------------------------------------------- */
/**
* Destroy a specific Highlight graphic
* @param {string} name The name for the referenced highlight layer
*/
destroyHighlightLayer(name) {
const layer = this.highlightLayers[name];
if ( layer ) {
this.highlight.removeChild(layer);
layer.destroy();
}
}
/* -------------------------------------------- */
/**
* Obtain the highlight layer graphic by name
* @param {string} name The name for the referenced highlight layer
*/
getHighlightLayer(name) {
return this.highlightLayers[name];
}
/* -------------------------------------------- */
/**
* Add highlighting for a specific grid position to a named highlight graphic
* @param {string} name The name for the referenced highlight layer
* @param {object} [options] Options for the grid position that should be highlighted
* @param {number} [options.x] The x-coordinate of the highlighted position
* @param {number} [options.y] The y-coordinate of the highlighted position
* @param {PIXI.ColorSource} [options.color=0x33BBFF] The fill color of the highlight
* @param {PIXI.ColorSource|null} [options.border=null] The border color of the highlight
* @param {number} [options.alpha=0.25] The opacity of the highlight
* @param {PIXI.Polygon} [options.shape=null] A predefined shape to highlight
*/
highlightPosition(name, {x, y, color=0x33BBFF, border=null, alpha=0.25, shape=null}) {
const layer = this.highlightLayers[name];
if ( !layer ) return;
const grid = canvas.grid;
if ( grid.type !== CONST.GRID_TYPES.GRIDLESS ) {
const cx = x + (grid.sizeX / 2);
const cy = y + (grid.sizeY / 2);
const points = grid.getShape();
for ( const point of points ) {
point.x += cx;
point.y += cy;
}
shape = new PIXI.Polygon(points);
} else if ( !shape ) return;
if ( !layer.highlight(x, y) ) return;
layer.beginFill(color, alpha);
if ( border !== null ) layer.lineStyle(2, border, Math.min(alpha * 1.5, 1.0));
layer.drawShape(shape).endFill();
}
/* -------------------------------------------- */
/* Deprecations and Compatibility */
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get type() {
const msg = "GridLayer#type is deprecated. Use canvas.grid.type instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.type;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get size() {
const msg = "GridLayer#size is deprecated. Use canvas.grid.size instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.size;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get grid() {
const msg = "GridLayer#grid is deprecated. Use canvas.grid instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
isNeighbor(r0, c0, r1, c1) {
const msg = "GridLayer#isNeighbor is deprecated. Use canvas.grid.testAdjacency instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.testAdjacency({i: r0, j: c0}, {i: r1, j: c1});
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get w() {
const msg = "GridLayer#w is deprecated in favor of canvas.grid.sizeX.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.sizeX;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get h() {
const msg = "GridLayer#h is deprecated in favor of canvas.grid.sizeY.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.sizeY;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
get isHex() {
const msg = "GridLayer#isHex is deprecated. Use canvas.grid.isHexagonal instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.isHexagonal;
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
getTopLeft(x, y) {
const msg = "GridLayer#getTopLeft is deprecated. Use canvas.grid.getTopLeftPoint instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.getTopLeft(x, y);
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
getCenter(x, y) {
const msg = "GridLayer#getCenter is deprecated. Use canvas.grid.getCenterPoint instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
return canvas.grid.getCenter(x, y);
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
getSnappedPosition(x, y, interval=1, options={}) {
const msg = "GridLayer#getSnappedPosition is deprecated. Use canvas.grid.getSnappedPoint instead.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
if ( interval === 0 ) return {x: Math.round(x), y: Math.round(y)};
return canvas.grid.getSnappedPosition(x, y, interval, options);
}
/* -------------------------------------------- */
/**
* @deprecated since v12
* @ignore
*/
measureDistance(origin, target, options={}) {
const msg = "GridLayer#measureDistance is deprecated. "
+ "Use canvas.grid.measurePath instead for non-Euclidean measurements.";
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
const ray = new Ray(origin, target);
const segments = [{ray}];
return canvas.grid.measureDistances(segments, options)[0];
}
}