UNPKG

mai3-phaser-sdk

Version:

A UI component library based on the Phaser game engine

289 lines (288 loc) 12.3 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 __()); }; })(); import Phaser from 'phaser'; import { Container } from './Container'; import { Label } from './Label'; var TextBox = /** @class */ (function (_super) { __extends(TextBox, _super); function TextBox(scene, config) { var _a, _b, _c; var _this = _super.call(this, scene, config, 'TextBox') || this; _this.charWidths = []; _this.isSelecting = false; _this._config = config; _this.isFocus = false; _this.maxWidth = (_a = config.width) !== null && _a !== void 0 ? _a : 100; _this.label = new Label(scene, config); _this.label.Text = (_b = config.text) !== null && _b !== void 0 ? _b : ''; _this.label.setPosition(0, 0); _this.addChildAt(_this.label, 0); _this.cursor = scene.make.text({ style: { color: '#383838', fontSize: (_c = config.textStyle) === null || _c === void 0 ? void 0 : _c.fontSize } }); _this.cursor.text = "|"; _this.cursor.setOrigin(0); _this.cursor.x = _this.label.TextWidth; _this.cursor.y = (_this.label.RealHeight - _this.cursor.displayHeight) / 2; _this.cursor.setVisible(false); _this.addChildAt(_this.cursor, 1); _this.selection = scene.add.rectangle(0, 0, 0, 0, 0xEE6363, 0.5); _this.selection.setOrigin(0); _this.selection.y = _this.cursor.y; _this.selection.height = _this.cursor.displayHeight; _this.addChildAt(_this.selection, 1); _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('keyup', _this.handleKeyup, _this); } _this.createHiddenInput(); return _this; } TextBox.prototype.handleKeyup = function (event) { if (!this.isFocus) return; if (event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'Backspace') { this.handleMoveCursor(); } }; TextBox.prototype.getCursorPosition = function () { var _a, _b; return (_b = (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.selectionStart) !== null && _b !== void 0 ? _b : 0; }; TextBox.prototype.createHiddenInput = function () { var _this = this; this.hiddenInput = document.createElement('input'); this.hiddenInput.type = 'text'; this.hiddenInput.style.position = 'absolute'; this.hiddenInput.style.opacity = '0'; this.hiddenInput.style.pointerEvents = 'none'; this.hiddenInput.style.zIndex = '-1'; this.hiddenInput.style.top = '-1000px'; // 将隐藏输入框移到屏幕外 this.hiddenInput.value = this.label.Text; document.body.appendChild(this.hiddenInput); this.hiddenInput.addEventListener('input', function () { var _a, _b; var newText = (_b = (_a = _this.hiddenInput) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''; if (_this.getTextWidth(newText) <= _this.maxWidth) { _this.label.Text = newText; _this.updateCursorPosition(); } else { _this.hiddenInput.value = _this.label.Text; } _this.updateSelectionAfterInput(); }); }; TextBox.prototype.getTextWidth = function (text) { var _a; if (!TextBox.measureCanvas) { TextBox.measureCanvas = (_a = this.scene.game.canvas) !== null && _a !== void 0 ? _a : document.createElement('canvas'); TextBox.measureContext = TextBox.measureCanvas.getContext('2d'); } var context = TextBox.measureContext; if (!context) { console.error('无法获取2D上下文'); return 0; } var fontSize = this.label.Label.style.fontSize || '16px'; var fontFamily = this.label.Label.style.fontFamily || 'Arial'; context.font = "".concat(fontSize, " ").concat(fontFamily); return context.measureText(text).width; }; TextBox.prototype.updateSelectionAfterInput = function () { var _a; if (this.hiddenInput) { var cursorPosition = (_a = this.hiddenInput.selectionStart) !== null && _a !== void 0 ? _a : 0; this.selectionStart = cursorPosition; this.selectionEnd = cursorPosition; this.selection.width = 0; this.selection.setVisible(false); this.updateCursorPosition(); this.cursor.setVisible(true); } }; TextBox.prototype.handleOver = function () { this.scene.input.setDefaultCursor('text'); }; TextBox.prototype.handleOut = function () { this.scene.input.setDefaultCursor('default'); }; TextBox.prototype.handlePointerDown = function (pointer) { var _a; this.isFocus = true; (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.focus(); var worldPoint = this.getLabelWorldPoint(); var cursorX = pointer.x - worldPoint.x; if (cursorX > this.label.TextWidth) { cursorX = this.label.TextWidth; } this.cursor.x = cursorX; this.cursor.setVisible(true); this.selection.width = 0; this.selection.setVisible(false); this.setDomCursorPosition(); this.setNativeCursorPosition(); this.selection.x = this.cursor.x; this.selectionStart = this.getCursorPosition(); this.selectionEnd = this.selectionStart; this.isSelecting = true; this.addTimerEvent(); }; TextBox.prototype.handlePointerMove = function (pointer) { if (!this.isSelecting) return; var worldPoint = this.getLabelWorldPoint(); var cursorX = pointer.x - worldPoint.x; if (cursorX > this.label.TextWidth) { cursorX = this.label.TextWidth; } if (cursorX < 0) { cursorX = 0; } this.selectionEnd = this.getCharacterIndexAtPosition(cursorX); this.updateSelection(); }; TextBox.prototype.handlePointerUp = function () { this.isSelecting = false; if (this.selectionStart === this.selectionEnd) { this.selection.setVisible(false); } }; TextBox.prototype.updateCursorPosition = function () { var _a, _b; var cursorPosition = (_b = (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.selectionStart) !== null && _b !== void 0 ? _b : 0; this.cursor.x = this.getCharacterXPosition(cursorPosition); }; TextBox.prototype.updateSelection = function () { var _a; if (this.selectionStart === undefined || this.selectionEnd === undefined) return; var start = Math.min(this.selectionStart, this.selectionEnd); var end = Math.max(this.selectionStart, this.selectionEnd); var startX = this.getCharacterXPosition(start); var endX = this.getCharacterXPosition(end); this.selection.x = startX; this.selection.width = endX - startX; this.selection.setVisible(true); this.cursor.x = endX; this.cursor.setVisible(true); (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.setSelectionRange(start, end); }; TextBox.prototype.handleMoveCursor = function () { this.setNativeCursorPosition(); }; TextBox.prototype.setDomCursorPosition = function () { var _a; if (this.cursor.x > this.label.TextWidth) { this.cursor.x = this.label.TextWidth; } var characterIndex = this.getCharacterIndexAtPosition(this.cursor.x); (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.setSelectionRange(characterIndex, characterIndex); }; TextBox.prototype.setNativeCursorPosition = function () { var characterIndex = this.getCursorPosition(); var characterX = this.getCharacterXPosition(characterIndex); this.cursor.x = characterX; this.cursor.setVisible(true); }; TextBox.prototype.getCharacterIndexAtPosition = function (x) { var _a; this.charWidths = this.getCharacterWidths(); var accumulatedWidth = 0; for (var i = 0; i < this.label.Text.length; i++) { accumulatedWidth += (_a = this.charWidths[i]) !== null && _a !== void 0 ? _a : 0; if (x < accumulatedWidth) { return i; } } return this.label.Text.length; }; TextBox.prototype.getCharacterWidths = function () { var _a, _b; if (!TextBox.measureCanvas) { TextBox.measureCanvas = document.createElement('canvas'); TextBox.measureContext = TextBox.measureCanvas.getContext('2d'); } var context = TextBox.measureContext; if (!context) { console.error('无法获取2D上下文'); return []; } var fontSize = this.label.Label.style.fontSize || '16px'; var fontFamily = this.label.Label.style.fontFamily || 'Arial'; context.font = "".concat(fontSize, " ").concat(fontFamily); var charWidths = []; var text = (_b = (_a = this.hiddenInput) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''; for (var i = 0; i < text.length; i++) { var char = text[i]; var charWidth = context.measureText(char).width; charWidths.push(charWidth); } return charWidths; }; TextBox.prototype.getCharacterXPosition = function (index) { var _a; var charWidths = this.getCharacterWidths(); index = Math.min(index, charWidths.length); var x = 0; for (var i = 0; i < index; i++) { x += (_a = charWidths[i]) !== null && _a !== void 0 ? _a : 0; } return x; }; TextBox.prototype.addTimerEvent = function () { var _this = this; if (this.timerEvent) return; this.timerEvent = this.scene.time.addEvent({ delay: 800, callback: function () { _this.cursor.visible = !_this.cursor.visible; }, callbackScope: this, loop: true }); }; TextBox.prototype.getLabelWorldPoint = function () { var worldPoint = new Phaser.Math.Vector2(); var transformMatrix = this.label.getWorldTransformMatrix(); transformMatrix.transformPoint(this.label.x, this.label.y, worldPoint); return worldPoint; }; TextBox.prototype.destroy = function (fromScene) { var _a, _b; this.label.destroy(fromScene); this.cursor.destroy(fromScene); (_a = this.timerEvent) === null || _a === void 0 ? void 0 : _a.remove(); (_b = this.timerEvent) === null || _b === void 0 ? void 0 : _b.destroy(); if (this.hiddenInput) { this.hiddenInput.remove(); } _super.prototype.destroy.call(this, fromScene); }; TextBox.measureCanvas = null; TextBox.measureContext = null; return TextBox; }(Container)); export { TextBox };