前提・実現したいこと
HTML CSS Javascriptで、
・円周上に、外向きの八方向の矢印ボタンを配置
・矢印ボタンを押したイベントを取得
したいと考えております。
それぞれの実現方法、ライブラリなどについて何かご存知でしたら、教えていただけないでしょうか?
発生している問題・エラーメッセージ
以下の実現方法が見つけられません。
・矢印を円周上に配置
・矢印の領域だけをボタンとして認識
・左斜め上矢印(コード上の変数名target6)の表示位置がズレている
試したこと
下記方法で、8方向の矢印をCSSで作ることはできました。
https://migi.me/css/direction-size-flexible-arrow/
また下記レッスンをやることで、単純な四角形、円の領域のみをボタンとして認識させることはできました。
https://dotinstall.com/lessons/basic_javascript_v4
上記ノウハウを組み合わせて、矢印を表示しているdivにイベントリスナーclickを設定しましたが、矢印の余白をクリックしても反応してしまいます。
コード
※右矢印「=>」をクリックすると反応するようにイベントリスナーを設定しています。
コードと実行結果
https://jsfiddle.net/yamekodev/a3koyf1z/
HTML
1<head> 2<script type='text/javascript' src='https://code.jquery.com/jquery-3.5.1.min.js'> 3</head> 4 <body> 5 <section class="circle-box"> 6 </section> 7 </body>
CSS
1 .circle-box{ 2 position: relative; 3 width: 300px; 4 height: 300px; 5 margin: 100px auto; 6 background:#eee; 7 border-radius: 50%; 8 } 9 .item{ 10 position: absolute; 11 background: #aaa; 12 width: 25px; 13 height: 25px; 14 text-align: center; 15 color: #fff; 16 font-weight: bold; 17 font-size: 25px; 18 } 19 20 21.arrow { 22 display: inline-block; 23 24 /* 矢印サンプルだとrelativeだったが、円周サンプルのabsoluteに変更 */ 25 position: absolute; 26 width: 4em; 27 height: 4em; 28 color: #3388dd; 29 font-size: 30px; 30} 31.arrow:before, 32.arrow:after { 33 position: absolute; 34 top: 50%; 35 transform: translateY(-50%); 36 content: ""; 37 38} 39.arrow:before { 40 right: -1em; 41 width: 0px; 42 height: 0px; 43 44 /* 矢印の三角形の底辺の長さ */ 45 border: 1.4em solid transparent; 46 47 /* 矢印の三角形の高さ */ 48 border-left: 0.7em solid currentColor; 49} 50.arrow:after { 51 left: 0px; 52 53 /* 矢印の長方形のタテの長さ */ 54 width: 3em; 55 56 /* 矢印の長方形のヨコの長さ */ 57 height: 1.8em; 58 59 background-color: currentColor; 60} 61 62/* 縦×横×斜め 8方向分のクラス */ 63.arrow.d_u { 64 transform: rotate(270deg); 65} 66.arrow.d_ur { 67 transform: rotate(315deg); 68} 69.arrow.d_r { 70 transform: rotate(0deg); 71} 72.arrow.d_dr { 73 transform: rotate(45deg); 74} 75.arrow.d_d { 76 transform: rotate(90deg); 77} 78.arrow.d_dl { 79 transform: rotate(135deg); 80} 81.arrow.d_l { 82 transform: rotate(180deg); 83} 84.arrow.d_ul { 85 transform: rotate(215deg); 86} 87 88.clicked { 89 /* 押されたことがわかるように矢印を赤く */ 90 color: red; 91}
Javascript
1$(function(){ 2 3 //hour の arrow を .circle-box に出力 4 //for( i=0; i<8; i++){ 5 $('.circle-box').append('<div class="arrow" id="target1"></div>'); 6 $('.circle-box').append('<div class="arrow" id="target2"></div>'); 7 $('.circle-box').append('<div class="arrow" id="target3"></div>'); 8 $('.circle-box').append('<div class="arrow" id="target4"></div>'); 9 $('.circle-box').append('<div class="arrow" id="target5"></div>'); 10 $('.circle-box').append('<div class="arrow" id="target6"></div>'); 11 $('.circle-box').append('<div class="arrow" id="target7"></div>'); 12 $('.circle-box').append('<div class="arrow" id="target8"></div>'); 13 //} 14 15 const target1 = document.getElementById('target1'); 16 const target2 = document.getElementById('target2'); 17 const target3 = document.getElementById('target3'); 18 const target4 = document.getElementById('target4'); 19 const target5 = document.getElementById('target5'); 20 const target6 = document.getElementById('target6'); 21 const target7 = document.getElementById('target7'); 22 const target8 = document.getElementById('target8'); 23 24 target1.classList.add('d_r'); // → 25 target2.classList.add('d_dr'); // →↓ 26 target3.classList.add('d_d'); // ↓ 27 target4.classList.add('d_dl'); // ←↓ 28 target5.classList.add('d_l'); // ← 29 target6.classList.add('d_ul'); // ←↑ 30 target7.classList.add('d_u'); // ↑ 31 target8.classList.add('d_ur'); // ↑→ 32 33 //arrowの親要素の半径を計算 34 var r = $('.circle-box').width()/2; 35 36 //arrow要素数から角度を計算 37 var angle = 360/$('.arrow').length; 38 39 //arrow要素の幅,高さの2分の1を取得 40 var l = $('.arrow').width()/2; 41 var h = $('.arrow').height()/2; 42 43 //指定 44 $(".arrow").each(function(i, elem) { 45 46 var deg = angle * i; 47 //console.log(deg); 48 49 //x,y座標の取得 50 var x = Math.cos(deg*Math.PI/180)*r+r; 51 var y = Math.sin(deg*Math.PI/180)*r+r; 52 53 //円周上を中心に配置されるよう位置を指定 54 $(".arrow").eq(i).css("left",x-l); 55 $(".arrow").eq(i).css("top",y-h); 56 57 }); 58 59 //hour 1が先頭に来るようにする 60// $(".arrow").each(function(i) { 61// $(this).text(i+3); 62// var a = $(this).text(); 63// 64// if( a > 8){ 65// $(this).text(a - 8); 66// } 67// }); 68 69 target1.addEventListener('click', () => { 70 target1.textContent = "clicked"; 71 target1.classList.toggle('clicked'); 72 }); 73// target1.classList.add('d_r'); // → 74// target2.classList.add('d_dr'); // →↓ 75// target3.classList.add('d_d'); // ↓ 76// target4.classList.add('d_dl'); // ←↓ 77// target5.classList.add('d_l'); // ← 78// target6.classList.add('d_ul'); // ←↑ 79// target7.classList.add('d_u'); // ↑ 80// target8.classList.add('d_ur'); // ↑→ 81 82 83});
補足情報(FW/ツールのバージョンなど)
chrome
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー