Monday 14 August 2023

Web Tutorial: The Chameleon Site

In recent weeks, I came across this amusing story about eBay. Basically, it's about UI and UX, and how users react negatively to sudden changes in a system unless that change takes place very slowly, over time. In the story, such a change was brought about, to the site's background color.

This story amused me so much that I just had to write a bit of code to replicate this effect. It's not spectacular and accomplishes nothing really new, but let's dive into it anyway, eh?

We first have some standard website HTML. I generated the text using ChatGPT.
<!DOCTYPE html>
<html>
    <head>
        <title>Chameleon</title>

        <script>

        </script>
    </head>

    <body>
        <p>
            Welcome to ColorShift! We are passionate about the power of colors to transform and enhance your world. Whether you're looking to revamp your home decor, design a striking logo, or simply add a touch of vibrancy to your digital creations, we have you covered. Our expert team is dedicated to helping you explore the endless possibilities of color.
        </p>

        <p>
            Discover a kaleidoscope of hues, shades, and tones that will ignite your creativity. Dive into our extensive color palette and find the perfect combination that speaks to your unique style. From bold and energetic to calm and soothing, we offer a vast spectrum of options to suit any mood or aesthetic.
        </p>

        <p>
            Our intuitive color selection tool allows you to experiment with different combinations, ensuring you find the harmony you're seeking. Adjust brightness, saturation, and contrast to achieve just the right balance. Create stunning gradients or play with complementary and contrasting colors to make your designs truly stand out.
        </p>

        <p>
            Whether you're a seasoned designer or a novice enthusiast, our blog is a treasure trove of inspiration and guidance. Dive into articles that delve into the psychology of color, explore the latest trends, and learn invaluable tips and tricks to make your colors pop.
        </p>

        <p>
            At ColorShift, we understand that colors have the power to evoke emotions, convey messages, and make a lasting impression. Let us be your guide on this chromatic journey. Unleash your imagination, unleash the colors!
        </p>
    </body>
</html>


Within the script tag, we create the setBgColor() function. It has three parameters. The first is maxDays, which is an integer that specifies how many days the change is going to take place over. fromColor and toColor are objects that dictate the beginning color and the end state color, each of these containing the RGB values in integers, as properties.
<script>
      function setBgColor(maxDays, fromColor, toColor)
      {

      }

</script>


When the site loads, we want to run the function. Let's first set it at 100 days, from the color white to orange.
<body onload="setBgColor(100, {r:255, g:255, b:255}, {r:255, g:200, b:0})">


Back to the setBgColor() function, we begin by declaring body as the HTML body tag.
function setBgColor(maxDays, fromColor, toColor)
{
      var body = document.getElementsByTagName("body");
      body = body[0];

}


We then declare startDate as a new Date object, and as a test, set it to the first day of this year. For this code to work, startDate should be before today's date.
function setBgColor(maxDays, fromColor, toColor)
{
      var body = document.getElementsByTagName("body");
      body = body[0];

      var startDate = new Date();
      startDate.setFullYear(2023, 0, 1);

}


Now we declare currentDate as another Date object, and it's today's date. Next, we have ms, which we use to calculate the number of milliseconds between currentDate and startDate.
function setBgColor(maxDays, fromColor, toColor)
{
      var body = document.getElementsByTagName("body");
      body = body[0];

      var startDate = new Date();
      startDate.setFullYear(2023, 0, 1);

      var currentDate = new Date();
      var ms = currentDate.getTime() - startDate.getTime();

}


And then we do some math on ms to get the number of days, assigning it to the variable days. We use floor() because days might not be a whole number, and it would be easier if it was.
function setBgColor(maxDays, fromColor, toColor)
{
      var body = document.getElementsByTagName("body");
      body = body[0];

      var startDate = new Date();
      startDate.setFullYear(2023, 0, 1);

      var currentDate = new Date();
      var ms = currentDate.getTime() - startDate.getTime();
      var days = Math.floor(ms / 86400000);
}


We declare finalColor and set it to the value of toColor.
function setBgColor(maxDays, fromColor, toColor)
{
    var body = document.getElementsByTagName("body");
    body = body[0];

    var startDate = new Date();
    startDate.setFullYear(2023, 0, 1);

    var currentDate = new Date();
    var ms = currentDate.getTime() - startDate.getTime();
    var days = Math.floor(ms / 86400000);

    var finalColor = toColor;
}


