ブラウザ版Pyxelでファイルアップロード
レトロゲームエンジンPyxelで、jsモジュールを使えばファイルのダウンロードができる、という記事を以前に投稿しました。
ダウンロードができるならアップロードもできるはず!ということで試してみました。
地味に苦戦したのですが、結論としては問題なくできます。
以下、動作イメージです。Lorem ipsumのサンプルテキストを読み込ませて画面に表示しているだけです。
ソースはこちら。
わかりやすくするため、HTML内に直接Pyxelのコードを書き込んでいます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pyxel x JavaScript Sample</title>
<script src="https://cdn.jsdelivr.net/gh/kitao/pyxel/wasm/pyxel.js"></script>
</head>
<body>
<pyxel-run
script="
import pyxel
from js import document, FileReader
from pyodide.ffi import create_proxy
class App:
def __init__(self):
self.texts = None
pyxel.init(160, 120)
document.body.addEventListener('dragover', create_proxy(self.on_dragover))
document.body.addEventListener('drop', create_proxy(self.on_drop))
pyxel.run(self.update, self.draw)
def update(self):
pass
def draw(self):
pyxel.cls(0)
if self.texts:
x = 0
y = 0
for text in self.texts:
pyxel.text(x * 4, y * 8 + 1, text, 7)
x += 1
if text == '\n':
y += 1
x = 0
else:
pyxel.text(50, 57, 'Drop file here.', 7)
def on_dragover(self, e):
e.preventDefault()
def on_drop(self, e):
e.preventDefault()
files = e.dataTransfer.files
for file in files:
reader = FileReader.new()
def on_load(e):
self.texts = reader.result
reader.onload = on_load
reader.readAsText(file)
break
App()
"
></pyxel-run>
</body>
</html>
あまりまともに解説できませんが、以下あたりがポイントでしょうか。
ファイルの中身を読み込むためには、FileReaderオブジェクトをjsモジュールからインポートしてFIleReaderオブジェクトから操作する必要がある
addEventListenerする際にはハンドラ関数を直接登録するのではなく、pyodideからcreate_proxyをインポートしてcreate_proxyの引数としてハンドラ関数を登録する必要がある(でないとイベントが破棄されてしまう)
いやPyxelって小規模なレトロゲーム作るゲームエンジンだろ、アップロードさせる必要ある?というツッコミはごもっともなのですが、Pyxel製のツールを作りたい際なんかには役に立つかもしれません。
Pyxel本体もバージョン2.0の開発が進んでいるようで(2023/10/9現在)楽しみですね。
この記事が気に入ったらサポートをしてみませんか?