#author("2020-04-20T14:08:07+09:00","","") #author("2020-04-25T00:38:37+09:00","","") ** colorscheme.inc.php [#yb4fe125] |RIGHT:100|LEFT:360|c |~サマリ|OSのカラースキームに応じてダークモード表示する| |~リビジョン|1.02| |~リビジョン|1.03| |~対応バージョン|1.5.3| |~投稿者|[[M.Taniguchi]]| |~投稿日|&new{2020-04-18 (土) 05:16:48};| **概要 [#m7fbf214] ウィキをOSのカラースキーム(カラーテーマ)に対応させ、ダークモード表示を簡易的に実現するプラグイン。~ PukiWiki 1.5.3/PHP 7.4 で動作確認済み。旧バージョンでもおそらく動くと思います。 **使い方 [#v284e893] -&colorscheme; … 選択ボックスが表示され、自動切替モード(※)・ライトモード・ダークモードを選ぶことができる。選んだモードはブラウザーに記憶される。 -#colorscheme … ユーザーインターフェイスなし、自動切替モード固定。 ※ OSないしブラウザーのカラースキームに応じて自動的に変化するモード。 ''ご注意'' -本プラグインは、MenuBar など全画面共通で表示されるページに挿入してください。もしくは、次のコードをスキンファイル(skin/pukiwiki.skin.php等)HTML内の適当な場所に挿入してください。 <?php if (exist_plugin_convert('colorscheme')) echo do_plugin_convert('colorscheme', 1); ?> -本プラグインを挿入できるのは1ページにつき1箇所のみです。 -逆効果になるため、もともと暗い色調のスキンや、カラースキームに対応済みのスキンとは併用しないでください。 -JavaScriptが有効でないと動作しません。 -古いブラウザーでは動作しない場合があります。 **コード [#ged94a07] colorscheme.inc.php~ (下記のコードをコピーして、plugin ディレクトリに colorscheme.inc.php というファイル名で保存してください) <?php /* PukiWiki - Yet another WikiWikiWeb clone. colorscheme.inc.php, v1.02 2020 M.Taniguchi colorscheme.inc.php, v1.03 2020 M.Taniguchi License: GPL v3 or (at your option) any later version ウィキをOSのカラースキーム(カラーテーマ)に対応させ、ダークモード表示を簡易的に実現するプラグイン。 【使い方】 &colorscheme; … 選択ボックスが表示され、自動切替モード(※)・ライトモード・ダークモードを選ぶことができる。選んだモードはブラウザーに記憶される。 #colorscheme … ユーザーインターフェイスなし、自動切替モード固定。 ※ OSのカラースキームに応じて自動的に変化するモード。 【ご注意】 ・本プラグインは、MenuBarなど全画面共通で表示されるページに挿入してください。もしくは、次のコードをスキンファイル(skin/pukiwiki.skin.php等)HTML内の適当な場所に挿入してください。 <?php if (exist_plugin_convert('colorscheme')) echo do_plugin_convert('colorscheme', 1); ?> ・本プラグインを挿入できるのは1ページにつき1箇所のみです。 ・逆効果になるため、もともと暗い色調のスキンや、カラースキームに対応済みのスキンとは併用しないでください。 ・JavaScriptが有効でないと動作しません。 ・古いブラウザーでは動作しない場合があります。 */ define('PLUGIN_COLORSCHEME_EXCLUSION', '#contents img, #contents video, object, embed, iframe'); // 明暗反転処理を除外する要素のセレクター(ヘッダ画像も除外するなら「#contents 」を省く) define('PLUGIN_COLORSCHEME_BRIGHTNESS', '85%'); // ダークモード時の画面輝度(0%~100%) function plugin_colorscheme_convert() { list($ui) = func_get_args(); return plugin_colorscheme_output($ui); } function plugin_colorscheme_inline() { return plugin_colorscheme_output(true); } function plugin_colorscheme_output($ui) { if (!PKWK_ALLOW_JAVASCRIPT) return ''; static $included = false; if ($included) return ''; $included = true; $style = 'body{background-color:#000;filter:invert(100%) hue-rotate(180deg) brightness(' . PLUGIN_COLORSCHEME_BRIGHTNESS . ')}' . PLUGIN_COLORSCHEME_EXCLUSION . '{filter:invert(100%) hue-rotate(180deg)}'; if (!$ui) { $body = '<style>@media screen and (prefers-color-scheme: dark), screen and (light-level: dim){' . $style . '}</style>'; } else { $body = <<<EOT <select id="PluginColorSchemeUI"><option value="0">Auto</option><option value="1">Light</option><option value="2">Dark</option></select> <script> __PluginColorScheme__ = function() { const self = this; const ui = document.getElementById('PluginColorSchemeUI'); var mode = parseInt(localStorage.getItem('pluginColorScheme.mode')) || 0; self.change(mode); ui.options[mode].selected = true; ui.addEventListener('change', function(e) { self.change(parseInt(e.srcElement.value)); }); }; __PluginColorScheme__.prototype.change = function(mode) { const doc = document.getElementsByTagName('body')[0]; const id = '__DarkModePluginStyle__'; const style = '${style}'; localStorage.setItem('pluginColorScheme.mode', mode); var v = document.getElementById(id); if (v) v.remove(); if (v) { if (v.remove) v.remove(); else v.parentNode.removeChild(v); // IE対策 } v = (mode == 0)? '@media screen and (prefers-color-scheme: dark), screen and (light-level: dim){' + style + '}' : ((mode == 2)? style : ''); if (v) doc.insertAdjacentHTML('beforeend', '<style id="' + id + '">' + v + '</style>'); }; new __PluginColorScheme__(); </script> EOT; } return $body; } **処理の詳細 [#b5398a7c] ***カラースキーム [#x5512aee] カラースキームの自動判定には、CSSメディアクエリー・レベル5の「prefers-color-scheme」および「light-level」を利用しています。~ 対応状況や反映・設定の仕方はブラウザーやOSに依存しますが、主要なモダンブラウザー・OSは軒並み対応しています。~ ***ダークモード [#madb76a7] ダークモード表示は、CSSフィルターにより画面の明暗を反転することで実現しています。~ 具体的には、「body { filter: invert(100%) hue-rotate(180deg) brightness(85%) }」です。~ ネガポジ反転したうえで、色相を逆転することで色合いをなるべく保ちます。~ 加えて、全体の輝度を下げます(輝度のパーセンテージはコード内の PLUGIN_COLORSCHEME_BRIGHTNESS 定数で指定)。~ ただし、ページ内の画像等はさらに反転して元のまま表示します(対象となる要素はコード内の PLUGIN_COLORSCHEME_EXCLUSION 定数で指定)。~ ***設定の保存 [#j86194f1] 選択ボックスで選んだモードは、クッキーではなくブラウザーのローカルストレージ(Web Storage API)に保存しています。~ 秘密情報ではないので無条件に保存し、また極めて単純なためわざわざユーザーに紐付けてサーバー側で保存するようなこともしません。~ なお、ローカルストレージも主要モダンブラウザーであればいずれも対応しています。 ***相性について [#aafbc1f1] 明暗を反転するだけなので、スキンの内容によっては相性が悪いこともあり得ます。~ また、使用しているフォントやOS・ブラウザーによっては文字が見づらくなる場合があります。~ 作者が試した範囲では、Windows版Chromeはフォント描画があまりきれいではなく、標準スキンを本プラグインでダークモード表示したところ、黒地に白の本文がちらついて見えました。~ したがって、ダークモードを強制しないよう、選択ボックスを表示すること(&colorscheme; のほう)を勧めます。 **ライセンス [#d05a04c3] GPL v3