DEV Community

Cover image for How To Make Adaptive Card Color Depending On Image Background
mcanam
mcanam

Posted on

How To Make Adaptive Card Color Depending On Image Background

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:

reference

And the experiment result:

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>

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

script.js

console.log("hello world");
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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());
        };
    });
}
Enter fullscreen mode Exit fullscreen mode

If you get an error and you use image from internet, you can add crossorigin="anonymous" attribute on the img tag.

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)

Collapse
 
shshank profile image
Shshank

This post and comment is really helpful, thank you for sharing this info πŸ˜„

Collapse
 
mcanam profile image
mcanam

Thank you very much for the corrections and suggestions πŸ™Œ. I'll update the article soon.

I learned something new today πŸ˜†