@mai3/phaser-sdk
Version:
A UI component library based on the Phaser game engine
187 lines (186 loc) • 8.35 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { Label } from './Label';
import { TextBox } from './TextBox';
var TextArea = /** @class */ (function (_super) {
__extends(TextArea, _super);
function TextArea(scene, config) {
var _a, _b, _c;
var _this = _super.call(this, scene, config) || this;
_this.charWidths = [];
_this.isSelecting = false;
_this._config = config;
_this.isFocus = false;
_this.maxWidth = (_a = config.width) !== null && _a !== void 0 ? _a : 100;
_this.maxHeight = (_b = config.height) !== null && _b !== void 0 ? _b : 100;
_this.lineHeight = ((_c = config.textStyle) === null || _c === void 0 ? void 0 : _c.fontSize) ?
parseInt(config.textStyle.fontSize.toString()) : 16;
_this.createMultilineLabel();
_this.setEventInteractive();
_this.on('pointerover', _this.handleOver, _this);
_this.on('pointerout', _this.handleOut, _this);
_this.on('pointerup', _this.handlePointerUp, _this);
_this.on('pointerdown', _this.handlePointerDown, _this);
_this.on('pointermove', _this.handlePointerMove, _this);
if (scene.input.keyboard) {
scene.input.keyboard.on('keydown', _this.handleKeyDown, _this);
}
_this.createHiddenTextArea();
return _this;
}
TextArea.prototype.createMultilineLabel = function () {
this.label.destroy();
this.label = new Label(this.scene, __assign(__assign({}, this._config), { height: this.maxHeight, isWordWrap: true, autoHeight: true }));
this.label.setPosition(0, 0);
this.addChildAt(this.label, 0);
};
TextArea.prototype.handleKeyDown = function (event) {
var _this = this;
if (!this.isFocus)
return;
if (event.key === 'Enter') {
event.preventDefault();
this.insertTextAtCursor('\n');
}
else if (event.key === 'ArrowUp' || event.key === 'ArrowDown' ||
event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
setTimeout(function () { return _this.updateCursorPosition(); }, 0);
}
else {
_super.prototype.handleKeyup.call(this, event);
}
this.updateTextFromTextArea();
};
TextArea.prototype.createHiddenTextArea = function () {
var _this = this;
this.hiddenTextArea = document.createElement('textarea');
this.hiddenTextArea.style.position = 'absolute';
this.hiddenTextArea.style.opacity = '0';
this.hiddenTextArea.style.pointerEvents = 'none';
this.hiddenTextArea.style.zIndex = '-1';
this.hiddenTextArea.value = this.label.Text;
document.body.appendChild(this.hiddenTextArea);
this.hiddenTextArea.addEventListener('input', function () {
_this.updateTextFromTextArea();
});
};
TextArea.prototype.updateTextFromTextArea = function () {
if (this.hiddenTextArea) {
this.label.Text = this.hiddenTextArea.value;
this.updateCursorPosition();
}
};
TextArea.prototype.getCursorPosition = function () {
var _a, _b;
return (_b = (_a = this.hiddenTextArea) === null || _a === void 0 ? void 0 : _a.selectionStart) !== null && _b !== void 0 ? _b : 0;
};
TextArea.prototype.setCursorPosition = function (position) {
var _a;
(_a = this.hiddenTextArea) === null || _a === void 0 ? void 0 : _a.setSelectionRange(position, position);
this.updateCursorPosition();
};
TextArea.prototype.updateCursorPosition = function () {
var cursorPosition = this.getCursorPosition();
var lines = this.label.Text.split('\n');
var currentLineIndex = 0;
var accumulatedLength = 0;
for (var i = 0; i < lines.length; i++) {
if (cursorPosition <= accumulatedLength + lines[i].length) {
currentLineIndex = i;
break;
}
accumulatedLength += lines[i].length + 1; // +1 for newline character
}
var offsetInLine = cursorPosition - accumulatedLength;
this.cursor.x = this.getCharacterXPosition(offsetInLine, lines[currentLineIndex]);
this.cursor.y = currentLineIndex * this.lineHeight;
// 确保光标在可见区域内
if (this.cursor.y + this.cursor.height > this.maxHeight) {
this.label.y = this.maxHeight - (this.cursor.y + this.cursor.height);
}
else if (this.cursor.y < 0) {
this.label.y = -this.cursor.y;
}
// 如果光标在文本末尾,确保光标位置在文本框的末尾
if (cursorPosition === this.hiddenTextArea.value.length) {
this.cursor.x = this.label.width;
}
};
TextArea.prototype.getCharacterXPosition = function (index, line) {
if (line === undefined) {
return _super.prototype.getCharacterXPosition.call(this, index);
}
var textStyle = this.label.Label.style;
var context = this.scene.sys.game.canvas.getContext('2d');
if (context) {
context.font = "".concat(textStyle.fontSize, "px ").concat(textStyle.fontFamily);
return context.measureText(line.substring(0, index)).width;
}
return 0;
};
TextArea.prototype.insertTextAtCursor = function (text) {
var cursorPosition = this.getCursorPosition();
var currentText = this.hiddenTextArea.value;
var newText = currentText.slice(0, cursorPosition) + text + currentText.slice(cursorPosition);
this.hiddenTextArea.value = newText;
this.setCursorPosition(cursorPosition + text.length);
this.updateTextFromTextArea();
};
TextArea.prototype.handlePointerDown = function (pointer) {
if (this.isFocus) {
var localX = this.label.x + this.label.getBounds().left;
var localY = this.label.y + this.label.getBounds().top;
var cursorX = pointer.x - localX;
var cursorY = pointer.y - localY;
var lines = this.label.Text.split('\n');
var currentLineIndex = Math.floor(cursorY / this.lineHeight);
if (currentLineIndex >= lines.length) {
currentLineIndex = lines.length - 1;
}
var line = lines[currentLineIndex];
var offsetInLine = Math.floor(this.getCharacterXPosition(cursorX, line));
// 如果点击位置超过当前行的长度,将光标设置在行尾
if (offsetInLine > line.length) {
offsetInLine = line.length;
}
var cursorPosition = 0;
for (var i = 0; i < currentLineIndex; i++) {
cursorPosition += lines[i].length + 1; // +1 for newline character
}
cursorPosition += offsetInLine;
this.setCursorPosition(cursorPosition);
}
};
TextArea.prototype.destroy = function (fromScene) {
if (this.hiddenTextArea) {
document.body.removeChild(this.hiddenTextArea);
}
_super.prototype.destroy.call(this, fromScene);
};
return TextArea;
}(TextBox));
export { TextArea };