ZawaWorks’s diary

プログラミング技術メモ

p5js:スマホのブラウザ上でmouseX,mouseYが使えない問題と解決法

はじめに

p5jsを使って簡単なお絵描きツールを作ろうとしたのですが、PC上ではマウスで線を描画できたのに、スマホ上ではタッチで線を描画することができませんでした。今回はその問題の解決法を紹介します。

環境設定

PC上でのコード

PCのブラウザ上でマウスを使い線を描画するため、index.htmlを用意しました。

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">
    <script language="javascript" type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.9/p5.min.js"></script>
<body>
    <script>
    / /p5js

       function setup() {
            createCanvas(displayWidth, displayHeight);
            background(255);

            strokeWeight(10)
            stroke(0);
        }

        function draw() {}

        function mouseDragged() {
            line(mouseX, mouseY, pmouseX, pmouseY);
            return false;
        }
  </script>
</body>

</html>

これを実行したすると次の動画のようになります。

youtu.be

スマホ上のコード

解決までの経緯

これをNode.jsでサーバを立ててスマホ上で開いてみます。server.jsindex.htmlと同じフォルダーに入れてください。

server.js

var http = require('http'),
    fs = require('fs');
var server = http.createServer();
var ipadress = "";//pcのipアドレスを書く
var port = 3000;//ポート番号

server.on('request', function (req, res) {
    fs.readFile(__dirname + '/indext.html', 'utf-8', function (err, data) {
        if (err) {
            res.writeHead(404, { 'Content-Type': 'text/plain' });
            res.write("not found!");
            return res.end();
        }
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write(data);
        res.end();
    });
});
server.listen(port, ipadress);
console.log("server listening ...");

これをnode serverで実行してスマホのブラウザで読み込みました。しかし、なぜか描画できない……。 調べてみるとどうやらp5jsにはtouchMoved()という関数が定義されており、スマホ上ではそちらを使うようです。そして、touchMoved()を使って線を描画するサンプルがあったのでindex.htmlの中身を変えてみました。

index.htmlのp5jsコードの部分

 function setup() {
    createCanvas(displayWidth, displayHeight);
    strokeWeight(10)
    stroke(0);
}

function touchMoved() {
    line(mouseX, mouseY, pmouseX, pmouseY);
    return false;
}

p5.js | examplesより引用

しかし、どれだけタッチしてもmouseXmouseYも値が0のままで、PC上のような描画ができませんでした。

解決方法

さらに調べてみるとtoutchesという配列がp5jsで定義されているようです( (p5:touches)https://p5js.org/reference/#/p5/touches

)。これはスマホのタッチデバイスで検出した指の本数分の座標を格納する配列です。これ使い、コードを書き直しました。

index.htmlのp5jsコードの部分

        var ptouchX;
        var ptouchY;

        function setup() {
            createCanvas(displayWidth, displayHeight);
            background(255);

            strokeWeight(10)
            stroke(0);

        }

        function draw() {
            ptouchX = touches[0].x;
            ptouchY = touches[0].y;
        }

        function touchMoved() {
            line(touches[0].x, touches[0].y, ptouchX, ptouchY);
            return false;
        }

youtu.be

すると見事に動きました!

最終的なコード

sketch.html · GitHub

おわりに

p5jsがマウスイベントとタッチイベントを全く別に定義していることを知らなかったため、PC上で動いたコードがスマホ上で動かなかったときは大変驚きました。p5jsは簡単にスマホ向けWebアプリを作れて便利ですので、皆さんもぜひ使ってみてください。