1

I have written a Javascript code for matching the images in a 4x4 grids. I want the images to flip when a user clicks on them and flip back when the two images are not same. I am able to flip the images when they are first clicked. The images then are getting compared. When equal, I'v set display: none but it is when they are NOT equal, there are problems. I'v tried all permutation and combinations but the images are not flipping. Please help me out in flipping the images back.

Here is my code:

HTML:

<div class="container">
        <div class="f1_container" onclick="choose(0)">
            <div class="shadow f1_card">

                <div class="back face center"><img src="A.png" onclick="Click()"></div>
            </div>
        </div>
    <div class="f1_container" onclick="choose(1)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="B.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(2)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="C.png"></div>
        </div>
    </div>

    <div class="f1_container" onclick="choose(3)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="D.png"></div>
        </div>
    </div>
    <br>
    <div class="f1_container" onclick="choose(4)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="E.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(5)"> 
        <div class="shadow f1_card">

            <div class="back face center"><img src="F.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(6)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="G.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(7)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="H.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(8)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="A.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(9)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="B.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(10)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="C.png"></div>
        </div>
    </div>

    <div class="f1_container" onclick="choose(11)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="D.png"></div>
        </div>
    </div>
    <br>
    <div class="f1_container" onclick="choose(12)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="E.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(13)"> 
        <div class="shadow f1_card">

            <div class="back face center"><img src="F.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(14)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="G.png"></div>
        </div>
    </div>
    <div class="f1_container" onclick="choose(15)">
        <div class="shadow f1_card">

            <div class="back face center"><img src="H.png"></div>
        </div>
    </div>
    <br>
</div>

Javascript:

<script>
    var clicks = 0; //counts how may picks have been made in each turn
    var firstchoice; //stores index of first card selected
    var secondchoice; //stores index of second card selected
    var match = 0; //counts matches made
    var backcard = "images/card.png"; //shows back of card when turned over
    var tiles_flipped = 0;
    var faces = ['A.png', 'B.png', 'C.png', 'D.png', 'E.png', 'F.png','G.png', 'H.png', 'A.png', 'B.png', 'C.png', 'D.png', 'E.png', 'F.png','G.png', 'H.png'  
                 /*'canada.png', 'germany.png', 'india.png', 'spain.png', 'uk.png', 'usa.png'*/]; //array to store card images
    /*function shuffle(a) 
    {
        for (let i = a.length; i; i--) {
            let j = Math.floor(Math.random() * i);
            [a[i - 1], a[j]] = [a[j], a[i - 1]];
        }
    }
    shuffle(faces);*/
    var count_clicks = 0;
    function choose(card) 
    {
        count_clicks += 1;
        if (clicks == 2) 
        {
            return;
        }
        if (clicks == 0) 
        {
            firstchoice = card;
            document.images[card].src = faces[card];
            clicks = 1;
        }else 
        {
            clicks = 2;
            secondchoice = card;
            document.images[card].src = faces[card];
            timer = setInterval("check()", 500);
        }
    }
    /* Check to see if a match is made */
    function check() 
    {
        clearInterval(timer); //stop timer
        clicks = 0;
        if (faces[secondchoice] == faces[firstchoice]) 
        {
            match++;
            document.images[firstchoice].style.display = 'none';
            document.images[secondchoice].style.display = 'none';
            document.getElementById("matches").innerHTML = match;
        } else 
        {  // This is the part I have doubt in.
           // I'v set it to an image but it should flip back.
            document.images[firstchoice].src = backcard;
            document.images[secondchoice].src = backcard;
            return;
        }
    }
    var clicks = 0;
    var previous_scores = localStorage.getItem("old-score");
    console.log(previous_scores);
    function Click() 
    {
        if(tiles_flipped == faces.length)
        {
            document.getElementById("clicks").innerHTML = "New Score: "+clicks+"<br>"+"Old Score: "+previous_scores;
            localStorage.setItem("old-score", clicks);

        }
        else
        {
            clicks += 1;
            document.getElementById("clicks").innerHTML = "Clicks: "+clicks;
            return clicks;
        }
    }
    console.log(count_clicks);
