PageMenuにお手軽アイコン利用を許可するCSS
利用例
https://gyazo.com/295a68b9fe1fe016282e507bdf996847
再生マーク・PDFマークは僕の設定したものではありません
PageMenuにボタンを追加するとき、ボタンアイコンに用いる画像URLの指定を求められます。 code:script.js
scrapbox.PageMenu().addMenu({
title: "Button Title",
image: "Image URL",
onClick: () => {}
});
しかし、指定したい画像が、あなたの好むScrapboxの色調やデザインに真向から食い違っていたらどうでしょうか。別の配色の画像をいちいち用意するのは面倒です。しかし、もしフォントアイコンを利用できれば、要素に適用するフォントカラーを変更するだけで解決できます。それに、Scrapboxはデフォルトで複数のアイコンファイルを読み込んでいます。それを手軽に利用できないのも惜しいことです。 そこで今回は、ScrapboxがデフォルトでPageMenuアイコンに利用しているフォントや、Font Awesome 5 Freeを利用することで、洗練されたアイコンを簡単に利用できるようにUserCSSを設定します。これで、従来の画像URLを指定する方法を邪魔することもありません。 インストール
以下をユーザーページやプロジェクトsettingsに貼り付けてご利用ください。
code:style.css
@import "/api/code/public-minaph/PageMenuにお手軽アイコン利用を許可するCSS/main.css";
使い方
まず、使いたいアイコンのコードポイントを手に入れます。
16進数で4桁です。
こちらFont Awesomeの検索リンクからアイコンを検索するか、または以下の一覧から好きなアイコンを選んでください。 https://gyazo.com/375cd4cfde2afce28ac16781fee7ff9f
https://gyazo.com/a7345d809122473d2dda64f0eeee8981
この画像から選ぶ場合は、左下の数字を16進数表記に変換して0xE000に足してください。
Font Awesomeのサイトの場合、アイコンを選択するとページ上部にコードポイントが表示されます
上記でインストールしたUserCSSは画像srcに設定されたアイコン情報を読み込みます。
以下の形式でPageMenuを登録してください
code:script.js
scrapbox.PageMenu().addMenu({
title: "Button Title",
image: "\uXXXX", // XXXX is your icon codepoint
onClick: () => {}
});
開発
デフォルトのページメニューのボタンには、Scrapboxがロードしているフォントファイルが適用されています。woff2だと手軽なビューワーが対応していない場合が多いので、TTFファイルにコンバートして中身を見てみましょう。 ちなみに、このフォントはfontelloで作成されたカスタムフォントのようですね https://gyazo.com/375cd4cfde2afce28ac16781fee7ff9f
https://gyazo.com/a7345d809122473d2dda64f0eeee8981
コードポイントは0xE000から順に配置されています。各マス目左下の番号を16進表記に変換し、0xE000に足し算することでコードポイントが求まるということですね。
ではこれを実際に使っていきましょう。
PageMenuにボタンを追加する場合の通常のスクリプトは以下の形式です
code:script.js
scrapbox.PageMenu().addMenu({
title: "Button Title",
image: "Image URL",
onClick: () => {}
});
コードポイントを指定するというのはそもそも想定されている使い方ではないので、少しハックします。今回は便宜を考え、以下の形式で利用できるようにCSSを設定するということにします。
code:script.js
scrapbox.PageMenu().addMenu({
title: "Button Title",
image: "\uXXXX", // Your Icon Codepoint
onClick: () => {}
});
これを実際に読み込むと、新しくボタンが配置され、その中にimg要素が用意されます。そのsrc属性に指定したアイコン(のコードポイント)が設定されています(もちろん、開発者ツールなどで見ても文字化けして、アイコンだとはわかりませんが)。画像srcに登録されたコードポイントをうまく表示しつつ、上記で説明したアイコンフォントを適用すれば、アイコンが見事ボタンとして表示されるようになるというわけです。
ところで、Scrapboxにもとから配置されているボタンを見てみると、アイコンは.kamonクラスのついたThe Idiomatic Text element(<i>)の::before擬似要素を使って表示しているみたいです。公式が.kamonに設定したCSSを拝借しながら、以下のようにCSSを書いてみました。 code:main.css
@import "fix.css";
img.extension-btn::before {
/* アイコンを中心に表示 */
content: attr(src); /* ここでsrcを表示 */
position: relative;
top: calc(50% - 12px);
left: calc(50% - 12px);
vertical-align: middle;
/* 画像を描画範囲から追い出す */
display: block;
margin-bottom: 100%;
/* .kamon rules */
width: 24px;
height: 24px;
line-height: 24px;
font-size: 24px;
/* display: inline-block; */
/* .kamon::before rules */
font-family: "AppIcons";
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-style: normal;
font-variant: normal;
font-weight: normal;
text-decoration: none;
text-transform: none;
}
/* 追い出された部分は表示しない */
overflow: hidden;
display: inline-block;
}
これで、前述の登録方法で簡単にアイコンを使えるようになりました。これをいちいちUserScriptで設定しようと思ったら大変ですね。 ついでにfont-familyにFont Awesome 5 Freeを追加しておきました。Font Awesomeで使える16001200のアイコンのうち4つだけはコードポイントが重複しているので利用できませんが、これで使えるアイコンが大幅に増えました。 Font Awesome 5 Freeの表示に問題があったので、このフォントの導入は下記に分離しました。
CSSの細部について説明しておきます。
画像srcにアイコンを設定するため、もちろん画像が読み込みエラーになります。そこで読み込みエラーになった画像本体を非表示にします。:not(src*='.'):not(src*='/'):not(src*=':')によって、imgがドット、スラッシュ、コロンのどれも含んでいないsrcを設定していれば、アイコンを設定していると判定して非表示にします。具体的には、描画範囲を制御しているimg要素にoverflow: hidden;を設定しつつ、imgの描画範囲から本来の画像を追い出し、CSS擬似要素に描画範囲を独占させることでアイコン表示にしています。擬似要素は表示する必要があるので、img要素にdisplay: none;を利用できず、ちょっと工夫が必要な部分でした。
画像の疑似要素は画像が読み込み不可だった場合にのみ表示される挙動で、今回の実装では大変役に立ちました。
2021/12/3 追記
ついでにコメントを増やし、CSSを大幅にリファクタリングしました。この一連の苦闘を経てずいぶんとCSSには詳しくなれました。
code:fix.css
/* hover fix */
text-decoration: none;
}
img.extension-btn::after {
display: inline-block;
/* アイコンを中心に表示 */
content: attr(src);
position: absolute; /* not relative */
top: calc(50% - 12px);
left: calc(50% - 12px);
vertical-align: middle;
/* font awesome setup */
font-family: "Font Awesome 5 Free";
font-weight: 600;
/* .kamon rules */
width: 24px;
height: 24px;
line-height: 24px;
font-size: 24px;
/* display: inline-block; */
/* .kamon::before rules */
/* font-family: "AppIcons"; */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-style: normal;
font-variant: normal;
/* font-weight: normal; */
text-decoration: none;
text-transform: none;
}
2021/10/02追記
あるはずのアイコンが指定できないので、おかしいなと思って実際にロードしているFont Awesomeを調べてみました
1600件というのは誤りで、正しくは1200件程度でした
無料アイコンのうちregularとsolidというカテゴリのものだけが使えるようです。