Hi, this time we will experiment with creating a simple UI component that can change color according to the background image.
I was inspired by the music player notification on my phone:
And the experiment result:
looks cool right? now let's start making it ๐
Preparation
we need to create html, css, and js files first
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Adaptive Card Color</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <script src="script.js"></script>
</body>
</html>
style.css
*,
*::before,
*::after {
    padding: 0; margin: 0;
    box-sizing: border-box;
}
html {
    font-family: sans-serif;
    font-size: 16px;
    line-height: 1.5;
}
body {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
script.js
console.log("hello world");
Make card component
create html structure of the card like this
<div class="card">
    <img class="card-image" src="">
    <div class="card-text">
        <span>Lorem Ipsum</span>
        <span>Is simply dummy text of the printing and typesetting industry.</span>
    </div>
 </div>
don't forget the style
.card {
    position: relative;
    overflow: hidden;
    width: 90%;
    max-width: 400px;
    margin-bottom: 30px;
    padding: 30px;
}
.card-image {
    position: absolute;
    top: 0; right: 0;
    width: auto;
    height: 100%;
    object-fit: cover;
    object-position: center;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000);
            mask-image: linear-gradient(90deg, transparent, #000);
}
.card-text {
    position: relative;
    z-index: 2;
    max-width: 75%;
    display: flex;
    flex-direction: column;
}
.card-text span:first-child {
    font-weight: 500;
    font-size: 1.2rem;
    margin-bottom: 5px;
}
.card-text span:last-child {
    opacity: 0.7;
}
For image source you can get it from unsplash or use a local file.
Extract color from image
Yes, we have to extract color from image and it's a quite complex job. Luckily, i found a cool library that will do for us https://github.com/lokesh/color-thief
add the library to our project
<script src="https://unpkg.com/colorthief@2.3.2/dist/color-thief.umd.js"></script>
Javascript Time
// get all card elements.
const cards = document.querySelectorAll(".card");
// create colorthief instance
const colorThief = new ColorThief();
cards.forEach(async (card) => {
    const image = card.children[0];
    const text = card.children[1];
    // get palette color from image
    const palette = await extractColor(image);
    const primary = palette[0].join(",");
    const secondary = palette[1].join(",");
    // change color
    card.style.background = `rgb(${primary})`;
    text.style.color = `rgb(${secondary})`;
});
// async function wrapper
function extractColor(image) {
    return new Promise((resolve) => {
        const getPalette = () => {
            return colorThief.getPalette(image, 4);
        };
        // as said in the colorthief documentation, 
        // we have to wait until the image is fully loaded.
        if (image.complete) {
            return resolve(getPalette());
        }
        image.onload = () => {
            resolve(getPalette());
        };
    });
}
If you get an error and you use image from internet, you can add
crossorigin="anonymous"attribute on theimgtag.
Next task, check if the primary color is dark or light so we can correctly choose color for the text. Happy experimenting :D
Thank you very much for reading. Don't hesitate to leave comments, criticisms or suggestions, I will really appreciate it โบ๏ธ
Image cover by Hasmik Ghazaryan Olson on Unsplash
              

    
Top comments (2)
This post and comment is really helpful, thank you for sharing this info ๐
Thank you very much for the corrections and suggestions ๐. I'll update the article soon.
I learned something new today ๐