0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第09回 SVG 複数のアイコン画像を1つのSVGにまとめる

Posted at

はじめに

今回は、1つのSVGファイルに複数のアイコン画像をまとめてみようと思います。
1つにまとめることで、

  • 全体としてSVGファイルのサイズが小さくなりそうなこと
  • HTMLとSVG読み込み時に読み込みファイル数が減ること
  • 1つのアイコンに色々なものを準備してバリエーションをもたすことができること(例:ホームアイコンの種類を複数作るみたいなイメージ)
  • および、一部のSVG読み込みできず、一部のアイコンだけ表示されないことを防ぐことができること

など、まとめたほうがよいことがあるのかなと思いました。
この4つ目の利点については、第20回 JavaScript モーダルサイドバーの共通化でサイドバーを作成した時に、アイコンをで作ろうと思ったときにSVGで作成すれば、ひとつにまとめらえるなと考えていました。
ということで、この20回のソースを使用してアイコンを設定していきます。

今回実施する内容

これまでに作成した以下のアイコン画像を1つのSVGファイルにまとめます。さらにそれをサイドバーに実装します。

image.png

plural.gif

ソースコード(Git Hub)

環境

OS: Windows 11 JP (64bit)
Edge: バージョン 140.0.3485.81 (公式ビルド) (64 ビット)

参考

用語

基本(ソースは01フォルダ)

ファイル試合はシンプルです。
menu.htmlからmenuIcon.svgを読み込んで、3つのアイコンをIDを指示して表示させます。

menu.htmlの抜粋
  <div id="menuIcon">
    <svg width="48px" height="48px">
      <use xlink:href="menuIcon.svg#hamburgerIcon"></use>
    </svg>
  </div>
  <div id="homeIcon">
    <svg width="48px" height="48px">
      <use xlink:href="menuIcon.svg#homeIcon"></use>
    </svg>
  </div>
  <div id="myPageIcon">
    <svg width="48px" height="48px">
      <use xlink:href="menuIcon.svg#myPageIcon"></use>
    </svg>
  </div>
menuIcon.svg
<?xml version="1.0" standalone="no"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <symbol id="hamburgerIcon" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
      <path d="M9 10 L24 10" stroke="black" stroke-width="2" />
      <path d="M9 16 L24 16" stroke="black" stroke-width="2" />
      <path d="M9 22 L24 22" stroke="black" stroke-width="2" />
    </symbol>
    <symbol id="homeIcon" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
      <path d="M16 7 L17 7 L26 16 L26 17 L23 17 L23 26 L18 26 L18 20 L15 20 L15 26 L10 26 L10 17 L7 17 L7 16 z"/>
    </symbol>
    <symbol id="myPageIcon" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
      <circle cx="16" cy="12" r="6" fill="none" stroke-width="2" stroke="#000" />
      <path d="M 8 25 a 8 7 0 1 1 16 0" stroke-width="2" fill="none" stroke="#000" />
    </symbol>
  <defs>
</svg>

menu.htmlの内容

