お絵描きアプリについて

https://qiita.com/juri_don/items/a0c978c32d303a361dc5

上記を参考に、お絵描きアプリを実装しているのですが、

iPadで行うと、絵が描けません。
解決方法がございましたら、ご教示願います。

 

こんにちは。筆者です。

今思えば、懐かしくもあり恥ずかしくもある記事ですが、読んでくださってありがとうございます。
試してはいないのですが、マウスイベントをタッチイベントに変えてみると動くかもしれません。

それと、コードを見たらお分かりと思いますが、エラー処理とかしていないので、そのあたりはご自分で実装してください。
お遊びで作ったコードでもあるので、ご参考程度に、自己責任でお願いしますねm(_ _)m

ご回答ありがとうございます。
JavaScript初心者なんですが、タッチイベントがうまく動作しません。
方法をご教示いただければ幸いです。

mouseをそのままtouchに変えるだけで動けば良いんですけど、
まぁそうはうまくいかないですよね。。。

実装の方法は試してみないとわかりません。
というわけで、ごめんなさい、わからないです。

javascript タッチイベント マウスイベント 違い
このあたりを検索して実装を試してみるとよいとおもいます。

juridon 様

お世話になっております。
教えて頂いた、タッチイベントで、iPad上で描画が出来る様になりました。
ありがとうございます。

一点教えて頂きたいのですが、Windows上で描画したものを保存する事が出来たのですが、
iPadのGoogle Chrome上では、保存が出来ません。
何か、知っている事があれば、ご教示願います。

(function() {

  'use strict';

  kintone.events.on('app.record.create.submit.success', event => {

    //canvasの画像を保存

    const saveCanvas = (canvas_id) => {

        const canvas = document.getElementById(canvas_id);

        const title = "test";//ファイル名をお好きなように

        // Brobを取得

        canvas.toBlob( blob => {

            // FormDataにファイルを格納

            const formData = new FormData();

            formData.append(' __REQUEST_TOKEN__', kintone.getRequestToken());

            formData.append('file', blob, title+'.png');    

            //ファイルをアップロード

            const xmlHttp = new XMLHttpRequest();

            xmlHttp.open('POST','https://○○○○/k/v1/file.json');

            xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

            xmlHttp.send(formData);

            //200が帰ってきたらレコード登録

            xmlHttp.onload = () => {

                if(xmlHttp.status===200){

                    const key = JSON.parse(xmlHttp.responseText).fileKey;

                    const body={

                        app:kintone.app.getId(),

                        id: event.recordId,//←できたてほやほやのレコードID

                        record:{

                            "添付ファイル":{value:[

                                {fileKey: key}

                            ]}

                        }

                    }

                    //fileKeyを設定

                    kintone.api("/k/v1/record","PUT",body).then(function(resp){

                        console.log(resp);

                    },(err)=>{

                        console.log(err);

                    });

                }

            }

        });

    }

    //保存

    saveCanvas("canvas");

    return event;

});

})();

 

 

コード書いてくださったんですね!
ごめんなさい、今iPadで試せる環境がなく。

イベントが「submit.success」で、保存後だからですかね?

juridon 様
お世話になっております。