And now we set the background color of body to use the r, g and b properties in finalColor.
function setBgColor(maxDays, fromColor, toColor)
{
    var body = document.getElementsByTagName("body");
    body = body[0];

    var startDate = new Date();
    startDate.setFullYear(2023, 0, 1);

    var currentDate = new Date();
    var ms = currentDate.getTime() - startDate.getTime();
    var days = Math.floor(ms / 86400000);

    var finalColor = toColor;

    body.style.backgroundColor = "rgb(" + finalColor.r + ", " + finalColor.g + ", " + finalColor.b + ")";
}


What do we do with days, then? Well, we use a conditional statement to check if days is less than maxDays. If so, we'll alter the value of finalColor (not right now, though) but if not, the background color of body will effectively be the current value of finalColor, which is toColor.
function setBgColor(maxDays, fromColor, toColor)
{
    var body = document.getElementsByTagName("body");
    body = body[0];

    var startDate = new Date();
    startDate.setFullYear(2023, 0, 1);

    var currentDate = new Date();
    var ms = currentDate.getTime() - startDate.getTime();
    var days = Math.floor(ms / 86400000);

    var finalColor = toColor;

    if (days < maxDays)
    {

    }


    body.style.backgroundColor = "rgb(" + finalColor.r + ", " + finalColor.g + ", " + finalColor.b + ")";
}


Since it's 3rd August and definitely more than 100 days (the value of maxDays), you can see the color of background is orange!




Now in the If block, declare ratio. It's the result of dividing days by maxDays, which will give you a value less than 1 because days is less than maxDays.
if (days < maxDays)
{
    var ratio = days / maxDays;
}


Next, we declare rDiff, which is the difference between the r property of toColor and the r property of fromColor.
if (days < maxDays)
{
    var ratio = days / maxDays;

    var rDiff = toColor.r - fromColor.r;
}


Same for gDiff and bDiff.
if (days < maxDays)
{
    var ratio = days / maxDays;

    var rDiff = toColor.r - fromColor.r;
    var gDiff = toColor.g - fromColor.g;
    var bDiff = toColor.b - fromColor.b;  
 
}


If rDiff is greater than 0 (which means there is a difference), we alter the r property of finalColor to be the r property of fromColor, plus the ratio-ed value of rDiff! So the closer days is to maxDays, the closer the r property of finalColor will be to the r property of toColor.
if (days < maxDays)
{
    var ratio = days / maxDays;

    var rDiff = toColor.r - fromColor.r;
    var gDiff = toColor.g - fromColor.g;
    var bDiff = toColor.b - fromColor.b;    

    if (rDiff != 0) finalColor.r = fromColor.r + (Math.floor(rDiff * ratio));
}


Yes, we can do the same for the g and b properties of finalColor.
if (days < maxDays)
{
    var ratio = days / maxDays;

    var rDiff = toColor.r - fromColor.r;
    var gDiff = toColor.g - fromColor.g;
    var bDiff = toColor.b - fromColor.b;    

    if (rDiff != 0) finalColor.r = fromColor.r + (Math.floor(rDiff * ratio));
    if (gDiff != 0) finalColor.g = fromColor.g + (Math.floor(gDiff * ratio));
    if (bDiff != 0) finalColor.b = fromColor.b + (Math.floor(bDiff * ratio));

}


Let's test this! Change the value here to an entire year.
<body onload="setBgColor(365, {r:255, g:255, b:255}, {r:255, g:200, b:0})">


It's now 3rd August. That's 212 days after 1st Jan, right? 212 over 365 is 0.5808219178082191, give or take. So the color should be 58% orange!




Change this to an even bigger number...
<body onload="setBgColor(3650, {r:255, g:255, b:255}, {r:255, g:200, b:0})">


And you see the color gets closer to the "original" color, white.




Conclusion

I hope the logic was clear. This web tutorial is a little light on functionality, but it was fun to do. Which is the reason why I do anything on this blog.

Don't fade away on me now!
T___T

No comments:

Post a Comment