フロントの人の雑多メモ

【JS】meta theme-colorを動的にふわっと変更するサンプル

【JS】meta theme-colorを動的にふわっと変更するサンプル

主にスマホのブラウザでツールバーの色を変更できるmetaタグ「theme-color

<meta name="theme-color" content="#F0F5F9">

これをJSで動的に変更してみます。

目次

まずは普通に変更してみる

まずはアニメーション無しで、普通に変更してみます。

スマホなど、theme-colorが効くデバイスで

クリックしてお試しください。

カラーコード変更はこちら。

ソースコードは詳しくは省略しますが

最小限こんな感じです。

//「.btn」をクリックしたとき
$(".btn").on("click", function(){
	//metaタグを書き換え
	$("meta[name=theme-color]").attr("content", "#F0F5F9");
});

実機での見え方

iOS16 Safari

Android12 Chrome

両者ともに、アニメーションはせずパッパッと切り替わりました。

iOSのChromeではmeta theme-colorは効きませんでした。

ふわっと切り替えてみる

ふわっとアニメーションしながら切り替える関数を作ってみました。

サンプル

カラーコード変更はこちら。

サンプルソース

$(function(){
	const meta_theme = $("meta[name=theme-color]");

	$("input[name=theme_animate]").on("change", function(){
		let from = $("input[data-animate=animate1]").val();
		let to = $("input[data-animate=animate2]").val();
		theme_color(from, to);
	});

	//ふわっと切り替える関数 ("#ace0f9", "#fff1eb")
	function theme_color(from, to) {
		let frames = 30; //フレーム
		let duration = 1000; //アニメーションの長さ ms

		let per = duration / frames; //1フレームあたりの長さ

		let from_rgb = convert_rgb(from);
		let to_rgb = convert_rgb(to);

		for(let i=0; i<=frames; i++){
			(function(pram) {
				setTimeout(function() {
					//それぞれの差
					let diff_r = (from_rgb[0] - to_rgb[0]) / frames * pram;
					let diff_g = (from_rgb[1] - to_rgb[1]) / frames * pram;
					let diff_b = (from_rgb[2] - to_rgb[2]) / frames * pram;

					//このフレームでの色
					let r = from_rgb[0] - diff_r;
					let g = from_rgb[1] - diff_g;
					let b = from_rgb[2] - diff_b;

					let code = convert_16([r, g, b]);

					meta_theme.attr("content", code);
				}, pram * per);
			})(i);
		}
	}

	//16進数をRGBに変換する関数 ("#ace0f9")
	function convert_rgb(str){
		let hex_r, hex_g, hex_b;

		if (str.length < 6) {
			// #abcをa,b,cに分割
			let hex_3digit = str.match(/^#([0-9a-f]{1})([0-9a-f]{1})([0-9a-f]{1})/);
			// aa
			hex_r = hex_3digit[1] + hex_3digit[1];
			// bb
			hex_g = hex_3digit[2] + hex_3digit[2];
			// cc
			hex_b = hex_3digit[3] + hex_3digit[3];
		} else {
			// #abcdefをab,cd,efに分割
			let hex_6digit = str.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/);
			// ab
			hex_r = hex_6digit[1];
			// cd
			hex_g = hex_6digit[2];
			// ef
			hex_b = hex_6digit[3];
		}

		// 16進数から10進数へ
		let rgb_r = parseInt(hex_r, 16);
		let rgb_g = parseInt(hex_g, 16);
		let rgb_b = parseInt(hex_b, 16);

		//配列にして返す
		return [rgb_r, rgb_g, rgb_b];
	}

	//RGBを16進数にする関数
	function convert_16(arr){
		//引数の配列にマイナスが含まれてしまったら00に
		for(let i=0; i<3; i++){
			if(arr[i] < 0){
				arr[i] = 0;
			}
		}

		// 10進数から16進数へ
		let hex_r = (parseInt(arr[0])).toString(16);
		let hex_g = (parseInt(arr[1])).toString(16);
		let hex_b = (parseInt(arr[2])).toString(16);

		// 1桁の場合は0をつける
		hex_r = hex_r.replace(/(^[0-9a-f]{1}$)/, '0$1'); 
		hex_g = hex_g.replace(/(^[0-9a-f]{1}$)/, '0$1'); 
		hex_b = hex_b.replace(/(^[0-9a-f]{1}$)/, '0$1'); 

		return '#' + hex_r + hex_g + hex_b;
	}
});

実機での見え方

iOS16 Safari

Android12 Chrome

両者ともに、結構きれいにアニメーションできました。

RGBと16進数を変換するのにこちらの記事を参考にさせていただきました。

RGBと16進数の変換 | 私的雑録

コメント

  • #001

    匿名さん

    感動しました笑

    ちょうどPWA開発の途中でテーマカラーに迷っていたため簡単にテストでき非常に役に立ちました!

  • #002

    金井 健人

    お役に立てて良かったです!

    コメントありがとうございます😄

内容を確認の上、個人情報などは省いて掲載させていただきます。

お名前・メールアドレスも入力する

メールで返信がほしい場合に入力してください。

頂いた個人情報は開示しません。返信のためだけに利用いたします。

直接送信されます。確認の上、「送信」してください。

お役に立てましたら応援をお待ちしております!
頂いた応援は子育てに活用させていただきます。

OFUSEで応援を送る


または以下のボタンからなにか買って応援 (PR)

Amazon

楽天市場

Yahoo!ショッピング

Amazonのアソシエイトとして「けん」は適格販売により収入を得ています。

シェア

Twitterでシェア Facebookでシェア LINEでシェア はてなブックマークでシェア

お役に立てましたら応援をお待ちしております!
頂いた応援は子育てに活用させていただきます。

OFUSEで応援を送る