<article class="demo">
  <section>
    <div id="lea-running" class="animated-sprite image-rendering-pixelated" data-frames="6" data-fps="18">
      <img src="https://auroratide.com/posts/pixelart-and-the-image-rendering-paradox/lea-running.png" alt="Lea is running from left to right." />
    </div>
  </section>
  <section class="radio-buttons">
    <input type="radio" id="image-rendering-auto-selection" name="image-rendering-selection" value="auto" />
    <label for="image-rendering-auto-selection">Auto</label>
    <input type="radio" id="image-rendering-pixelated-selection" name="image-rendering-selection" value="pixelated" checked />
    <label for="image-rendering-pixelated-selection">Pixelated</label>
    <input type="radio" id="image-rendering-crisp-edges-selection" name="image-rendering-selection" value="crisp-edges" />
    <label for="image-rendering-crisp-edges-selection">Crisp Edges</label>
  </section>
  <footer>
    <p>Pixelart is of Lea from the game <a href="http://cross-code.com/">Cross Code</a> by <a href="http://www.radicalfishgames.com/">Radical Fish Games</p>
  </footer>
</article>
.image-rendering-auto {
  image-rendering: auto;
}

.image-rendering-pixelated {
  image-rendering: crisp-edges; /* firefox */
  image-rendering: pixelated;
}

.image-rendering-crisp-edges {
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}

/* Layout
 * ====================================================*/
.demo {
  font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", Tahoma, sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.demo section {
  padding: 0.5rem 0;
}

/* Sprites
 * ====================================================*/
#lea-running {
  width: 128px;
  height: 128px;
}

.animated-sprite {
  overflow: hidden;
}

.animated-sprite img {
  position: relative;
}

/* Options
 * ====================================================*/
.radio-buttons {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.radio-buttons input[type="radio"] {
  position: absolute;
  opacity: 0;
}

.radio-buttons label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1.2;
  padding: 0.625em 1em;
  margin: 0 0.25em 0.5em;
  min-width: 6em;
  background: #444857;
  color: #ffffff;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0.125em 0.125em rgba(255, 255, 255, 0.5) inset, -0.125em -0.125em rgba(0, 0, 0, 0.5) inset, 0.125em 0 #000, -0.125em 0 #000, 0 0.125em #000, 0 -0.125em #000;
}

.radio-buttons label:hover {
  background: #5a5f73;
}

.radio-buttons input[type="radio"]:checked + label,
.radio-buttons label:active {
  box-shadow: -0.125em -0.125em rgba(255, 255, 255, 0.5) inset, 0.125em 0.125em rgba(0, 0, 0, 0.5) inset, 0.125em 0 #000, -0.125em 0 #000, 0 0.125em #000, 0 -0.125em #000;
}

.radio-buttons input[type="radio"]:checked + label {
  background: #1e1f26;
  cursor: auto;
}
function animateSprite(elem) {
  const fps = parseInt(elem.dataset.fps) || 60
  const frames = parseInt(elem.dataset.frames)
  const img = elem.querySelector('img')
  
  img.style.width = `${frames * 100}%`
  img.style.left = '0%'
  
  let lastTickTime = 0
  const interval = 1000 / fps
  function tick(time) {
    if (time - lastTickTime >= interval) {
      const currentFrame = parseInt(img.style.left) / -100
      img.style.left = `${-100 * ((currentFrame + 1) % frames)}%`
      lastTickTime = time
    }
    requestAnimationFrame(tick)
  }
  
  requestAnimationFrame(tick)
}

const lea = document.getElementById('lea-running')

const options = {}
document.querySelectorAll('input[name="image-rendering-selection"]').forEach(elem => {
  options[elem.value] = elem
})

animateSprite(lea)

Object.entries(options).forEach(([option, elem]) => {
  elem.oninput = () => {
    Object.keys(options).forEach((key) => lea.classList.remove(`image-rendering-${key}`))
    lea.classList.add(`image-rendering-${elem.value}`)
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.