LoginSignup
2
1

enchant.jsをタッチパネルに対応させるため修正してみた

Last updated at Posted at 2023-11-22

今さらenchant.js?

 GIGAタブレットが全国の小中学生全員に配布されています。市町村によって機種が異なり、Windows、Chromebook、iPadの3種類のどれかになっています。Webアプリであれば、3種類のGIGAタブレット共通に動きます。enchant.jsもWebアプリを作動させるライブラリとして利用できます。しかし、enchant.jsはiPadでは問題なく作動しますが、タッチパネル上の移動イベント(touchmove)を取得できないため、Windows、Chromebookでは作動が不完全になります。
 そこで、touchmoveが作動するように書き換えてみました。これで、過去に作成したenchant.jsを利用したプログラムがGIGAタブレットでも作動可能になります。

×タッチパネルで操作できない例「とけいの学習」(マウス可、iPadでは作動)

タッチパネルで操作可能の例「とけいの学習」(マウス可、iPadでも作動)

 「今さらenchant.js?」と思われるかもしれませんが、過去の作品を少し手直しするだけで、現在の機器で利用できるプログラムに生まれ変わります。

修正のしかた

 enchant.js v0.8.3 の場合を例に修正方法を説明します。他のバージョンでも同様に修正するとタブレットでタッチ作動します。(0.5.2でも確認しています)
 「enchant.js」ファイルを修正します。修正場所は5カ所になります。

1 変数を定義

 変数を定義します。

enchant.js 8行目から
var myTouchmoveX;        // touchmoveの座標
var myTouchmoveY;        // touchmoveの座標
var myTouchFlag = 0;     // mousedownとtouchstart連続反応防止フラグ

2 'mousedown' を検索して修正 1つ目

 enchant.js ファイルで「'mousedown'」 を検索します。4か所あります。
検索1つ目、1129行目から1156行目までの「'mousedown'」「'mousemove'」「'mouseup'」イベントリスナーの部分をコピーします。
1157行目にペースト(複製)し、「'mousedown' を 'touchstart'」「'mousemove'を'touchmove'」「'mouseup'を'touchend'」に変更します。

enchant.js 1157行目から
stage.addEventListener('touchstart', function(e) {               // touchstartに変更
    var tagName = (e.target.tagName).toLowerCase();
    if (enchant.ENV.USE_DEFAULT_EVENT_TAGS.indexOf(tagName) === -1) {
        e.preventDefault();
        core._mousedownID++;
        if (!core.running) {
            e.stopPropagation();
        }
    }
}, true);
stage.addEventListener('touchmove', function(e) {               // touchmoveに変更
    var tagName = (e.target.tagName).toLowerCase();
    if (enchant.ENV.USE_DEFAULT_EVENT_TAGS.indexOf(tagName) === -1) {
        e.preventDefault();
        if (!core.running) {
            e.stopPropagation();
        }
    }
}, true);
stage.addEventListener('touchend', function(e) {               // touchendに変更
    var tagName = (e.target.tagName).toLowerCase();
        if (enchant.ENV.USE_DEFAULT_EVENT_TAGS.indexOf(tagName) === -1) {
            e.preventDefault();
            if (!core.running) {
                e.stopPropagation();
            }
        }
}, true);

3 'mousedown' を検索して修正 2つ目

検索2つ目、1230行目からの「'mousedown'」イベントリスナーを以下のように修正します。

enchant.js 1230行目から
stage.addEventListener('mousedown', function(e) {
    if(myTouchFlag == 1){                         // mousedownとtouchstartを続けて反応させない
        return;
    };
    myTouchFlag = 1;                              // フラグ設定
    setTimeout(function(){                        // 反応させないための待機時間設定
        myTouchFlag = 0;
    },50);
    var core = enchant.Core.instance;
    var evt = new enchant.Event(enchant.Event.TOUCH_START);
    evt._initPosition(e.pageX, e.pageY);
    var target = core.currentScene._determineEventTarget(evt);
    core._touchEventTarget[core._mousedownID] = target;
    target.dispatchEvent(evt);
}, false);

