webtalekit-alpha 0.2.11 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DefaultUIHandler = void 0;
40
+ var DefaultUIHandler = /** @class */ (function () {
41
+ function DefaultUIHandler() {
42
+ }
43
+ /**
44
+ * 指定されたEventBusにDOM操作関連のイベントハンドラをすべて登録する。
45
+ *
46
+ * @param eventBus - 共有EventBusインスタンス
47
+ * @param drawer - Drawerインスタンス(キャンバス・テキスト描画)
48
+ * @param gameContainer - ゲームのルートコンテナ要素
49
+ * @param resolution - キャンバス初期化に使用するエンジン解像度
50
+ */
51
+ DefaultUIHandler.register = function (eventBus, drawer, gameContainer, resolution) {
52
+ var _this = this;
53
+ // ----------------------------------------------------------------
54
+ // screen:load
55
+ // テンプレートURLからHTMLを読み込み・パースしてDOMに注入する。
56
+ // 通常モードはgameContainerのinnerHTMLを置換し、drawer.setScreenを呼び出す。
57
+ // ダイアログモードはダイアログ要素を追加し、スタイルにマークを付ける。
58
+ // data.template — テンプレートファイルのURL
59
+ // data.isDialog — ダイアログモードかどうか
60
+ // data.fallbackTemplate — テンプレートが見つからない場合のフォールバック関数
61
+ // ----------------------------------------------------------------
62
+ eventBus.on('screen:load', function (data) { return __awaiter(_this, void 0, void 0, function () {
63
+ var template, isDialog, fallbackTemplate, htmlString, parser, doc, mainDiv, fallbackContent, wrapper, styleEl, styleElement, styleContent, styleTags, styleEl, existingDialog, styleEl;
64
+ return __generator(this, function (_a) {
65
+ switch (_a.label) {
66
+ case 0:
67
+ template = data.template, isDialog = data.isDialog, fallbackTemplate = data.fallbackTemplate;
68
+ return [4 /*yield*/, fetch(template)];
69
+ case 1: return [4 /*yield*/, (_a.sent()).text()];
70
+ case 2:
71
+ htmlString = _a.sent();
72
+ parser = new DOMParser();
73
+ doc = parser.parseFromString(htmlString, 'text/html');
74
+ mainDiv = isDialog
75
+ ? doc.getElementById('dialogContainer')
76
+ : doc.getElementById('main');
77
+ if (!mainDiv) {
78
+ // 対象要素が見つからない場合はフォールバックテンプレートを使用する
79
+ if (fallbackTemplate) {
80
+ console.warn('テンプレートにメイン要素が見つからないため、フォールバックを使用します');
81
+ fallbackContent = fallbackTemplate();
82
+ wrapper = doc.createElement('div');
83
+ wrapper.innerHTML = fallbackContent.htmlString;
84
+ mainDiv = wrapper;
85
+ styleEl = doc.head.getElementsByTagName('style')[0] || doc.createElement('style');
86
+ styleEl.textContent = fallbackContent.styleString || '';
87
+ doc.head.appendChild(styleEl);
88
+ }
89
+ else {
90
+ throw new Error('テンプレートにメイン要素が見つからず、フォールバックも指定されていません。');
91
+ }
92
+ }
93
+ styleElement = doc.head.getElementsByTagName('style')[0];
94
+ styleContent = styleElement ? styleElement.textContent : null;
95
+ if (!isDialog) {
96
+ styleTags = Array.from(document.head.getElementsByTagName('style'));
97
+ styleTags.forEach(function (tag) { return document.head.removeChild(tag); });
98
+ gameContainer.tabIndex = 0;
99
+ gameContainer.style.outline = 'none';
100
+ // HTMLコンテンツを注入する
101
+ gameContainer.innerHTML = mainDiv.innerHTML;
102
+ // キャンバスと各ビューの参照を初期化する
103
+ drawer.setScreen(gameContainer, resolution);
104
+ // テンプレートのスタイルシートを適用する
105
+ if (styleContent) {
106
+ styleEl = document.createElement('style');
107
+ styleEl.textContent = styleContent;
108
+ document.head.appendChild(styleEl);
109
+ }
110
+ gameContainer.focus();
111
+ }
112
+ else {
113
+ // 古いダイアログ用スタイルシートを削除する
114
+ document.head
115
+ .querySelectorAll('style[data-dialog-style]')
116
+ .forEach(function (tag) { return document.head.removeChild(tag); });
117
+ existingDialog = document.querySelector('#dialogContainer');
118
+ if (existingDialog) {
119
+ existingDialog.close();
120
+ existingDialog.remove();
121
+ }
122
+ // 新しいダイアログ要素を追加する
123
+ gameContainer.appendChild(mainDiv);
124
+ // ダイアログ用スタイルシートにマークを付けて適用する
125
+ if (styleContent) {
126
+ styleEl = document.createElement('style');
127
+ styleEl.textContent = styleContent;
128
+ styleEl.setAttribute('data-dialog-style', 'true');
129
+ document.head.appendChild(styleEl);
130
+ }
131
+ }
132
+ return [2 /*return*/];
133
+ }
134
+ });
135
+ }); });
136
+ // ----------------------------------------------------------------
137
+ // text:clear
138
+ // メッセージテキスト表示領域をクリアする。
139
+ // ----------------------------------------------------------------
140
+ eventBus.on('text:clear', function () {
141
+ drawer.clearText();
142
+ });
143
+ // ----------------------------------------------------------------
144
+ // text:show
145
+ // 話者名を表示し、コンテンツを1文字ずつアニメーションで描画する。
146
+ // data.expandVariable — Coreから渡される変数展開コールバック
147
+ // data.waitFn — Coreから渡されるwaitHandlerコールバック(<wait>タグ用)
148
+ // ----------------------------------------------------------------
149
+ eventBus.on('text:show', function (data) { return __awaiter(_this, void 0, void 0, function () {
150
+ var name, content, speed, expandVariable, waitFn, _i, content_1, text, container;
151
+ return __generator(this, function (_a) {
152
+ switch (_a.label) {
153
+ case 0:
154
+ name = data.name, content = data.content, speed = data.speed, expandVariable = data.expandVariable, waitFn = data.waitFn;
155
+ drawer.drawName(name);
156
+ _i = 0, content_1 = content;
157
+ _a.label = 1;
158
+ case 1:
159
+ if (!(_i < content_1.length)) return [3 /*break*/, 9];
160
+ text = content_1[_i];
161
+ if (!(typeof text === 'string')) return [3 /*break*/, 3];
162
+ return [4 /*yield*/, drawer.drawText(expandVariable(text), speed)];
163
+ case 2:
164
+ _a.sent();
165
+ return [3 /*break*/, 8];
166
+ case 3:
167
+ if (!(text.type === 'br' || text.type === 'wait')) return [3 /*break*/, 6];
168
+ if (text.type === 'br')
169
+ drawer.drawLineBreak();
170
+ if (!(text.type === 'wait' && !text.nw)) return [3 /*break*/, 5];
171
+ return [4 /*yield*/, waitFn({ wait: text.time })];
172
+ case 4:
173
+ _a.sent();
174
+ _a.label = 5;
175
+ case 5: return [3 /*break*/, 8];
176
+ case 6:
177
+ container = drawer.createDecoratedElement(text);
178
+ return [4 /*yield*/, drawer.drawText(expandVariable(text.content[0]), text.speed || speed, container)];
179
+ case 7:
180
+ _a.sent();
181
+ _a.label = 8;
182
+ case 8:
183
+ _i++;
184
+ return [3 /*break*/, 1];
185
+ case 9: return [2 /*return*/];
186
+ }
187
+ });
188
+ }); });
189
+ // ----------------------------------------------------------------
190
+ // choice:show
191
+ // インタラクティブビューを表示し、Drawerで選択肢ボタンを描画して、
192
+ // 選択後に非表示に戻す。選択結果 { selectId, onSelect } を返す。
193
+ // ----------------------------------------------------------------
194
+ eventBus.on('choice:show', function (data) { return __awaiter(_this, void 0, void 0, function () {
195
+ var interactiveView, result;
196
+ return __generator(this, function (_a) {
197
+ switch (_a.label) {
198
+ case 0:
199
+ interactiveView = document.querySelector('#interactiveView');
200
+ if (interactiveView)
201
+ interactiveView.style.visibility = 'visible';
202
+ return [4 /*yield*/, drawer.drawChoices(data)];
203
+ case 1:
204
+ result = _a.sent();
205
+ if (interactiveView)
206
+ interactiveView.style.visibility = 'hidden';
207
+ return [2 /*return*/, result];
208
+ }
209
+ });
210
+ }); });
211
+ // ----------------------------------------------------------------
212
+ // dialog:show
213
+ // 読み込まれたダイアログコンテナにプロンプトテキストとアクションボタンを
214
+ // 設定し、モーダルを表示する。ダイアログが閉じられると選択されたアクションの
215
+ // IDで解決するPromiseを返す。
216
+ // data.expandVariable — Coreから渡される変数展開コールバック
217
+ // data.addScenario — scenarioManager.addScenarioコールバック
218
+ // ----------------------------------------------------------------
219
+ eventBus.on('dialog:show', function (data) { return __awaiter(_this, void 0, void 0, function () {
220
+ var content, expandVariable, addScenario, result, dialogContainer;
221
+ return __generator(this, function (_a) {
222
+ content = data.content, expandVariable = data.expandVariable, addScenario = data.addScenario;
223
+ result = null;
224
+ dialogContainer = document.querySelector('#dialogContainer');
225
+ if (!dialogContainer) {
226
+ throw new Error('Dialog container not found.');
227
+ }
228
+ content.forEach(function (item) {
229
+ if (item.type === 'prompt') {
230
+ var promptElement = dialogContainer.querySelector('.dialog-prompt');
231
+ if (promptElement) {
232
+ promptElement.innerHTML = item.content
233
+ .map(function (text) { return expandVariable(text); })
234
+ .join('\n');
235
+ }
236
+ }
237
+ else if (item.type === 'actions') {
238
+ var buttonContainer_1 = dialogContainer.querySelector('.dialog-buttons');
239
+ if (!buttonContainer_1)
240
+ return;
241
+ item.content.forEach(function (action) {
242
+ action.label = expandVariable(action.label);
243
+ var button = buttonContainer_1.querySelector("#dialog-button-".concat(action.id));
244
+ if (!button) {
245
+ // ボタンが存在しない場合は新規作成する
246
+ button = document.createElement('button');
247
+ button.id = "dialog-button-".concat(action.id);
248
+ button.classList.add('dialog-button');
249
+ buttonContainer_1.appendChild(button);
250
+ }
251
+ button.innerText = action.label;
252
+ button.addEventListener('click', function () {
253
+ // 選択されたアクションのシナリオを追加してダイアログを閉じる
254
+ addScenario(action.content);
255
+ result = action.id;
256
+ dialogContainer.close();
257
+ });
258
+ });
259
+ }
260
+ });
261
+ dialogContainer.showModal();
262
+ return [2 /*return*/, new Promise(function (resolve) {
263
+ dialogContainer.addEventListener('close', function () {
264
+ resolve(result);
265
+ });
266
+ })];
267
+ });
268
+ }); });
269
+ // ----------------------------------------------------------------
270
+ // input:bind
271
+ // ゲームコンテナにキーボードとクリックのリスナーをバインドする。
272
+ // data.onNext — ユーザーが進行操作(Enter / クリック)した際に呼ばれる
273
+ // data.setSkip — (drawerSkip: boolean, coreNext: boolean) => void
274
+ // 再度 input:bind が発行された際は以前のリスナーを先に削除する。
275
+ // ----------------------------------------------------------------
276
+ var inputAbortController = null;
277
+ eventBus.on('input:bind', function (data) {
278
+ // 重複登録を防ぐために以前バインドしたリスナーを削除する
279
+ if (inputAbortController)
280
+ inputAbortController.abort();
281
+ inputAbortController = new AbortController();
282
+ var signal = inputAbortController.signal;
283
+ var onNext = data.onNext, setSkip = data.setSkip, toggleAuto = data.toggleAuto, toggleSkip = data.toggleSkip;
284
+ gameContainer.addEventListener('keydown', function (e) {
285
+ if (e.key === 'Enter') {
286
+ onNext();
287
+ }
288
+ else if (e.key === 'Control') {
289
+ toggleSkip();
290
+ }
291
+ else if (e.key.toLowerCase() === 'a' && toggleAuto) {
292
+ toggleAuto();
293
+ }
294
+ }, { signal: signal });
295
+ gameContainer.addEventListener('keyup', function (e) {
296
+ if (e.key === 'Control') {
297
+ toggleSkip();
298
+ }
299
+ }, { signal: signal });
300
+ gameContainer.addEventListener('click', function () {
301
+ gameContainer.focus();
302
+ onNext();
303
+ }, { signal: signal });
304
+ });
305
+ };
306
+ return DefaultUIHandler;
307
+ }());
308
+ exports.DefaultUIHandler = DefaultUIHandler;
309
+ //# sourceMappingURL=defaultUIHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultUIHandler.js","sourceRoot":"","sources":["../../../src/core/defaultUIHandler.ts"],"names":[],"mappings":"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"}
@@ -37,8 +37,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.Drawer = void 0;
40
- var logger_1 = require("../utils/logger");
41
40
  var waitUtil_1 = require("../utils/waitUtil");