今回、保存ボタンを作成し、保存したいと考えております。
保存のコードを移植しても動かないのですが、何か修正点があればご教示願います。

  //----------------------------------------------------------------------------
    //保存
    //----------------------------------------------------------------------------
    var NewButton1 = document.createElement('button');
    NewButton1.id = 'NewUserButton1';
    NewButton1.innerText = '保存';
    NewButton1.style.width = '70%';
    NewButton1.style.height = '50px';
    NewButton1.style.marginLeft = '5%';
    NewButton1.style.marginTop = '15%';
    NewButton1.onclick = function()
    {
        const saveCanvas = (canvas_id) => {
        const canvas = document.getElementById(canvas_id);
        const title = "test";//ファイル名をお好きなように

        // Brobを取得
        canvas.toBlob( blob => {
        // FormDataにファイルを格納
        const formData = new FormData();
        formData.append(' __REQUEST_TOKEN__', kintone.getRequestToken());
        formData.append('file', blob, title+'.png');    

        //ファイルをアップロード
        const xmlHttp = new XMLHttpRequest();
        xmlHttp.open('POST','https://XXXXXX.cybozu.com/k/v1/file.json');
        xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xmlHttp.send(formData);

        //200が帰ってきたらレコード登録
        xmlHttp.onload = () => {
        if(xmlHttp.status===200){
        const key = JSON.parse(xmlHttp.responseText).fileKey;
        const body={
        app:kintone.app.getId(),
        id: event.recordId,//←できたてほやほやのレコードID
        record:{
        "添付ファイル":{value:[
            {fileKey: key}
        ]}
        }
        }
        //fileKeyを設定
        kintone.api("/k/v1/record","PUT",body).then(function(resp){
        console.log(resp);
        },(err)=>{
        console.log(err);
        });
        }
        }
        });
        }

        //保存
        saveCanvas("canvas");

    }
    kintone.app.record.getSpaceElement('NewUserButton1').appendChild(NewButton1); 
    //----------------------------------------------------------------------------

私に精神的余裕と試す環境iPadがないのでヒントだけで申し訳ないんですが

提示されたコードの部分だけでは合ってるも間違ってるも何とも言えないです。
どの画面でいつそれを動かすのかが関係します。

↓こちらのコメント、伝わったかどうか・・・ですが、できたてほやほやというのは新規の保存完了のタイミングだったのでできたてほやほやでした。

event.recordId,//←できたてほやほやのレコードID

コードについての質問の回答は以上とさせてください~m(_ _)m

kintone_TS44 様

こんにちは。

また、juridon 様よこから失礼いたします。

 

私も検証してないので間違ってたらすいません。

おそらくipadのchromeがXMLHttpRequestがかなり古い技術なので対応してないのではないでしょうか?

今だとfetchを使うのが一般的ですので、fetchで試して頂ければと思います。

これだけだと難しいので、置換えるサンプルも提示しときますね。

const option = {
  method: "POST",
  headers: { "X-Requested-With": "XMLHttpRequest" },
  body: formData,
};
fetch(kintone.api.url("/k/v1/file"), option)
  .then((res) => res.json())
  .then((fileKey) => {
    const data = {
      app: kintone.app.getId(),
      id: kintone.app.record.getId(),
      record: { file: { value: [fileKey] } },
    };
    return kintone.api(kintone.api.url("/k/v1/record"), "PUT", data);
  })
  .then(() => location.reload())
  .catch((err) => console.log(err.message));

上記を差し替えて結果を教えて頂けると幸いでございます。

 

また、差し替える範囲は、

const xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", "https://XXXXXX.cybozu.com/k/v1/file.json");
xmlHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xmlHttp.send(formData);

xmlHttp.onload = () => {
  if (xmlHttp.status === 200) {
    const key = JSON.parse(xmlHttp.responseText).fileKey;
    const body = {
      app: kintone.app.getId(),
    id: event.recordId,
      record: {
        添付ファイル: { value: [{ fileKey: key }] },
      },
    };
    //fileKeyを設定
    kintone.api("/k/v1/record", "PUT", body).then(
      function (resp) {
        console.log(resp);
      },
      (err) => {
        console.log(err);
      }
    );
  }
};

上記の部分です。

私の興味本位で申し訳ないですが、検証よろしくお願いいたします。

新屋 育男 様

