You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.0 KiB
260 lines
7.0 KiB
4 years ago
|
import * as PIXI from 'pixi.js';
|
||
|
|
||
|
const DEFAULT_LINE_STYLE = {
|
||
|
width: 1,
|
||
|
color: 0xffffff,
|
||
|
alpha: 1,
|
||
|
alignment: 0.5,
|
||
|
native: true,
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @description 在屏幕上绘制网格的实用程序类。
|
||
|
* @extends PIXI.Graphics
|
||
|
*/
|
||
|
export class AxGrid extends PIXI.Graphics {
|
||
|
private _cellSize: number;
|
||
|
private _correctedWidth: number;
|
||
|
private _gridWidth: number;
|
||
|
private _useCorrectedWidth: boolean;
|
||
|
private _drawBoundaries: any;
|
||
|
private _amtLines: any;
|
||
|
/**
|
||
|
* @param {number} cellSize 默认值:网格边长的平方根
|
||
|
*/
|
||
|
set cellSize(cellSize) {
|
||
|
this._cellSize = cellSize || Math.sqrt(this._correctedWidth);
|
||
|
}
|
||
|
|
||
|
get cellSize() {
|
||
|
return this._cellSize;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 网格边等距线的数量
|
||
|
*/
|
||
|
get amtLines() {
|
||
|
return Math.floor(this.gridWidth / this.cellSize);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 由' width '构造函数参数给出的网格的请求宽度。
|
||
|
*/
|
||
|
get originalWidth() {
|
||
|
return this._gridWidth;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 修正后的网格宽度,即大于最小平方根的数
|
||
|
* 修正后的宽度。
|
||
|
*/
|
||
|
get correctedWidth() {
|
||
|
return this._correctedWidth;
|
||
|
}
|
||
|
|
||
|
get useCorrectedWidth() {
|
||
|
return this._useCorrectedWidth;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 网格中每个角落的坐标。
|
||
|
* @returns {{ x1: number, y1: number, x2: number, y2: number}}
|
||
|
* 最左边(**x1**),最上面(**y1**),最右边(**x2**)和最下面(**y2**)的坐标。
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 网格的实际宽度。
|
||
|
* 当' cellSize '不是默认值时,网格的宽度将为
|
||
|
* 在' width '构造函数中给出的宽度。否则,就是修改后的宽度。
|
||
|
*/
|
||
|
get gridWidth() {
|
||
|
if (!this.useCorrectedWidth) { return this._gridWidth; }
|
||
|
return Math.abs(this.cellSize - Math.sqrt(this._correctedWidth)) <= 1e-6 ? this._correctedWidth : this._gridWidth;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param {number} width number. Required.
|
||
|
*
|
||
|
* The target sidelength of the grid. It is best for `width` to be a perfect square (i.e., 2, 4, 9, 16, 25, etc.). If
|
||
|
* not and the parameter `useCorrectedWidth` is set to **false**, then the grid will use a corrected width,
|
||
|
* which is the smallest perfect square greater than `width`.
|
||
|
*
|
||
|
* @param {number} cellSize number, null. Optional, default: square root of corrected width
|
||
|
*
|
||
|
* The size of each cell in the grid.
|
||
|
* If the value is **null**, the grid will use the default value.
|
||
|
*
|
||
|
* @param {{ width: number, color: number, alpha: number, alignment: number, native: boolean }}. Object. Optional.
|
||
|
*
|
||
|
* default:
|
||
|
* **{
|
||
|
* width: 1,
|
||
|
* color: 0xffffff,
|
||
|
* alpha: 1,
|
||
|
* alignment: 0.5,
|
||
|
* native: true
|
||
|
* }**
|
||
|
*
|
||
|
* Configuration for the line style on the object. See documentation on `PIXI.Graphics` for more on the `LineStyle` class.
|
||
|
*
|
||
|
* @param {boolean} useCorrectedWidth boolean. Optional. default: **true**
|
||
|
* If **true**, the grid will use the smallest perfect square greater than `width`.
|
||
|
* Otherwise, the grid will use the exact value given by `width`.
|
||
|
*
|
||
|
* @param {boolean} drawBoundaries boolean. Optional. default: **true**
|
||
|
* If **true**, the grid will draw its boundaries.
|
||
|
* Otherwise, the grid will not draw its boundaries. Mouse pointer detection is not affected.
|
||
|
*/
|
||
|
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
|
||
|
);
|
||
|
|
||
|
// handle mouse move
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 清除网格
|
||
|
*
|
||
|
* @param {boolean} retainLineStyle 可选,默认:true
|
||
|
*
|
||
|
* 当**true**时,线条样式对象的配置将被保留。
|
||
|
* 否则,对象的行样式将恢复为' PIXI '指定的默认值。图形的对象。
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Transforms global coordinates to grid coordinates.
|
||
|
* @param {number} x
|
||
|
* The global X coordinate.
|
||
|
*
|
||
|
* @param {number} y
|
||
|
* The global Y coordinate.
|
||
|
*/
|
||
|
getCellCoordinates(x, y) {
|
||
|
return {
|
||
|
x: Math.floor((x - this.bounds.x1) / this.cellSize),
|
||
|
y: Math.floor((y - this.bounds.y1) / this.cellSize),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 检测到mousemove事件后触发的回调。
|
||
|
*
|
||
|
* @param {PIXI.InteractionData} evt
|
||
|
* 'PIXI.InteractionData '事件
|
||
|
*
|
||
|
* @param {{x: number, y: number}} gridCoords
|
||
|
* 网格坐标
|
||
|
*/
|
||
|
onMousemove(evt, gridCoords) {
|
||
|
|
||
|
}
|
||
|
|
||
|
// 计算修正后的宽度。如果`useCorrectedWidth`构造函数参数设置为**false**,
|
||
|
// 然后,它简单地保持“width”的给定值作为修正后的宽度。
|
||
|
_correctWidth() {
|
||
|
if (!this._useCorrectedWidth) {
|
||
|
this._correctedWidth = this._gridWidth;
|
||
|
}
|
||
|
|
||
|
this._correctedWidth = Math.ceil(Math.sqrt(this._gridWidth)) ** 2;
|
||
|
}
|
||
|
|
||
|
// 计算修正后的宽度。如果`useCorrectedWidth`构造函数参数设置为**false**,
|
||
|
// 然后,它简单地保持“width”的给定值作为修正后的宽度。
|
||
|
correctWidth(width: number) {
|
||
|
if (!this._useCorrectedWidth) {
|
||
|
this._correctedWidth = width;
|
||
|
}
|
||
|
|
||
|
this._correctedWidth = Math.ceil(Math.sqrt(width)) ** 2;
|
||
|
this.cellSize = null;
|
||
|
}
|
||
|
}
|