41
+ var gsap_1 = require("gsap");
42
42
  /*
43
43
  drawerの目的
44
44
  UIのHTMLとcanvasを描画する。
@@ -89,56 +89,62 @@ var Drawer = /** @class */ (function () {
89
89
  };
90
90
  Drawer.prototype.drawText = function (text, wait, containerElement) {
91
91
  return __awaiter(this, void 0, void 0, function () {
92
- var element, _i, text_1, char;
92
+ var element, textNode, rt, displayedLength, _i, text_1, char;
93
93
  var _this = this;
94
94
  return __generator(this, function (_a) {
95
95
  switch (_a.label) {
96
96
  case 0:
97
- (0, logger_1.outputLog)('drawText', 'debug', { text: text, wait: wait, containerElement: containerElement });
98
97
  element = this.messageText;
99
98
  // テキストを表示するコンテナ要素を指定した場合は、その要素に追加する
100
99
  if (containerElement) {
101
100
  this.messageText.appendChild(containerElement);
102
101
  element = containerElement;
103
102
  }
103
+ textNode = document.createTextNode('');
104
+ element.appendChild(textNode);
105
+ // ruby要素の場合、ルビテキスト(<rt>)をベーステキストの後に追加する
106
+ if (element.tagName === 'RUBY' && element.dataset.rubyText) {
107
+ rt = document.createElement('rt');
108
+ rt.textContent = element.dataset.rubyText;
109
+ element.appendChild(rt);
110
+ }
111
+ displayedLength = 0;
104
112
  _i = 0, text_1 = text;
105
113
  _a.label = 1;
106
114
  case 1:
107
- if (!(_i < text_1.length)) return [3 /*break*/, 7];
115
+ if (!(_i < text_1.length)) return [3 /*break*/, 5];
108
116
  char = text_1[_i];
109
117
  //prettier-ignore
110
118
  setTimeout(function () { _this.readySkip = true, wait; });
111
119
  if (!!this.isSkip) return [3 /*break*/, 3];
112
- element.innerHTML += char;
120
+ textNode.textContent += char;
121
+ displayedLength++;
113
122
  return [4 /*yield*/, (0, waitUtil_1.sleep)(wait)];
114
123
  case 2:
115
124
  _a.sent();
116
125
  return [3 /*break*/, 4];
117
126
  case 3:
118
127
  if (this.readySkip) {
119
- element.innerHTML += text.slice(element.textContent.length);
128
+ textNode.textContent += text.slice(displayedLength);
120
129
  this.readySkip = false;
121
130
  this.isSkip = false;
122
- return [3 /*break*/, 7];
131
+ return [3 /*break*/, 5];
123
132
  }
124
133
  _a.label = 4;
125
- case 4: return [4 /*yield*/, (0, waitUtil_1.sleep)(wait)];
126
- case 5:
127
- _a.sent();
128
- _a.label = 6;
129
- case 6:
134
+ case 4:
130
135
  _i++;
131
136
  return [3 /*break*/, 1];
132
- case 7: return [2 /*return*/];
137
+ case 5: return [2 /*return*/];
133
138
  }
134
139
  });
135
140
  });
136
141
  };
137
142
  Drawer.prototype.drawLineBreak = function () {
138
143
  return __awaiter(this, void 0, void 0, function () {
144
+ var br;
139
145
  return __generator(this, function (_a) {
140
- // メッセージテキストに改行を追加する
141
- this.messageText.innerHTML += '<br>';
146
+ br = document.createElement('br');
147
+ this.messageText.appendChild(br);
142
148
  return [2 /*return*/];
143
149
  });
144
150
  });
@@ -156,22 +162,19 @@ var Drawer = /** @class */ (function () {
156
162
  return span;
157
163
  case 'ruby':
158
164
  var ruby = document.createElement('ruby');
159
- var rt = document.createElement('rt');
160
- rt.textContent = element.text;
161
- ruby.appendChild(rt);
165
+ ruby.dataset.rubyText = element.text;
162
166
  return ruby;
163
167
  case 'b':
164
168
  return document.createElement('strong');
165
169
  case 'i':
166
170
  return document.createElement('i');
167
171
  default:
168
- (0, logger_1.outputLog)("Unknown decoration type: ".concat(element.type), 'warn');
169
172
  return document.createElement('span');
170
173
  }
171
174
  };
172
175
  Drawer.prototype.drawChoices = function (choices) {
173
176
  return __awaiter(this, void 0, void 0, function () {
174
- var isSelect, selectId, onSelect, interactiveView, _loop_1, this_1, _i, _a, choice;
177
+ var isSelect, selectId, onSelect, interactiveView, CHOICE_HEIGHT, TWO_COLUMN_THRESHOLD, choiceCount_1, choiceCount, useTwoColumns, _loop_1, this_1, _i, _a, choice;
175
178
  var _this = this;
176
179
  var _b, _c;
177
180
  return __generator(this, function (_d) {
@@ -179,12 +182,31 @@ var Drawer = /** @class */ (function () {
179
182
  selectId = 0;
180
183
  onSelect = 0;
181
184
  interactiveView = document.querySelector('#interactiveView');
185
+ CHOICE_HEIGHT = 50 // 1つの選択肢の高さ(px) - button.style.heightと一致させる必要がある
186
+ ;
187
+ TWO_COLUMN_THRESHOLD = 6 // 2列レイアウトに切り替える選択肢の数
188
+ ;
182
189
  if (choices.position == 'auto' || choices.position === undefined) {
183
190
  interactiveView.className = 'auto';
191
+ choiceCount_1 = choices.content.length;
192
+ if (choiceCount_1 >= TWO_COLUMN_THRESHOLD) {
193
+ // 6つ以上の選択肢がある場合、2列レイアウトに切り替え
194
+ interactiveView.style.flexWrap = 'wrap';
195
+ interactiveView.style.columnGap = '20px'; // 列間の余白を減らす
196
+ interactiveView.style.alignContent = 'center';
197
+ }
198
+ else {
199
+ // 少数の選択肢の場合、通常通り表示
200
+ interactiveView.style.flexWrap = 'wrap';
201
+ interactiveView.style.columnGap = '';
202
+ interactiveView.style.alignContent = 'center';
203
+ }
184
204
  }
185
205
  else {
186
206
  interactiveView.className = 'manual';
187
207
  }
208
+ choiceCount = choices.content.length;
209
+ useTwoColumns = choiceCount >= TWO_COLUMN_THRESHOLD;
188
210
  _loop_1 = function (choice) {
189
211
  var defaultImage = choice.default !== undefined ? choice.default : './src/resource/system/systemPicture/02_button/button.png';
190
212
  var hoverImage = choice.hover !== undefined ? choice.hover : './src/resource/system/systemPicture/02_button/button2.png';
@@ -197,7 +219,8 @@ var Drawer = /** @class */ (function () {
197
219
  button.style.left = ((_c = choice.position) === null || _c === void 0 ? void 0 : _c.x) || 0;
198
220
  }
199
221
  button.style.color = choice.color !== undefined ? choice.color.default : 'black';
200
- button.style.width = '100%';
222
+ // 2列レイアウトの場合は幅を調整
223
+ button.style.width = useTwoColumns ? 'calc(50% - 10px)' : '100%';
201
224
  button.style.height = '50px';
202
225
  button.style.backgroundImage = "url(".concat(defaultImage, ")");
203
226
  button.style.textAlign = 'center';
@@ -221,7 +244,6 @@ var Drawer = /** @class */ (function () {
221
244
  });
222
245
  button.innerHTML = choice.label;
223
246
  button.onclick = function () {
224
- (0, logger_1.outputLog)('click', 'debug', choice);
225
247
  _this.interactiveView.querySelectorAll('.choice').forEach(function (element) {
226
248
  var _a;
227
249
  (_a = element.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(element);
@@ -233,7 +255,6 @@ var Drawer = /** @class */ (function () {
233
255
  this_1.interactiveView.appendChild(button);
234
256
  };
235
257
  this_1 = this;
236
- // 選択肢を表示
237
258
  for (_i = 0, _a = choices.content; _i < _a.length; _i++) {
238
259
  choice = _a[_i];
239
260
  _loop_1(choice);
@@ -254,7 +275,6 @@ var Drawer = /** @class */ (function () {
254
275
  return __awaiter(this, arguments, void 0, function (duration, img, option) {
255
276
  if (duration === void 0) { duration = 1000; }
256
277
  return __generator(this, function (_a) {
257
- (0, logger_1.outputLog)('Fade in', 'debug', duration);
258
278
  return [2 /*return*/, this.fade(0, 1, duration, img, option)];
259
279
  });
260
280
  });
@@ -263,7 +283,6 @@ var Drawer = /** @class */ (function () {
263
283
  return __awaiter(this, arguments, void 0, function (duration, img, option) {
264
284
  if (duration === void 0) { duration = 1000; }
265
285
  return __generator(this, function (_a) {
266
- (0, logger_1.outputLog)('Fade out', 'debug', duration);
267
286
  return [2 /*return*/, this.fade(1, 0, duration, img, option)];
268
287
  });
269
288
  });
@@ -290,12 +309,10 @@ var Drawer = /** @class */ (function () {
290
309
  else {
291
310
  _this.fadeCtx.fillRect(0, 0, _this.fadeCanvas.width, _this.fadeCanvas.height);
292
311
  }
293
- (0, logger_1.outputLog)('Fade animation', 'debug', { progress: progress, alpha: currentAlpha });
294
312
  if (progress < 1) {
295
313
  requestAnimationFrame(animate);
296
314
  }
297
315
  else {
298
- (0, logger_1.outputLog)('Fade animation complete', 'debug');
299
316
  _this.clear(_this.fadeCtx);
300
317
  resolve();
301
318
  }
@@ -329,32 +346,25 @@ var Drawer = /** @class */ (function () {
329
346
  for (var key in displayedImages) {
330
347
  _loop_2(key);
331
348
  }
349
+ this.adjustScale(this.gameScreen);
332
350
  };
333
351
  Drawer.prototype.moveTo = function (name, displayedImages, pos, durning) {
334
352
  var _this = this;
335
353
  return new Promise(function (resolve) {
336
354
  var target = displayedImages[name];
337
- var startPos = { x: target.pos.x, y: target.pos.y };
338
- var dest = { x: startPos.x + Number(pos.x), y: startPos.y + Number(pos.y) };
339
- var startTime = performance.now();
340
- var move = function (currentTime) {
341
- var elapsedTime = (currentTime - startTime) / 1000; // 秒単位の経過時間
342
- var progress = Math.min(elapsedTime / durning, 1); // 0から1の進捗
343
- target.pos.x = startPos.x + (dest.x - startPos.x) * progress;
344
- target.pos.y = startPos.y + (dest.y - startPos.y) * progress;
345
- _this.show(displayedImages);
346
- if (progress < 1) {
347
- window.requestAnimationFrame(move);
348
- }
349
- else {
350
- // 最終位置を正確に設定
351
- target.pos.x = dest.x;
352
- target.pos.y = dest.y;
355
+ var dest = { x: target.pos.x + Number(pos.x), y: target.pos.y + Number(pos.y) };
356
+ gsap_1.gsap.to(target.pos, {
357
+ x: dest.x,
358
+ y: dest.y,
359
+ duration: durning,
360
+ ease: 'power2.out',
361
+ onUpdate: function () {
353
362
  _this.show(displayedImages);
363
+ },
364
+ onComplete: function () {
354
365
  resolve(null);
355
- }
356
- };
357
- window.requestAnimationFrame(move);
366
+ },
367
+ });
358
368
  });
359
369
  };
360
370
  Drawer.prototype.clear = function (ctx) {
@@ -364,7 +374,6 @@ var Drawer = /** @class */ (function () {
364
374
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
365
375
  };
366
376
  Drawer.prototype.drawCanvas = function (img, pos, size, reverse, ctx) {
367
- (0, logger_1.outputLog)('drawCanvas', 'debug', { img: img, pos: pos, size: size, reverse: reverse });
368
377
  if (ctx === undefined) {
369
378
  ctx = this.ctx;
370
379
  }
@@ -384,8 +393,15 @@ var Drawer = /** @class */ (function () {
384
393
  var scaleY = viewportHeight / originalHeight;
385
394
  // 幅と高さのうち、小さい方のスケールを選択(アスペクト比を維持)
386
395
  var scale = Math.min(scaleX, scaleY);
387
- // ターゲット要素にスケールを適用
388
- targetElement.style.transform = "scale(".concat(scale, ")");
396
+ // スケール後のサイズを計算
397
+ var scaledWidth = originalWidth * scale;
398
+ var scaledHeight = originalHeight * scale;
399
+ // 中央配置のための位置を計算
400
+ var offsetX = (viewportWidth - scaledWidth) / 2;
401
+ var offsetY = (viewportHeight - scaledHeight) / 2;
402
+ // ターゲット要素にスケールと位置を適用
403
+ targetElement.style.transformOrigin = 'top left';
404
+ targetElement.style.transform = "translate(".concat(offsetX, "px, ").concat(offsetY, "px) scale(").concat(scale, ")");
389
405
  };
390
406
  Drawer.prototype.setVisibility = function (name, isVisible) {
391
407
  var target = this.screenHtml.querySelector(name);