1

Well i created a colorFlipper website it works fine but i want to add some features to it .So i decided to work on css animation with javascript but a faced some problems. What I want to do is to change background color smoothly on click and the color should be a hex color generated randomly on every click. I made it to change the color smoothly, but it only works the first time, then the color change immediately without animation

this is my html - css - Js files.

// Getting Elements

const button = document.getElementById("btn");
const color = document.querySelector(".color");
const background = document.querySelector("main");
const mainStyles = window.getComputedStyle(background);
let currentMainColor = mainStyles.getPropertyValue('background-color');;


console.log(background)

// Event listners
button.addEventListener("click", changecolor);


//Functions


function changecolor() {

    const newColor = `#${Math.floor(Math.random()*255**3).toString(16).padStart(6,0)}`;
    let styleTag = document.querySelector("style");
    console.log(styleTag);
    if (styleTag !== null) {
        styleTag.remove();
        var style = document.createElement('style');
        style.innerHTML =
            `@keyframes example1 {
        from {background-color : ${currentMainColor}}
        to {background-color: ${newColor};}}`
        var ref = document.querySelector('script');
        // Insert our new styles before the first script tag
        ref.parentNode.insertBefore(style, ref);
    } else {
        var style = document.createElement('style');
        style.innerHTML =
            `@keyframes example2 {
        from {background-color : ${currentMainColor}}
        to {background-color: ${newColor};}}`
        var ref = document.querySelector('script');
        // Insert our new styles before the first script tag
        ref.parentNode.insertBefore(style, ref);

    }
    currentMainColor = newColor;
    color.innerHTML = newColor;




}
*,
 ::after,
 ::before {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Roboto Mono", sans-serif;
}

html {
    height: 90vh;
}

body {
    font-family: "Roboto Mono", sans-serif;
    overflow: hidden;
}

nav {
    height: 3rem;
    display: flex;
    align-items: center;
    box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.3);
    z-index: 9999;
}

nav a {
    text-decoration: none;
}