ご教示いただき誠にありがとうございます。
色々と試してはおりますが、クリックすいた直後の下記でエラーで落ちてしまっているので、
まずは下記を通る方法を考えます。
const saveCanvas = (canvas_id) => {

kintone_TS44 様

こんかいの修正で、置換えで最初に起こりそうなことを予想でお答えしますね。

閉じかっこを消しすぎた可能性はないでしょうか?

constsaveCanvas =(canvas\_id) =\>{
canvas.toBlob(blob =\>{

上記の分の閉じかっこが該当するかと思います。

ですので、上記が該当箇所だとした場合閉じかっこが

}); // canvas.toBlob(blob =\>{ の分の閉じかっこ
} //constsaveCanvas =(canvas\_id) =\>{ の分の閉じかっこ
  
//保存
saveCanvas("canvas");

も消したかなと言う予想です。

一度確認をしてみてください。

新屋 育男 様
ご回答、ありがとうございます。
カッコの数はあっているはずなんですが…

NewButton1.onclick = function()

      {

          const saveCanvas = (canvas_id) => {

          const canvas = document.getElementById(canvas_id);

          const title = "test";//ファイル名をお好きなように




          // Brobを取得

          canvas.toBlob( blob => {

          // FormDataにファイルを格納

          const formData = new FormData();

          formData.append(' __REQUEST_TOKEN__', kintone.getRequestToken());

          formData.append('file', blob, title+'.png');

          const option =

          {

            method: "POST",

            headers: { "X-Requested-With": "XMLHttpRequest" },

            body: formData,

          };

          fetch(kintone.api.url("/k/v1/file"), option)

            .then((res) => res.json())

            .then((fileKey) =>

            {

              const data = {

                app: kintone.app.getId(),

                id: kintone.app.record.getId(),

                record: { file: { value: [fileKey] } },

              };

              return kintone.api(kintone.api.url("/k/v1/record"), "PUT", data);

            })

            .then(() => location.reload())

            .catch((err) => console.log(err.message));

          });

          }

          //保存

          saveCanvas("canvas");




      }

kintone_TS44 様

ありがとうございます。

かっこは大丈夫そうですね。

逆になぜエラーが出ているのか不思議です。。。

 

修正箇所は一か所見つけてるんですけど、data オブジェクトの中ですね。

const data = {
  app: kintone.app.getId(),
  id: kintone.app.record.getId(),
  record: { 添付ファイル: { value: [fileKey] } },
};

file になっている部分を『添付ファイル』に書き換えないといけないと思います。

これは、私がしっかり見てなかったせいですね。

それ以外だと、kintone.app.record.getId() が機能しない場合があるなど不思議なことがあるので、少し調べさせて下さい。

kintone_TS44 様

ああ、わかりました。

新規作成だからそもそも kintone.app.record.getId() が機能しないんですね。

だから、サクセス後の event.recordIdで更新先取得しているみたいですね。

新規作成だと一工夫いりそうですよ。

 

要はイベントの発火タイミングで変わります。

POST にするのか PUT にするのかなど、まぁどちらにしても event.recodeId を利用した方が良いみたいでした。

kintone_TS44 様

ここまで一通り作成したので、ipadのchromeまで検証をしました。

ボタンを使ったイベント処理や、submit.successなどのイベントでも特に問題なく保存されましたね。

 

ただ、XMLHttpRequest の検証は一切しておりません。

最初のXMLHttpRequestで特に問題が見受けられないことから、おそらくで申し訳ないですけどXMLHttpRequestに対応していないのだと思われます。

とりあえず私は満足したので、これにて失礼いたします。

新屋 育男
お世話になっております。
話は、脱線するのですが、
下記で、描画したものを消去しようとしているのですが、タブレットで消去ボタンをタップしても、一度は消えるのですが、再度描画すると消す直前のものが表示されてしまいます。

var sp = kintone.app.record.getSpaceElement('sp_img');        var canvas = document.createElement('canvas');      canvas.id="canvas";      sp.appendChild(canvas);            canvas.setAttribute("width",500);      canvas.setAttribute("height",500);        var ctx = canvas.getContext('2d');       ctx.strokeStyle = 'rgb(0,0,0)';//線の色      ctx.lineWidth = 1;      ctx.fillStyle = 'rgb(255,255,255)'; //塗りつぶしの色      ctx.fillRect(0,0,c_W,c_H);            //----------------------------------------------------------------------------      var NewButton = document.createElement('button');      NewButton.id = 'NewUserButton';      NewButton.innerText = '消去';      NewButton.style.width = '70%';      NewButton.style.height = '50px';      NewButton.style.marginLeft = '5%';      NewButton.style.marginTop = '15%';      NewButton.onclick = function()      {          ctx.fillStyle = 'rgb(255,255,255)';          ctx.fillRect(0,0,c_W,c_H);                }      kintone.app.record.getSpaceElement('NewUserButton').appendChild(NewButton);

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。