ざっくり大まかですが、正方形のdiv内で手回し発電の容量で左クリックを押しながら(タッチデバイスはタップ)しながら、右回りに円を描くとテキストボックスの数字の値が増加し、左周りで描くと数字の値が減少する構文を書きたいのです。右回りの時にスタート時が0で回していくうちに1〜99と増え、完全に同じ位置に回って戻ってくると100に回していく度に連続で増えていくという感じにしたいです。何から取っかかれば全くわかりません。ご教授ください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
テキストの範囲指定等であればドラッグイベントで容易に取れるのですが、たんに要素上の移動を取りたい場合はmousedownとmousemoveとmouseupのあわせ技で取る必要があります。
js
1 2let isMouseDown = false; 3document.body.addEventListener('mousedown', () => { isMouseDown = true; }); 4document.body.addEventListener('mouseup', () => { isMouseDown = false; }); 5document.body.addEventListener('mousemove', () => { 6 // マウスダウン状態でない場合は何もしない 7 if(!isMouseDown) return; 8 9 console.log('Dragging now!'); 10});
マウスイベントを取るとき、イベントハンドラに渡される第一引数で座標を取ることができます。
移動するごとに座標を保持しておき、直前の座標と比べることで移動方向を判断できます。
js
1let prevMouseX = 0; 2let prevMouseY = 0; 3document.body.addEventListener('mousemove', evt => { 4 // マウスダウン状態でない場合は何もしない 5 if(!isMouseDown) return; 6 7 if(prevMouseX - evt.pageX > 0) console.log('Dragged to Left'); 8 if(prevMouseX - evt.pageX < 0) console.log('Dragged to Right'); 9 if(prevMouseY - evt.pageY < 0) console.log('Dragged to Up'); 10 if(prevMouseY - evt.pageY > 0) console.log('Dragged to Down'); 11 // NOTE: 1ドットごとに移動を判断するので、斜めへの移動は困難。 12 // 本当に一瞬で左上に動かしたらLeftとUpが同時に出るが、基本的には 13 // Leftに行ってからUp (あるいはその逆) になる 14 15 // 保持している座標を更新 16 prevMouseX = evt.pageX; 17 prevMouseY = evt.pageY; 18});
問題はタップイベント対応ですね……OSやブラウザの制御でスクロールに取られる可能性があり、一筋縄では行かない気がします。
<html>要素と<body>要素の高さがブラウザの高さを超えなければ大丈夫かな……要検証ですねご参考になれば幸いです。 CodePen
html
1<div id="area"></div> 2<p>coords: X <span id="x"></span> / Y <span id="y"></span></p> 3<p id="gauge"><span id="fill"></span>power: <span id="power"></span>
css
1body { 2 background-color: #eee; 3 display: flex; 4 flex-direction: column; 5 align-items: center; 6} 7#area { 8 background-color: #fff; 9 border: 1px solid #000; 10 height: 100px; 11 width: 100px; 12} 13p { 14 margin: 0.2em 0; 15} 16#gauge { 17 width: 100px; 18 position: relative; 19} 20#fill { 21 background-color: rgba(255, 0, 0, 0.3); 22 position: absolute; 23 top: 0; 24 left: 0; 25 bottom: 0; 26 z-index: 999; 27}
js
1/** 2 * Powerの数値をセットしてゲージを描画する 3 * @param {Number} newPower セットする数値 4 */ 5const setPower = newPower => { 6 const power = document.getElementById('power'); 7 const gaugeFill = document.getElementById('fill'); 8 9 power.textContent = newPower; 10 gaugeFill.style.width = `${newPower}%`; 11} 12 13/** 14 * マウスのstate 15 * @type {Boolean} isButtonDown いまクリックボタンが押されているか 16 * @type {Object} previousCoords 直前のマウスカーソルの座標 17 */ 18const mouseState = { 19 isButtonDown: false, 20 previousCoords: { 21 x: NaN, 22 y: NaN, 23 } 24} 25 26/** 27 * 移動方向の判断を容易にするために、マウスイベントが持つ絶対座標を 28 * 要素の中心を原点とした相対座標に変換する 29 * X座標は右が正、Y座標は上が正 30 * @param {Event} evt マウスイベント 31 */ 32const getRelativeMouseCoordsOnElement = (evt) => { 33 const rect = evt.target.getBoundingClientRect(); 34 return { 35 x: evt.pageX - rect.left - window.pageXOffset - rect.width / 2, 36 y: (evt.pageY - rect.top - window.pageYOffset - rect.height / 2) * -1 37 }; 38} 39 40/** 41 * クリックボタンが押されたときのハンドラ 42 * @param {Event} evt マウスイベント 43 */ 44const mouseDownHandler = evt => { 45 const relativeMouseCoords = getRelativeMouseCoordsOnElement(evt); 46 document.getElementById('x').textContent = relativeMouseCoords.x; 47 document.getElementById('y').textContent = relativeMouseCoords.y; 48 mouseState.isButtonDown = true, 49 mouseState.previousCoords = relativeMouseCoords; 50}; 51 52/** 53 * マウスカーソルが要素の上を移動しているときのハンドラ 54 * @param {Event} evt マウスイベント 55 */ 56const mouseMoveHandler = evt => { 57 if(!mouseState.isButtonDown) return; 58 const prevCoords = mouseState.previousCoords; 59 const newCoords = getRelativeMouseCoordsOnElement(evt); 60 document.getElementById('x').textContent = newCoords.x; 61 document.getElementById('y').textContent = newCoords.y; 62 63 // マウスが移動した方向 64 const isMovedLeft = prevCoords.x - newCoords.x > 0; 65 const isMovedRight = prevCoords.x - newCoords.x < 0; 66 const isMovedUp = prevCoords.y - newCoords.y < 0; 67 const isMovedDown = prevCoords.y - newCoords.y > 0; 68 69 // Powerの増加量 70 let gain = 0; 71 72 // 移動前は原点だった → とりあえずプラス 73 if(prevCoords.x === 0 && prevCoords.y === 0) gain = 1; 74 75 // 移動前は上の頂点だった → 右に動いたらプラス 76 if(prevCoords.x === 0 && prevCoords.y > 0) gain = isMovedRight ? 1 : -1; 77 78 // 移動前は右の頂点だった → 下に動いたらプラス 79 if(prevCoords.y === 0 && prevCoords.x > 0) gain = isMovedDown ? 1 : -1; 80 81 // 移動前は下の頂点だった → 左に動いたらプラス 82 if(prevCoords.x === 0 && prevCoords.y < 0) gain = isMovedLeft ? 1 : -1; 83 84 // 移動前は左の頂点だった → 上に動いたらプラス 85 if(prevCoords.y === 0 && prevCoords.x < 0) gain = isMovedUp ? 1 : -1; 86 87 // 移動前は右上のエリアだった → 右下に動いたらプラス 88 if(prevCoords.x > 0 && prevCoords.y > 0) gain = isMovedRight || isMovedDown ? 1 : -1; 89 90 // 移動前は右下のエリアだった → 左下に動いたらプラス 91 if(prevCoords.x > 0 && prevCoords.y <= 0) gain = isMovedLeft || isMovedDown ? 1 : -1; 92 93 // 移動前は左下のエリアだった → 左上に動いたらプラス 94 if(prevCoords.x <= 0 && prevCoords.y <= 0) gain = isMovedLeft || isMovedUp ? 1 : -1; 95 96 // 移動前は左上のエリアだった → 右上に動いたらプラス 97 if(prevCoords.x <= 0 && prevCoords.y > 0) gain = isMovedRight || isMovedUp ? 1 : -1; 98 99 const newPower = parseInt(document.getElementById('power').textContent, 10) + gain; 100 if(0 <= newPower && newPower <= 100) { 101 setPower(newPower); 102 } 103 mouseState.previousCoords = newCoords; 104}; 105 106// Powerの初期値をセット 107setPower(0); 108 109// イベント受付エリアにイベントをアサイン 110const area = document.getElementById('area'); 111area.addEventListener('mousedown', mouseDownHandler); 112area.addEventListener('mousemove', mouseMoveHandler); 113 114// マウスが離れたときの判定はbody全体で監視する 115document.body.addEventListener('mouseup', () => { 116 mouseState.isButtonDown = false; 117 mouseState.previousCoords.x = NaN; 118 mouseState.previousCoords.y = NaN; 119});
投稿2021/01/06 06:42
編集2021/01/06 06:45総合スコア2982
0
左クリックを押しながら
というのはドラッグのことでしょうか?
ドラッグの開始点から例えば右方向に引き始めても
それが右回りか、左回りかは判断できないので
下絵をなぞらせるようなUIが必要だと思います
投稿2021/01/06 00:40
編集2021/01/06 00:41総合スコア116724
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/08 08:19