質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

1929閲覧

canvas内の画像が消える・またはスワイプできない JSのtouchイベントを正しく動かしたい preventDefault()を特定の要素にだけは効かないようにしたい

sjww

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/08/04 23:39

前提・実現したいこと

canvas内の画像が消える・またはスワイプできない
JSのtouchイベントを正しく動かしたい
preventDefault()を特定の要素にだけは効かないようにしたい

発生している問題・エラーメッセージ

https://qiita.com/yamazaki3104/items/abbcb88f573d3c5a4a40

このページに載っているコードを参考に画像の切り抜きシステムを組んだのですが、スマホのtouchイベントからでは正しく動作しません。
画像をアップロードした後にcanvas内の画像を指でスワイプしたいのですが、画像を指で押した瞬間に画像が消えてしまいます。
また、ブラウザや機種によっては画像は消えずに済むのですけども、画像をスワイプさせようとするとサイト全体もスクロールしてしまいます。
更にサイト全体のスクロールと連動しているためか、縦方向にはスワイプできるのですが、横方向には全くスワイプできません。alertでpageXの値を表示させても0と出てきます。
そこでpreventDefault()を書き足してみたのですが、今度はcanvas内の画像が全くスワプしません。
一体どうすればスマホからでも無事にスワイプできるようになるでしょうか?
御教授お願い致します。

該当のソースコード

<div class="max-sp center"> <div class="upload"><input type="file" name="file" id="file" required></div> <input id='scal' type='range' value='' min='10' max='400' oninput="scaling(value)" style='width: 90%;'><br> <canvas id='cvs' class="max-500 center" width='300' height='400'></canvas> <br> <center><button id='trimming' style="font-size: 120%;min-width: 160px;" onclick='crop_img()'>トリミング</button></center><br> <canvas id='out' width='2400' height='2400'></canvas> <br><br> </div> <br><br> <script> const cvs = document.getElementById( 'cvs' ) const cw = cvs.width const ch = cvs.height const out = document.getElementById( 'out' ) const oh = out.height const ow = out.width let ix = 0 // 中心座標 let iy = 0 let v = 1.0 // 拡大縮小率 const img = new Image(); var obj1 = document.getElementById("file"); obj1.addEventListener("change", function(evt){ var file = evt.target.files; var reader = new FileReader(); //dataURL形式でファイルを読み込む reader.readAsDataURL(file[0]); //ファイルの読込が終了した時の処理 reader.onload = function(){ var dataUrl = reader.result; img.src = dataUrl ; } },false); img.onload = function( _ev2 ){ // 画像が読み込まれた ix = img.width / 2 iy = img.height / 2 let scl = parseInt( cw / img.width * 100 ) document.getElementById( 'scal' ).value = scl scaling( scl ) } function scaling( _v ) { // スライダーが変った v = parseInt( _v ) * 0.01 draw_canvas( ix, iy ) // 画像更新 } function draw_canvas( _x, _y ){ // 画像更新 const ctx = cvs.getContext( '2d' ) ctx.fillStyle = 'rgb(252, 243, 255)' ctx.fillRect( 0, 0, cw, ch ) // 背景を塗る ctx.drawImage( img, 0, 0, img.width, img.height, (cw/2)-_x*v, (ch/2)-_y*v, img.width*v, img.height*v, ); ctx.lineWidth = 30; ctx.strokeStyle = 'rgba(255, 0, 0, 1)' ctx.strokeRect( (cw-ow)/2, (ch-oh)/2, ow, oh ) // 赤い枠 } const ctx2 = out.getContext( '2d' ) ctx2.fillStyle = 'rgb(252, 243, 255)' ctx2.fillRect( 0, 0, ow, oh ) // 背景を塗る function crop_img(){ // 画像切り取り ctx2.drawImage( img, 0, 0, img.width, img.height, (ow/2)-ix*v, (oh/2)-iy*v, img.width*v, img.height*v, ) } let mouse_down = false // canvas ドラッグ中フラグ let sx = 0 // canvas ドラッグ開始位置 let sy = 0 cvs.addEventListener('touchstart', function ( _ev ){ // canvas ドラッグ開始位置 mouse_down = true sx = _ev.pageX sy = _ev.pageY return false // イベントを伝搬しない }, {passive: false}); cvs.addEventListener('touchend', function ( _ev ){ // canvas ドラッグ終了位置 if ( mouse_down == false ) return mouse_down = false draw_canvas( ix += (-sx+_ev.pageX)/v, iy += (-sy+_ev.pageY)/v ) return false // イベントを伝搬しない }, {passive: false}); cvs.addEventListener('touchmove', function ( _ev ){ // canvas ドラッグ中 if ( mouse_down == false ) return draw_canvas( ix + (sx-_ev.pageX)/v, iy + (sy-_ev.pageY)/v ) return false // イベントを伝搬しない }, {passive: false}); function send_image() { const canvas = out.toDataURL("image/jpeg"); document.getElementById('image').value = canvas; var f = document.forms["sendform"]; f.method = "POST"; f.submit(); return true; } //マウス操作のコードは省略してあります </script>

試したこと

ctx.fillRect( 0, 0, cw, ch )のコードをfunction内から移して最初から表示されるようにすると、canvas内の画像はクリックしても消えませんが、画像を動かす度に古い画像が残像のように残ります。かと言って完全に消してしまうと画像自体がcanvas内に表示されません。
event.preventDefault();を3つのtouchイベントに書き込むとcanvas内がスワイプでは完全に動かなくなります。

スマホでも機種によってはfirefoxならいくらか動きます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問