import * as PIXI from 'pixi.js'; const DEFAULT_LINE_STYLE = { width: 1, color: 0xffffff, alpha: 1, alignment: 0.5, native: true, }; export class AxGrid extends PIXI.Graphics { private _cellSize: number; private _correctedWidth: number; private _gridWidth: number; private _useCorrectedWidth: boolean; private _drawBoundaries: any; private _amtLines: any; set cellSize(cellSize) { this._cellSize = cellSize || Math.sqrt(this._correctedWidth); } get cellSize() { return this._cellSize; } get amtLines() { return Math.floor(this.gridWidth / this.cellSize); } get originalWidth() { return this._gridWidth; } /** * 修正后的网格宽度,大于最小平方根的数 */ get correctedWidth() { return this._correctedWidth; } get useCorrectedWidth() { return this._useCorrectedWidth; } /** * 网格中每个角落的坐标。 */ get bounds() { return { x1: this.x, y1: this.y, x2: this.x + this._correctedWidth, y2: this.y + this._correctedWidth, }; } set drawBoundaries(drawBoundaries) { this._drawBoundaries = drawBoundaries; } get drawBoundaries() { return this._drawBoundaries; } get gridWidth() { if (!this.useCorrectedWidth) { return this._gridWidth; } return Math.abs(this.cellSize - Math.sqrt(this._correctedWidth)) <= 1e-6 ? this._correctedWidth : this._gridWidth; } constructor( width, cellSize= null, lineConfig = null, useCorrectedWidth = true, drawBoundaries = true, ) { super(); this._cellSize = null; this._amtLines = null; this._gridWidth = width; this._useCorrectedWidth = useCorrectedWidth; this._correctedWidth = null; this._correctWidth(); this._drawBoundaries = drawBoundaries; this.cellSize = cellSize; const lConfig = { ...DEFAULT_LINE_STYLE, ...(lineConfig || {} )}; this.lineStyle( lConfig.width, lConfig.color, lConfig.alpha, lConfig.alignment, lConfig.native ); this.interactive = true; this.on('mousemove', (evt) => { const mouseCoords = evt.data.getLocalPosition(evt.currentTarget.parent); if ( mouseCoords.x >= this.bounds.x1 && mouseCoords.x <= this.bounds.x2 && mouseCoords.y >= this.bounds.y1 && mouseCoords.y <= this.bounds.y2 ) { const gridCoords = this.getCellCoordinates(mouseCoords.x, mouseCoords.y); this.onMousemove(evt, gridCoords); } }); } /** * 绘制网格 */ drawGrid() { this.clearGrid(true); for (let i = (this._drawBoundaries ? 0 : 1); i <= this.amtLines - (this._drawBoundaries ? 0 : 1); i += 1) { const startCoord = i * this._cellSize; // 画列 this.moveTo(startCoord, 0); this.lineTo(startCoord, this._correctedWidth); // 画行 this.moveTo(0, startCoord); this.lineTo(this._correctedWidth, startCoord); } this.endFill(); return this; } /** * 清除网格 */ clearGrid(retainLineStyle = true) { const { width, alignment, color, alpha, native } = this.line; this.clear(); if (!retainLineStyle) { return; } this.lineStyle(width, color, alpha, alignment, native); return this; } /** * 返回网格的坐标 * @param x 坐标x * @param y 坐标y */ getCellCoordinates(x, y) { return { x: Math.floor((x - this.bounds.x1) / this.cellSize), y: Math.floor((y - this.bounds.y1) / this.cellSize), }; } /** * 鼠标移动事件 * @param evt 鼠标事件 * @param gridCoords 鼠标所在网格坐标 */ onMousemove(evt, gridCoords) { } // 默认宽度 _correctWidth() { if (!this._useCorrectedWidth) { this._correctedWidth = this._gridWidth; } this._correctedWidth = Math.ceil(Math.sqrt(this._gridWidth)) ** 2; } // 自定义宽度 correctWidth(width: number) { if (!this._useCorrectedWidth) { this._correctedWidth = width; } this._correctedWidth = Math.ceil(Math.sqrt(width)) ** 2; this.cellSize = null; } }