</script>

CSS:

body::after 
{
    content: "";
    background: url(bg2.jpg);
    background-size: cover;
    opacity: 0.05;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    position: absolute;
    z-index: -1;  
}
.container
{
    width: 685px;
    margin: 0 auto;
}
.f1_container {
    position: relative;
    margin:10px;
    width: 150px;
    height: 150px;
    z-index : 1;
    float:left;
}
.f1_container {
    -webkit-perspective: 1000;
    perspective: 1000;

}
.f1_card {
    width: 150px;
    height: 150px;
    -webkit-transform-style: preserve-3d;
    -webkit-transition: all 0.3s linear;
    transform-style: preserve-3d;
    transition: all 0.3s linear;
    background: url('card.png');
    background-size: 150px 150px;

}
.f1_container.active .f1_card {
    -webkit-transform: rotateY(180deg);
    transform: rotateY(180deg);
    /* box-shadow: -5px 5px 5px #aaa; */

}
.face {
    position: absolute;
    width: 150px;
    height: 150px;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;

}
.face.back {
    display: block;
    -webkit-transform: rotateY(180deg);
    transform: rotateY(180deg);
    box-sizing: border-box;
    text-align: center;
    background-color: white;
}
.face.back img
{
    width: 150px;
}
Del Monte
  • 153
  • 3
  • 14
  • You could add a class when they are flipped, then, if they are not a match, remove the class again after some set time that it takes the transition to run. So the cards would transition from the normal state to the added class state; then if no match, transition back from the added class state to the normal state when the class is removed. – cjl750 Aug 01 '17 at 17:04
  • Thanks for replying. Can it be done without jQuery? Also I got the addClass and removeClass logic but didn't get the transition part.. – Del Monte Aug 01 '17 at 17:11
  • @cjl750 Yes please post it as answer because it is working :) – Del Monte Aug 02 '17 at 16:11
  • Great! I've posted an answer. – cjl750 Aug 02 '17 at 16:30

1 Answers1

0

What I would suggest doing is controlling the flipping animation with a class change. Set up your normal styles for your card in your CSS, then apply transform: rotateY(180deg) when the extra class is added.

That way, you can add that class when a card is clicked, and after a certain timeout, remove the class again. So long as you include a transform transition (for example, transition: transform 500ms) on your card, it will transition both ways: when it flips over as the class is added, and when it flips back as the class is removed.

You can add and remove this class with the click function and timeout you already have.

Below is an example of adding and removing a class with vanilla JavaScript with a timeout function. See how we add a flipped class to #wrapper with JavaScript, and we have the style #wrapper.flipped .card { transform: rotateY(180deg); } for the animation.

Note that this solution uses element.classList, which is supported in Internet Explorer 10+. If you need to support Internet Explorer 9 or below, see Code with classList does not work in IE? for some options.

document.getElementById('wrapper').addEventListener('click', function() {
  var wrapper = this;

  wrapper.classList.add('flipped');

  setTimeout(function() {
    wrapper.classList.remove('flipped');
  }, 1500);
});
#wrapper {
  perspective: 1000px;
  width: 100px;
  height: 150px;
}
#wrapper.flipped .card {
  transform: rotateY(180deg);
}
.card {
  width: 100%;
  height: 100%;
  position: relative;
  transition: transform 500ms;
  transform-style: preserve-3d;
}
.card .front,
.card .back {
  width: 100%;
  height: 100%;
  border-radius: 15px;
  position: absolute;
  top: 0;
  left: 0;
  backface-visibility: hidden;
}
.card .front {
  background-color: midnightblue;
  z-index: 1;
}
.card .back {
  background-color: firebrick;
  transform: rotateY(180deg);
}
<div id="wrapper" style="float: left;">
  <div class="card">
    <div class="front"></div>
    <div class="back"></div>
  </div>
</div>
<p style="float: left; margin: 65px 0 0 10px;">&larr; click me</p>
cjl750
  • 4,380
  • 3
  • 15
  • 27