大阪から日本全国のご依頼に対応。WEBサイト制作ならアトリエ涼。

お知らせ/ブログ

※当サイトは、アフェリエイト広告を利用しています。

2024.08.20

制作メモ

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

画像の一部にマウスカーソルを合わせると別の箇所の画像が変わる。
地図や見取り図などで見られるアクションです。
クリッカブルマップを使用して作られたりするのですが、レスポンシブには向いていなかったりするので、
今回はもっと簡単に実装できる、SVG画像を使用した方法をご紹介します。

マウスホバーで画像が変わる!

とあるギャラリーサイトの見取り図という設定です。
グレーのカメラマークをホバーしてみてみると、オレンジのカメラマークの箇所が変化します。

見取り図

ギャラリー見取り図

写真
写真1
写真2
写真3

CSSやjQueryも使用しているのですが、アクションの要はSVG画像の実装となります。

SVG画像とは??

拡大してもぼやけない

SVGはScalable Vector Graphics(スケーラブル・ベクター・グラフィックス)の略で、
大きさを変えられるベクター画像」という意味合いになります。

画像ファイルには、JPGやPNGがありますが
拡大するとぼやけてしまったりします。
SVGはベクターデータなため、拡大してもぼやけることはありません
Illustrator(イラストレーター)のAIファイルのような感じですが、複雑な画像には適していないファイル形式です。

CSSでスタイルを変更できる

マークアップ形式なので、CSSで色を変更したりすることができます。
JPGやPNGに比べ、データが軽量なのも特徴です。

実装の手順① 画像を用意する

必要な画像を準備して、HTML・CSS・ jQueryで実装という流れになります。

見取り図画像を用意する

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

まずは画像を作成します。
今回はIllustratorで作成しました。

SVGは複雑な画像作成には向いていないので、
マウスホバー箇所(カメラマーク)はSVGで、見取り図箇所はPNG(JPGでも可)で作成します。
PNG画像の上にSVG画像を乗せるため、画像を2枚作成する流れになります。

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜※わかりやすいように縁取りをつけていますが、実際はカラーなしで作成しています。

POINT
ここでポイントなのが、
2枚の画像の縦横の比率を同じにすることです。
比率が異なると、画像を合わせた時に描画部分がピッタリ合わずにずれてしまいます。

2枚の画像をレイヤーで分けて作成しているため、
「スクリーン用に書き出し」で書き出す際、比率が合いません。
比率を同じにするため、アートボードと同サイズの外枠(カラーなし)を作成します。

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

画像を書き出す前に、レイヤー名とグループ名を英語表記に変更します。(名称はお好みで。)
SVGを設定する際にこの名称部分が必要になるのですが、文字化け防止対策のため英語表記にします。
書き出し後に任意のものに変更してもらってもOKです。

マウスホバー箇所(photo)+外枠(box)を選択してアセットに追加します。

【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

形式をSVGにしてスクリーン用に書き出しアセットを書き出しで画像を作成します。
PNGも同様に、見取り図箇所(plan)+外枠(box)を選択してアセットに追加形式をPNGにして書き出します。

画像書き出し後、SVGデータを編集する

Visual Studio Codeなどのコードエディターやテキスト作成ツールなどでSVGデータを開きます。

<?xml version="1.0" encoding="UTF-8"?>
<svg id="_レイヤー_2" data-name="レイヤー 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 600">
<defs>
<style>
      .cls-1 {
        fill: none;
      }

      .cls-1, .cls-2, .cls-3 {
        stroke-width: 0px;
      }

      .cls-2 {
        fill: #9a9a9a;
      }

      .cls-3 {
        fill: #fff;
      }
</style>
</defs>
<g id="box">
    <rect class="cls-1" width="1500" height="600"/>
  </g>
  <g id="photo">
    <g id="img_03">
・
・
以下省略

このようなコードを確認することができます。
「box」や「photo」「img_03」といった、先ほどレイヤー名やグループ名を変更した箇所も確認できますね。
上の方のsvgのidやdata-nameも英語表記にする方がいいと思いますので、変更して保存します。

<?xml version="1.0" encoding="UTF-8"?> ←削除
<svg id="photobox" data-name="photobox" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 600">

名称はお好みで。今回はphotoboxとします。
head内で記述されていて2重になるので「?xml〜」も削除しておいてください。

変更箇所の画像を用意する

変更前と変更後の画像を作成します。
【SVGで実装!】画像の一部をマウスホバーで任意の画像が変化!〜地図・見取り図〜

見取り図のカメラマークをホバーすると、それぞれ指定の画像に変更するようにしたいので、
変更前の画像1枚と、ホバー箇所は3箇所あるので、変更後の画像を3枚作成します。
(ホバー箇所の数はお好みで変更してください。)

実装の手順② HTML・CSS・jQueryの設定をする

画像を用意した後、コーディングで実装していきます。

