2014/08/27
HTML5のCanvasでレスポンシブなリンク – 多角形編
今回は多角形について、HTML5のCanvasでレスポンシブに対応したリンクをつける方法をご紹介いたします。
↓こちらがDEMOです
方法
1.Canvasの準備をする。
こちらは前回までと同じ方法です。
1 2 3 | <div class="wrapper"> <canvas id="visual" width="900" height="400"></canvas> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .wrapper{ width: 960px; padding: 30px; margin: 0 auto; } @media only screen and (max-width: 960px){ .wrapper{ width: auto; padding: 10px; } canvas{ width: 100%; } } |
2.描画、リンクさせる要素の設定をする
今回は多角形ですので、X座標(横方向の位置)とY座標(縦方向の位置)を不特定の個数、配列で設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $(function(){ //canvasに描画する円弧の設定 var canvasElement = { elm1 : { x : [ 402, 463, 543, 496, 527, 432, 377, 376, 313, 383 ], //多角形の各x座標 y : [ 67, 141, 118, 199, 283, 240, 302, 221, 167, 140 ], //多角形の各y座標 color : "#f3c04f", //多角形の色 href : "index3-c1.html" //リンク先 }, elm2 : { x : [ 742, 767, 803, 784, 795, 755, 729, 728, 702, 734 ], //多角形の各x座標 y : [ 240, 271, 261, 298, 335, 316, 345, 307, 284, 271 ], //多角形の各y座標 color : "#50b3df", //多角形の色 href : "index3-c2.html" //リンク先 }, elm3 : { x : [ 217, 263, 124, 42, 41, 0, 0, 260 ], //多角形の各x座標 y : [ 70, 196, 130, 224, 101, 68, 0, 1 ], //多角形の各y座標 color : "#e17170", //多角形の色 href : "index3-c3.html" //リンク先 } }; ・・・ |
3.多角形を描画する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ・・・ //canvasの描画 var canvas = document.getElementById("visual"); if(canvas.getContext){ var ctx = canvas.getContext('2d'); for(elmKey in canvasElement){ //設定した要素の数だけ繰り返す ctx.beginPath(); //パスの設定を開始 ctx.moveTo(canvasElement[elmKey].x[0], canvasElement[elmKey].y[0]); for(i = 1; i <= canvasElement[elmKey].x.length; i++){//設定したパスの数だけ繰り返す ctx.lineTo(canvasElement[elmKey].x[i], canvasElement[elmKey].y[i]);//パスの設定 } ctx.closePath(); ctx.fillStyle = canvasElement[elmKey].color; //色の設定 ctx.fill(); //多角形の塗りつぶし } } ・・・ |
2で設定した値をもとに、多角形を描画します。
前回までと同様に、FOR IN文を使って、設定した1階層目のプロパティの数繰り返すようにします。
.begenPath() で多角形の描画を開始
.moveTo([始点のX座標], [始点のY座標])で多角形の開始点を設定。
パスはFOR IN文を使って、設定した多角形のパスの数から開始点を除いた分だけ繰り返します(開始点は設定済みのため)。
それぞれのパスは .lineTo([多角形のパスのX座標], [多角形のパスのY座標]) で設定。
.closePath() で多角形のパスを閉じ、
前回までと同様に、.fillStyleで塗りつぶしの色を設定して、
.fill()で多角形を塗りつぶします。
4.リンクの設定と実行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ・・・ /*---------------------- canvasのクリックの設定 ----------------------*/ //canvasの基準になる大きさ(width属性で設定した値)を取得 var canvasBaseWidth = $("canvas").attr("width"); $("canvas").click(function(e){ var canvasWidth = $("canvas").width(); //canvasをクリックした時点での、canvasの大きさを取得 var ratioSize = canvasWidth / canvasBaseWidth; //縮小率を計算 //マウス情報の取得と設定 var rect = e.target.getBoundingClientRect(); var mx = e.clientX - rect.left; var my = e.clientY - rect.top; for(elmKey in canvasElement){ //canvasの描画で設定した要素の数だけ繰り返す tgPoint = { //マウス座標を縮小率で割った座標を判定に利用 x : mx / ratioSize, y : my / ratioSize } if(isPointInPolygon(canvasElement[elmKey], tgPoint)){ location.href = canvasElement[elmKey].href; } } }); }); //多角形の内外判定(多角形の内側をクリックしていたら、0以外を返す) function isPointInPolygon(tgPoly, tgPoint){ cn = 0; if(tgPoint.x <= tgPoly.x[0]){var xFlag0 = true}else{var xFlag0 = false}; if(tgPoint.y <= tgPoly.y[0]){var yFlag0 = true}else{var yFlag0 = false}; point0 = { x : tgPoly.x[0], y : tgPoly.y[0] } tgPoly.x[tgPoly.x.length] = tgPoly.x[0]; tgPoly.y[tgPoly.y.length] = tgPoly.y[0]; for(i = 1; i < tgPoly.x.length ; i++){ if(tgPoint.x <= tgPoly.x[i]){var xFlag = true}else{var xFlag = false}; if(tgPoint.y <= tgPoly.y[i]){var yFlag = true}else{var yFlag = false}; if(yFlag0 != yFlag){ if(xFlag0 == xFlag){ if(xFlag0){ if(yFlag0){cn--}else{cn++} } }else{ if(tgPoint.x <= (point0.x + (tgPoly.x[i] - point0.x)*(tgPoint.y - point0.y)/(tgPoly.y[i] - point0.y))){ if(yFlag0){cn--}else{cn++} } } } point0 = { x : tgPoly.x[i], y : tgPoly.y[i] } xFlag0 = xFlag; yFlag0 = yFlag; } return cn; } |
リンクの設定手順は次の通りです。
- Canvasの元の大きさ(htmlのwidth属性で設定した値)を取得しておく
- Canvas上でクリックしたときに、クリック時の実際のCanvasサイズを取得し、元の大きさからの縮小率を計算
- Canvas上のマウスの位置を取得し、縮小率を反映したものを判定の値に設定
- 始めに設定した円弧の位置とクリックした位置が一致する場合、設定したリンクに移動
4の多角形とクリックした位置の判定はこれまでの矩形や円弧と異なって、やや複雑となるため、
↓こちらのサイトで紹介いただいていた関数をJavaScriptに置き換えたものを利用して行いました。
こちらの多角形のリンクを利用すれば、ある程度複雑な形状のリンクにも対応することができます。
↓矩形(四角)編はこちら
HTML5のCanvasでレスポンシブなリンク – 矩形(四角)編
↓円弧編はこちら
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE