UNPKG

@mai3/phaser-sdk

Version:

A UI component library based on the Phaser game engine

187 lines (186 loc) 8.35 kB
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 };