[JS] Sample to dynamically and smoothly change meta theme-color
![[JS] Sample to dynamically and smoothly change meta theme-color](img/ogp.png)
The meta tag "theme-color" that can change the browser toolbar color, mainly on smartphones.
<meta name="theme-color" content="#F0F5F9">
I will try to dynamically change this with JS.
Table of Contents
First, try changing it normally
First, I'll try changing it normally, without animation.
On devices where theme-color is effective, such as smartphones,
Please click to try it.
Change color code here.
I will omit the detailed source code, but
it's minimally like this.
//「.btn」をクリックしたとき
$(".btn").on("click", function(){
//metaタグを書き換え
$("meta[name=theme-color]").attr("content", "#F0F5F9");
});
How it looks on a real device
iOS16 Safari
Android12 Chrome
Both switched instantly without animation.
meta theme-color did not work in Chrome on iOS.
Try switching smoothly
I created a function that switches with a smooth animation.
Sample
Change color code here.
Sample Source
$(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);
});
//Function to switch smoothly ("#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);
}
}
//Function to convert hexadecimal to 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 as an array
return [rgb_r, rgb_g, rgb_b];
}
//Function to convert RGB to hexadecimal
function convert_16(arr){
//If the argument array contains a negative number, set it to 00
for(let i=0; i<3; i++){
if(arr[i] < 0){
arr[i] = 0;
}
}
// From decimal to hexadecimal
let hex_r = (parseInt(arr[0])).toString(16);
let hex_g = (parseInt(arr[1])).toString(16);
let hex_b = (parseInt(arr[2])).toString(16);
// Add 0 if it's a single digit
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;
}
});
How it looks on a real device
iOS16 Safari
Android12 Chrome
Both animated quite beautifully.
I referred to this article for converting RGB and hexadecimal values.
Comments
-
#001
Anonymous
I was impressed lol
I was in the middle of PWA development and was unsure about the theme color, so being able to test it easily was very helpful!
-
#002
Kento Kanai
I'm glad it was helpful!
Thank you for your comment 😄




If this was helpful, we appreciate your support!
Any support received will be used for childcare.
Or support by buying something from the buttons below
(You don't have to buy the linked product.)
Amazon
楽天市場
Yahoo!ショッピング
PR