1230行目から1263行目までの「'mousedown'」「'mousemove'」「'mouseup'」イベントリスナーの部分をコピーします。
1264行目にペースト(複製)し、「'mousedown' を 'touchstart'」「'mousemove'を'touchmove'」「'mouseup'を'touchend'」にして以下のように修正します。

enchant.js 1264行目から
stage.addEventListener('touchstart', function(e) { // touchstart に変更
    if(myTouchFlag == 1){                          // mousedownとtouchstartを続けて反応させない
        return;
    };
    myTouchFlag = 1;                               // フラグ設定
    setTimeout(function(){                         // 反応させないための待機時間設定
        myTouchFlag = 0;
    },50);
    var core = enchant.Core.instance;
    var evt = new enchant.Event(enchant.Event.TOUCH_START);
    evt._initPosition(e.touches[0].pageX, e.touches[0].pageY); // タッチ座標の取得
    var target = core.currentScene._determineEventTarget(evt);
    core._touchEventTarget[core._mousedownID] = target;
        target.dispatchEvent(evt);
    }, false);
stage.addEventListener('touchmove', function(e) {              // touchmove に変更
    var core = enchant.Core.instance;
    var evt = new enchant.Event(enchant.Event.TOUCH_MOVE);
    evt._initPosition(e.touches[0].pageX, e.touches[0].pageY); // タッチ座標の取得
    myTouchmoveX = e.touches[0].pageX;                         // タッチ座標の保存
    myTouchmoveY = e.touches[0].pageY;                         // タッチ座標の保存
    var target = core._touchEventTarget[core._mousedownID];
    if (target) {
        target.dispatchEvent(evt);
    }
}, false);
stage.addEventListener('touchend', function(e) {               // touchendに変更
    var core = enchant.Core.instance;
    var evt = new enchant.Event(enchant.Event.TOUCH_END);
    evt._initPosition(myTouchmoveX, myTouchmoveY);             // touchmoveした座標
    var target = core._touchEventTarget[core._mousedownID];
    if (target) {
        target.dispatchEvent(evt);
    }
    delete core._touchEventTarget[core._mousedownID];
}, false);

 マウスの場合には「mouseup」でマウスのボタンを離した(クリック終了、ドラッグ終了)座標を取得できます。しかし、タッチの場合には「touchend」でタッチ終了の座標の取得はできません。よって、touchmoveの最後の座標を「タッチ終了の座標」として処理します。

4 'mousedown' を検索して修正 3つ目と4つ目

 検索3つ目、4200行目の「'mousedown'」アド イベントリスナーの部分をコピー&ペーストします。
 4201行目を「'touchstart'」に修正します。

enchant.js 4200行目から
this.element.addEventListener('mousedown', this._setDomTarget, true);
this.element.addEventListener('touchstart', this._setDomTarget, true);

 検索4つ目、4207行目の「'mousedown'」リムーブ イベントリスナーの部分をコピー&ペーストします。
 4208行目を「'touchstart'」に修正します。

enchant.js 4207行目から
this.element.removeEventListener('mousedown', this._setDomTarget, true);
this.element.removeEventListener('touchstart', this._setDomTarget, true);

enchant.jsは非常に便利

 enchant.js v0.8.3 ファイルは次のURLにあります。
https://github.com/wise9/enchant.js
画面をスクロールして中間付近の「Download」の「Download Zip file」からダウンロードしてください。
 enchant.jsを使ったプログラムのしかたは、ネット検索をすると結構でています。図形をステージに配置して、移動や回転、重なり判定などを簡単にできるenchant.jsは学習用教材づくりに適しています。ディスプレイの大きさに合わせて、部品を自動で拡大縮小してくれるのも便利です。ライブラリの読み込みに若干時間がかかりますが、許せる範囲と思います。enchant.jsのアップデート終了から約10年、開発会社も既に解散し、サイトもなくなってしまっています。それでも、使いやすい日本製のソフトです。「なんで今さら」と思わずにenchant.jsを使ってみてください。

2
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1