use要素を使用して、`menuIcon.svgの各IDを呼び出すように設定するだけです。

menuIcon.svgの説明

今回は、defs要素を使用して最初にまとめました。defs要素自体は設定しなくても、今回の動作に何の影響を与えることはありませんが、定義の場所を明確化するために使用するもののようなので、従いました。
defs要素の配下は、symbol要素を使用して、symbol要素の配下に各アイコンの内容を記載しました。
アイコンの内容は、「参考」にも記載した過去の記事を参照ください。

サイドバーと組み合わせる(ソースは02フォルダ)

第20回 JavaScript モーダルサイドバーの共通化では、Webサイトでよく使われるサイドバーを作りました。

違いは、sideBar.js部分であるため、ここを紹介します。

sideBar.jsの抜粋
window.addEventListener("DOMContentLoaded", () => {
    let strHtml = `\n`;
    strHtml += `\t<svg class="menuIcon" id="menuIcon">\n`;
    strHtml += `\t\t<use xlink:href="menuIcon.svg#hamburgerIcon" />\n`;
    strHtml += `\t</svg>\n`;
    strHtml += `\t<div id="sideBar">\n`;
    strHtml += `\t\t<svg  class="menuIcon" id="menuIcon2">\n`;
    strHtml += `\t\t\t<use xlink:href="menuIcon.svg#hamburgerIcon" />\n`;
    strHtml += `\t\t</svg>\n`;
    strHtml += `\t\t<div id="menuList">\n`;
    strHtml += `\t\t\t<div id="home" class="menuItem">\n`;
    strHtml += `\t\t\t\t<svg width="48px" height="48px">\n`;
    strHtml += `\t\t\t\t\t<use href="menuIcon.svg#homeIcon" />\n`;
    strHtml += `\t\t\t\t</svg>ホーム</div>\n`;
    strHtml += `\t\t\t<div id="mypage" class="menuItem">\n`;
    strHtml += `\t\t\t\t<svg width="48px" height="48px">\n`;
    strHtml += `\t\t\t\t\t<use href="menuIcon.svg#myPageIcon" />\n`;
    strHtml += `\t\t\t\t</svg>マイページ</div>\n`;
    strHtml += `\t\t</div>\n`;
    strHtml += `\t</div>\n`;
    strHtml += `\t<div id="cover" class="cover"></div>\n`;
    menuSideBar.insertAdjacentHTML("beforeend", strHtml);

window.addEventListener("DOMContentLoaded",...の部分が、画面読み込み時に処理される内容です。
strHtmlがサイドバーを読み込みするためのHTMLを文字列で記載したものです。
第回との違いを示しながら説明します。

メニューアイコン(ハンバーガーアイコン)

image.png

第20回のsideBar.jsのハンバーガーアイコン部分
    strHtml += `\t<img src="humbergerIcon.svg" id="menuIcon" class="menuIcon"/>\n`;

これが、↓のように。

今回のsideBar.jsのハンバーガーアイコン部分
    strHtml += `\t<svg  class="menuIcon" id="menuIcon">\n`;
    strHtml += `\t\t<use xlink:href="menuIcon.svg#hamburgerIcon" />\n`;
    strHtml += `\t</svg>\n`;

元々はimg要素からhumbergerIcon.svgを呼び出していましたが、今回はsvg要素を使用してアイコンをまとめたmenuIcon.svgを使用して#hamburgerIconを呼び出しています。
どうでもよいですが、ハンバーガーのスペルが間違っていたため、今回は修正しました。

サイドバーのメニュー

image.png

第20回のsideBar.jsのサイドバーメニュー部分
    strHtml += `\t\t<img src="humbergerIcon.svg" id="menuIcon2" class="menuIcon"/>\n`;
    strHtml += `\t\t<div id="menuList">\n`;
    strHtml += `\t\t\t<div id="home" class="menuItem">ホーム</div>\n`;
    strHtml += `\t\t\t<div id="mypage" class="menuItem">マイページ</div>\n`;
    strHtml += `\t\t</div>\n`;

これが、↓のように。

今回のsideBar.jsのサイドバーメニュー部分
    strHtml += `\t\t<svg class="menuIcon" id="menuIcon2">\n`;
    strHtml += `\t\t\t<use xlink:href="menuIcon.svg#hamburgerIcon" />\n`;
    strHtml += `\t\t</svg>\n`;
    strHtml += `\t\t<div id="menuList">\n`;
    strHtml += `\t\t\t<div id="home" class="menuItem">\n`;
    strHtml += `\t\t\t\t<svg width="48px" height="48px">\n`;
    strHtml += `\t\t\t\t\t<use href="menuIcon.svg#homeIcon" />\n`;
    strHtml += `\t\t\t\t</svg>ホーム</div>\n`;
    strHtml += `\t\t\t<div id="mypage" class="menuItem">\n`;
    strHtml += `\t\t\t\t<svg width="48px" height="48px">\n`;
    strHtml += `\t\t\t\t\t<use href="menuIcon.svg#myPageIcon" />\n`;
    strHtml += `\t\t\t\t</svg>マイページ</div>\n`;
    strHtml += `\t\t</div>\n`;

元々はホームやマイページにアイコン事態存在しなかったため、アイコンを設定するようにしました。
今回作成したmenuIcon.svgにIDを設定して読み出すようにしています。
ハンバーガーアイコンのSVG要素ではwidthheihgt属性を設定していませんでしたが、ホームやマイページのSVGでは設定しました。これは、少し理由があり、ハンバーガーアイコンでは、sideBar.css.menuIconで、widthheightを設定しているため、sideBar.js上で設定しなくてもサイズが確定できているのに対して、新たに作成したホームやマイページではCSSがないため、sideBar.js上でwidthheightを設定する必要性がありました。
設定をCSS上に持っていくことも可能ですが、今回の説明であまり関係のない設定をほかのファイルに波及するのを避けたかったためこのようにしました。
が、後述する部分で結局CSSファイルを直してしまったのですが・・・

sideBar.cssの修正

CSSを変更せずに実装すると以下のようにアイコンと文字が上下中央に合わなかったため、CSSを一か所修正しました。
image.png

sideBar.css
.menuItem {
  width: 180px;
  display:flex;
  padding-left: 10px;
  padding-right: 10px;
  padding-top: 10px;
  padding-bottom: 10px;
  align-items: center;
  height: 48px;

.menuItemdisplay:flexalign-items:centerを追加しました。

おわりに

複数のアイコン画像を1つのSVGにまとめてみました。
また、サイドバー上のメニューにそのアイコンを設定しました。
第20回のサイドバーの記事は2024年9月投稿だったため、ほぼ一年かけて、やりたかったことを実装できたなという感じでした。

今回の修正では、widthheightsideBar.jsに含まれており、当時の作った感じだと画面の調整はCSSで実施するという方針だったと思うので、その辺はそのうち直したいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?