.nav-container {
    width: 90vw;
    max-width: 620px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nav-container h4 {
    font-size: 1rem;
    font-weight: 600;
    margin-right: 1rem;
    color: #49A6E9;
    letter-spacing: 0.25rem;
}

.nav-container ul {
    list-style: none;
    display: flex;
}

.nav-container ul li a {
    text-decoration: none;
    font-size: 1rem;
    font-weight: 600;
    margin-right: 1rem;
    color: hsl(205deg 86% 17%);
    letter-spacing: 0.25rem;
    transition: all 0.2s ease;
}

.nav-container ul li a:hover {
    color: #49A6E9;
}

main {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #F1F5F8;
    z-index: -1;
}

.animation1 {
    animation-name: example1;
    animation-duration: 4s;
    animation-fill-mode: forwards;
}

.animation2 {
    animation-name: example2;
    animation-duration: 4s;
    animation-fill-mode: forwards;
}

.container {
    text-align: center;
}

.container h1 {
    background: #222222;
    color: #FFFFFF;
    padding: 1rem;
    width: 50rem;
    border-radius: 10px;
    margin-bottom: 2.5rem;
    font-size: 2.5rem;
}

.color {
    color: #49A6E9;
}

.btn {
    padding: 0.7rem 2rem;
    border: 3px solid #222222;
    border-radius: 7px;
    background-color: transparent;
    cursor: pointer;
}

.btn:focus {
    outline: none;
}

.btn-hero {
    font-size: 1.7rem;
    text-transform: uppercase;
    letter-spacing: 0.25rem;
    transition: all 0.3s linear;
}

.btn-hero:hover {
    color: #F1F5F8;
    background-color: #222222;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Colot Flipper</title>
    <!-- Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap" rel="stylesheet">
    <!-- Custom Css -->
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <nav>
        <div class="nav-container">
            <a href="index.html">
                <h4 class="brand-name">Color Flipper</h4>
            </a>
            <ul class="menu">
                <li><a href="index.html">Simple</a></li>
                <li>
                    <a href="hex.html">Hex</a>
                </li>
            </ul>
        </div>
    </nav>
    <main class="animation1 animation2">
        <div class="container">
            <h1>Background Color : <span class="color">#F1F5F8</span></h1>
            <button class="btn btn-hero" id="btn">Click me</button>
        </div>
    </main>

    <script src="hex.js"></script>
</body>

</html>
Amine Ch 99
  • 145
  • 3
  • 14

2 Answers2

1

You can change it smoothly with the css transition property. Click the div to change its color.

//https://stackoverflow.com/questions/1484506/random-color-generator
function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

document.getElementById("div").addEventListener("click", e => {
  e.target.style.backgroundColor = getRandomColor();
});
.colordiv {
  width: 100vw;
  height: 100vh;
  transition: all 1s;
}
<div class="colordiv" id="div" style="background-color: lightgray"></div>
Jannes Carpentier
  • 1,838
  • 1
  • 5
  • 12
  • Thanks, man it works perfectly, but based on my logic (keyframes manipulation) do you know how to fix that bug to make it work because I believe that we can achieve the same result using keyframes – Amine Ch 99 Aug 04 '20 at 22:42
  • It should be possible, but it seems like an awful lot of work for something that can be done so easily. Do you need this approach for something else? – Jannes Carpentier Aug 04 '20 at 22:52
  • No, it just curiosity but you're right the simplest way remains the best thanks dude – Amine Ch 99 Aug 04 '20 at 22:56
1

One problem that you had is on your div, you are actually referring to two different classes that have animations associated, so the second is overriding the first.

After removing that, I cleaned up your code to simplify the changeColor function.

// Getting Elements

const button = document.getElementById("btn");
const color = document.querySelector(".color");
const background = document.querySelector("main");
const mainStyles = window.getComputedStyle(background);
let currentMainColor = mainStyles.getPropertyValue('background-color');;

// Event listners
button.addEventListener("click", changecolor);


function changecolor() {

    const newColor = `#${Math.floor(Math.random()*255**3).toString(16).padStart(6,0)}`;

    var style = document.querySelector("#style");
    if(style !== null){
       style.remove();
    }
    
    style = document.createElement('style');
    style.innerHTML =
            `@keyframes example1 {
        from {background-color : ${currentMainColor}}
        to {background-color: ${newColor};}}`
        style.id = "style";
    document.head.appendChild(style);

    currentMainColor = newColor;
    color.innerHTML = newColor;




}
*,
 ::after,
 ::before {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Roboto Mono", sans-serif;
}

html {
    height: 90vh;
}

body {
    font-family: "Roboto Mono", sans-serif;
    overflow: hidden;
}

nav {
    height: 3rem;
    display: flex;
    align-items: center;
    box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.3);
    z-index: 9999;
}

nav a {
    text-decoration: none;
}

.nav-container {
    width: 90vw;
    max-width: 620px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nav-container h4 {
    font-size: 1rem;
    font-weight: 600;
    margin-right: 1rem;
    color: #49A6E9;
    letter-spacing: 0.25rem;
}

.nav-container ul {
    list-style: none;
    display: flex;
}

.nav-container ul li a {
    text-decoration: none;
    font-size: 1rem;
    font-weight: 600;
    margin-right: 1rem;
    color: hsl(205deg 86% 17%);
    letter-spacing: 0.25rem;
    transition: all 0.2s ease;
}

.nav-container ul li a:hover {
    color: #49A6E9;
}

main {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #F1F5F8;
    z-index: -1;
}

.animation1 {
    animation-name: example1;
    animation-duration: 4s;
    animation-fill-mode: forwards;
}

.container {
    text-align: center;
}

.container h1 {
    background: #222222;
    color: #FFFFFF;
    padding: 1rem;
    width: 50rem;
    border-radius: 10px;
    margin-bottom: 2.5rem;
    font-size: 2.5rem;
}

.color {
    color: #49A6E9;
}

.btn {
    padding: 0.7rem 2rem;
    border: 3px solid #222222;
    border-radius: 7px;
    background-color: transparent;
    cursor: pointer;
}

.btn:focus {
    outline: none;
}

.btn-hero {
    font-size: 1.7rem;
    text-transform: uppercase;
    letter-spacing: 0.25rem;
    transition: all 0.3s linear;
}

.btn-hero:hover {
    color: #F1F5F8;
    background-color: #222222;
}
<nav>
        <div class="nav-container">
            <a href="index.html">
                <h4 class="brand-name">Color Flipper</h4>
            </a>
            <ul class="menu">
                <li><a href="index.html">Simple</a></li>
                <li>
                    <a href="hex.html">Hex</a>
                </li>
            </ul>
        </div>
    </nav>
    <main class="animation1 animation2">
        <div class="container">
            <h1>Background Color : <span class="color">#F1F5F8</span></h1>
            <button type="button" class="btn btn-hero" id="btn">Click me</button>
        </div>
    </main>
imvain2
  • 15,480
  • 1
  • 16
  • 21
  • thank you, yes I forgot it but I didn't work too I mean your solution it changes smoothly the first time then change immediately without animation I don't know why – Amine Ch 99 Aug 04 '20 at 22:49