HTML

<div class="plan-wrap">

<div class="img-box">
<img src="../img/plan.png" alt="見取り図" />
<svg id="photobox" data-name="photobox" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 600">
<defs>
<style>
      .cls-1 {
        fill: none;
      }

      .cls-1, .cls-2, .cls-3 {
        stroke-width: 0px;
      }

      .cls-2 {
        fill: #9a9a9a;
      }

      .cls-3 {
        fill: #fff;
      }
</style>
</defs>
<g id="box">
    <rect class="cls-1" width="1500" height="600"/>
  </g>
  <g id="photo">
    <g id="img_03">
・
・
以下省略
</div>

<div class="detail-box">

<h3 class="topic">ギャラリー見取り図</h3>

<div class="photo">
<img src="../img/photo.png" alt="写真" id="ph" />
<img src="../img/photo_01.png" alt="写真1" id="ph_01" />
<img src="../img/photo_02.png" alt="写真2" id="ph_02" />
<img src="../img/photo_03.png" alt="写真3" id="ph_03" />
</div>
</div>

</div>

このようなコードを配置します。
画像は先ほど作成した見取り図画像や、変更前・変更後の画像を入れます。
classやidの名称はお好みのものに変更してください。

POINT
この時ポイントなのが、SVG画像を直書き(インラインSVG)で実装することです。
先ほど設定したグループ名を使用する必要があり、imgタグで実装しても上手く反映されません。
記述が長くなる傾向がありますので、PHPで作成の際はパーツを分けて実装するのもアリかと思います。

CSS

.plan-wrap {
  width: 100%;
  margin: 0 auto;
}
.img-box {
  width: 100%;
  position: relative;
}
.img-box img {
  width: 100%;
  margin: 0;
  -o-object-fit: contain;
     object-fit: contain;
}
.img-box svg {
  position: absolute;
  top: 0;
  left: 0;
}
.detail-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 80%;
  margin: 0 auto;
}
.detail-box h3 {
  font-size: 22px;
  padding: 0 2%;
  margin: 0;
  border-bottom: solid 2px #4CA8BC;
}
.detail-box .photo {
  display: flex;
  width: 50%;
  margin: 0;
}
.detail-box .photo img {
  background: #efefdf;
  padding: 4%;
}
.detail-box .photo #ph_01, .detail-box .photo #ph_02, .detail-box .photo #ph_03 {
  display: none;
}
.detail-box .photo .hover {
  display: block !important;
}
.detail-box .photo .hidden {
  display: none;
}

CSSで見取り図画像を重ねています。
変更前画像の非表示設定、jQueryで制御予定の「hover」「hidden」クラスの設定をしておきます。
hoverクラスの「display: block !important;」の「!important」は必ず入れてください。
記述がないと上手く反映されません。

jQuery

// 見取り図 ホバーするとクラス付与
$('#img_01').hover(
  function() {
    //カーソルが重なった時
    $(this).parents('.plan-wrap').find('#ph_01').addClass('hover');
    $(this).parents('.plan-wrap').find('#ph').addClass('hidden');
  }, function() {
    //カーソルが離れた時
    $(this).parents('.plan-wrap').find('#ph_01').removeClass('hover');
    $(this).parents('.plan-wrap').find('#ph').removeClass('hidden');
  }
);

$('#img_02').hover(
  function() {
    //カーソルが重なった時
    $(this).parents('.plan-wrap').find('#ph_02').addClass('hover');
    $(this).parents('.plan-wrap').find('#ph').addClass('hidden');
  }, function() {
    //カーソルが離れた時
    $(this).parents('.plan-wrap').find('#ph_02').removeClass('hover');
    $(this).parents('.plan-wrap').find('#ph').removeClass('hidden');
  }
);

$('#img_03').hover(
  function() {
    //カーソルが重なった時
    $(this).parents('.plan-wrap').find('#ph_03').addClass('hover');
    $(this).parents('.plan-wrap').find('#ph').addClass('hidden');
  }, function() {
    //カーソルが離れた時
    $(this).parents('.plan-wrap').find('#ph_03').removeClass('hover');
    $(this).parents('.plan-wrap').find('#ph').removeClass('hidden');
  }
);

jQueryでホバー時のアクションを設定します。
ホバーすると変更前画像が隠れて、任意の画像に変化。
離れると変更後の画像が隠れて、変更前の画像が現れます。
ホバー箇所の数に合わせて作成します。

出だしの「#img_01」「#img_02」「#img_03」はSVGで設定したグループ名です。
ここで必要になります。
findメソッドで「.plan-wrap」内から変更前・変更後の画像IDを取得して、
クラスを付与・削除しています。

以上になります。
スマホの場合は、タッチで画像が切り替わる設定となっています。

SVGって本当に便利ですよね。軽くて綺麗ですし。
これからどんどん活用方法が出てくると嬉しいなと思います。