154 views
1. やりたいこと
画面上の非矩形な領域をマウスホバーした時に、何らかの反応をさせたい。
2. やってみる
方法1 : ベクタ画像データを使う
下記コードの実装例はこちら。
https://www.dogrow.net/hp/sample/00149/01/
(1) index.html
<!DOCTYPE html> <html> <head> <title>Blog No.148-1</title> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body> <div class="imgArea"> <img id="imgBg" src="./bg_snow_jutaku.jpg" alt="" /> <object id="item1" class="fimg" type="image/svg+xml" data="./myimg_1.svg" data-pup="pup1"></object> <div id="pup1" class="pup">パックマン?</div> <object id="item2" class="fimg" type="image/svg+xml" data="./myimg_2.svg" data-pup="pup2"></object> <div id="pup2" class="pup">セキセイインコたち</div> </div> </body> </html>
(2) script.js
document.addEventListener("DOMContentLoaded", function() { var elem_fimgs = document.querySelectorAll('object.fimg'); elem_fimgs.forEach(function(elem) { elem.addEventListener('load', function() { const svgDoc = this.contentDocument; const svgElem = svgDoc.querySelector('polygon'); const pup_id = elem.getAttribute('data-pup'); const pupElem = document.getElementById(pup_id); if(svgElem && pupElem){ svgElem.addEventListener('mouseover', function(ev) { svgElem.style.cursor = 'pointer'; elem.classList.add('anim_blink'); }); svgElem.addEventListener('mouseout', function(ev) { svgElem.style.cursor = ''; elem.classList.remove('anim_blink'); pupElem.style.display = 'none'; }); svgElem.addEventListener('click', function(ev) { pupElem.style.display = 'inline-block'; }); } }); }); });
(3) SVG画像
Adobe Illustratorで編集、出力した SVG画像をそのまま使った。
<?xml version="1.0" encoding="UTF-8"?> <svg id="_レイヤー_2" data-name="レイヤー 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 167.23 201.14"> <defs> <style> .cls-1 { fill: #3072b9; stroke-width: 0px; } </style> </defs> <g id="_レイヤー_1-2" data-name="レイヤー 1"> <image width="720" height="866" transform="scale(.23)" xlink:href="myimg_1.png"/> <polygon class="cls-1" style="opacity:0" points="48.7 0 0 63.24 0 149.4 67.57 201.14 167.23 147.48 76.48 106.41 158.27 42.97 48.7 0"/> </g> </svg>
(4) style.css
*{ margin: 0; padding: 0; box-sizing: border-box; } div.imgArea{ position: relative; margin: 1rem; border: 3px #000 solid; line-height: 0; } img#imgBg{ width: 100%; } .anim_blink { animation: kf_blink 1s infinite; } @keyframes kf_blink { 0% { opacity: 1; } 50% { opacity: 0.1; } 100%{ opacity: 1; } } div.pup{ position: absolute; background-color: #fffff8; box-shadow: 2px 2px 4px rgba(0,0,0,0.5); border-radius: 0.5rem; padding: 1rem; display: none; } #item1{ position: absolute; top: 10%; left: 20%; width: 10%; } #pup1{ top: 12%; left: 30%; } #item2{ position: absolute; top: 70%; left: 60%; width: 15%; } #pup2{ top: 72%; left: 75%; }
方法2 : ラスタ画像データを使う
背景透過の PNG画像を使用する。
ポイントした座標の画素値を参照し、αチャネルの値が0であれば背景であると判断する。
ポイントした座標の画素値を参照し、αチャネルの値が非0であれば画像上と判断する。→ 反応させる。
↓↓↓
実際に実装して動かしてみたが…
・コード量が多く複雑になる。
・画素値参照による処理負荷が大きい。
よって…
今回は上述の「ベクタ画像データを使う」を採用することにした。