2016-05-11 5 views
1

私はjavascript circuit simulatorを持っており、ゲートをドラッグしてサーキットを編集します。時には回路が非常に大きくなるので、描画されるキャンバス要素がブラウザのビューポートを超え、スクロールが必要になります。キャンバスでのスクロールとドラッグ操作のサポート

タッチスクリーンを持つユーザーが画面上で指をスライドさせると、回路要素から始まり、ドラッグとして解釈されるスライドが必要になります。しかし、空の空間から始まるスライド(私のカスタムロジックがキャンバスを何に見せているかによって決まる)は、スクロールとして解釈されるべきです。

ドラッグとスクロールの動作を調和させて共存させるにはどうすればよいですか?どのようにすればブラウザの通常のスクロール動作をあまりシミュレートせずに?スクロールがうまくいけば、ユーザーはそれを嫌う。ネイティブな振る舞い。

(ボーナス:?私はまだ[それをリロードする時期すでに、ページ上部のプルダウンAndroid上で例えば]ナビゲーションアクションをトリガーからスクロールを防止しながら、通常のスクロール動作が、を変更せずにそれを行うにはどうすればよいです)

私はキャンバスに制御を加えてドラッグを表示させたいときにのみ、touchEvent.preventDefaultを呼び出してみました。これは、スクロールバーが表示されるとすぐにうまく動作しなくなります(ブラウザはタッチを送信した後すぐにキャンセルします)。 CSSプロパティーtouch-actionも役立つかもしれませんが、私はそれを多く実験していません。

答えて

0

回避策は、ブロッカーディビジョンを使用して終了しました。

キャンバス内のドラッグ可能なすべての要素について、touch-action: none,opacity: 0、およびposition: absoluteのdivをその要素の位置に追加しました。ユーザーがブロッカーdivの1つにタッチすると、ドラッグイベントに干渉することなくスクロールがブロックされます。

setBlockers(blockers, overrideCursorStyle) { 
    // ensure enough blocker divs exist 
    while (this._blockerDivs.length < blockers.length) { 
     let blockerDiv = document.createElement('div'); 
     blockerDiv.style.touchAction = 'none'; 
     blockerDiv.style.position = 'absolute'; 
     blockerDiv.style.opacity = 0; 
     this._parentElement.appendChild(blockerDiv); 
     this._blockerDivs.push(blockerDiv); 
    } 

    // reposition blocker divs 
    for (let i = 0; i < blockers.length; i++) { 
     let s = this._blockerDivs[i].style; 
     let {x, y, w, h, cursor} = blockers[i]; 
     [s.left, s.top, s.width, s.height] = [x, y, w, h].map(e => e + "px"); 
     s.cursor = overrideCursorStyle || cursor || 'auto'; 
     s.display = 'inline'; 
    } 

    // hide unused blocker divs 
    for (let i = blockers.length; i < this._blockerDivs.length; i++) { 
     this._blockerDivs[i].style.display = 'none'; 
    } 
} 

これはChromeで動作し、SafariでのiOS上ではなく、Firefoxの中には、(:なしタッチアクションのためのサポートが欠けています)。

関連する問題