Home > OS >  CSS Animations: How can I reveal an image as it slides up?
CSS Animations: How can I reveal an image as it slides up?

Time:10-29

I am working on a "zombie whack-a-mole" game built with HTML, CSS and vanilla JavaScript.

I have the animation of the zombie popping up and down out of its grave working, but I'm having trouble figuring out how to "hide" him while he is under the dirt, and gradually reveal him as I animate him popping up and down.

Run the snippet below to see what I mean. (You may need to scroll the Result down to see the full picture of what's going on)

.background {
  width: 220px;
  z-index: 5;
}

.frontdirt {
  width: 220px;
  position: absolute;
  left: 10px;
  z-index: 15;
}

.zombie {
  animation: popup 2s ease-in-out 10 forwards;
  position: absolute;
  width: 220px;
  top:140px; 
  left:2px; 
  z-index: 10;
}

@keyframes popup {
  0% {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(-140px);
  }
  100% {
    transform: translateY(0px);
  }
}
<table>
  <tr>
    <td>
          <img src="https://www.codeeverydamnday.com/images/beforezombie2.png" class="background" />
          <img
            src="https://www.codeeverydamnday.com/images/zombie.png"
            class="zombie"
          />
          <img
            src="https://www.codeeverydamnday.com/images/groundfront2.png"
            class="frontdirt" />
        </td>
  </tr>
  <tr>
    <td>
          <img
            src="https://www.codeeverydamnday.com/images/beforezombie2.png" class="background"
          />
        </td>
  </tr>
</table>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I tried messing with z-indexes first to no avail, then with CSS positioning, but I can't see any other way to get it where I need it to show up without using absolute positioning.

I am currently trying to figure out if there is a way to keep the image at its starting position, but to hide the part of it that falls outside of its container (the table cell) with some kind of overflow: hidden property. However, since it's absolutely positioned, I have taken it out of the document flow so it will not respect any container bounds.

Any ideas how I could position it differently? Is there a way to position the zombie between the "background" and "frontdirt" images without using absolute so that it respects the container bounds? Or is there a different approach I should be taking entirely?

CodePudding user response:

I recommend you use CSS Grid specification. In this example I made an outer grid to hold the different "cells" (I assume you want a classic Whackamole setup) and then another grid per cell. With CSS Grid you can layer items on top of one another without using absolute positioning. Then I just gave the images position relative and kept the z-indexes you had. This way the overflow: hidden works on each cell.

Doing it this way has the added benefit of being somewhat responsive using the fr unit and grid's minmax function, just set the images at 100% width and they will scale together.

Side note I changed the translate function to be percentage based so it can work at multiple sizes, but you can also give each grid cell a fixed width if you want more direct control over the layout.

.grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(220px, 1fr))
}

.cell {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  overflow: hidden;
}

.background {
  width: 100%;
  z-index: 5;
  grid-area: 1 / 2 / 1 / 2
}

.frontdirt {
  width: 100%;
  position: relative;
  z-index: 15;
  grid-area: 1 / 2 / 1 / 2
}

.zombie {
  animation: popup 2s ease-in-out infinite forwards;
  position: relative;
  top: 50%;
  width: 100%;
  z-index: 10;
  grid-area: 1 / 2 / 1 / 2
}

@keyframes popup {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-50%);
  }
  100% {
    transform: translateY(0);
  }
}
<div class="grid">
  <div class="cell">
    <img src="https://www.codeeverydamnday.com/images/beforezombie2.png" class="background" />
    <img src="https://www.codeeverydamnday.com/images/zombie.png" class="zombie" />
    <img src="https://www.codeeverydamnday.com/images/groundfront2.png" class="frontdirt" />
  </div>
  <div class="cell">
    <img src="https://www.codeeverydamnday.com/images/beforezombie2.png" class="background" />
  </div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related