colorscheme.inc.php

サマリOSのカラースキームに応じてダークモード表示する
リビジョン1.03
対応バージョン1.5.3
投稿者M.Taniguchi
投稿日2020-04-18 (土) 05:16:48

概要

ウィキをOSのカラースキーム(カラーテーマ)に対応させ、ダークモード表示を簡易的に実現するプラグイン。

PukiWiki 1.5.3/PHP 7.4 で動作確認済み。旧バージョンでもおそらく動くと思います。

使い方

※ OSないしブラウザーのカラースキームに応じて自動的に変化するモード。

ご注意

コード

colorscheme.inc.php
(下記のコードをコピーして、plugin ディレクトリに colorscheme.inc.php というファイル名で保存してください)

<?php
/*
PukiWiki - Yet another WikiWikiWeb clone.
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) {
		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;
}

処理の詳細

カラースキーム

カラースキームの自動判定には、CSSメディアクエリー・レベル5の「prefers-color-scheme」および「light-level」を利用しています。
対応状況や反映・設定の仕方はブラウザーやOSに依存しますが、主要なモダンブラウザー・OSは軒並み対応しています。

ダークモード

ダークモード表示は、CSSフィルターにより画面の明暗を反転することで実現しています。
具体的には、「body { filter: invert(100%) hue-rotate(180deg) brightness(85%) }」です。
ネガポジ反転したうえで、色相を逆転することで色合いをなるべく保ちます。
加えて、全体の輝度を下げます(輝度のパーセンテージはコード内の PLUGIN_COLORSCHEME_BRIGHTNESS 定数で指定)。
ただし、ページ内の画像等はさらに反転して元のまま表示します(対象となる要素はコード内の PLUGIN_COLORSCHEME_EXCLUSION 定数で指定)。

設定の保存

選択ボックスで選んだモードは、クッキーではなくブラウザーのローカルストレージ(Web Storage API)に保存しています。
秘密情報ではないので無条件に保存し、また極めて単純なためわざわざユーザーに紐付けてサーバー側で保存するようなこともしません。
なお、ローカルストレージも主要モダンブラウザーであればいずれも対応しています。

相性について

明暗を反転するだけなので、スキンの内容によっては相性が悪いこともあり得ます。
また、使用しているフォントやOS・ブラウザーによっては文字が見づらくなる場合があります。
作者が試した範囲では、Windows版Chromeはフォント描画があまりきれいではなく、標準スキンを本プラグインでダークモード表示したところ、黒地に白の本文がちらついて見えました。
したがって、ダークモードを強制しないよう、選択ボックスを表示すること(&colorscheme; のほう)を勧めます。

ライセンス

GPL v3


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-11-21 (火) 23:42:13
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.930 sec.

SourceForge