Vyhledávání na webu

javascript - Změna slova ve frázi, vertikální animační smyčka CSS


Myslím, že k vysvětlení není nic lepšího než toto:

Skoro jsem dosáhl toho, co chci, jen s čistým CSS, ale...

  • Musím ručně nastavit „umístění“ každého slova
  • Pokud bude přidáno další slovo, musím všechno přepočítat
  • Nemohu nastavit dobu 1 sekundy pro každé slovo, jen celkový čas animace
  • Responzivní? Jen pokud všechno znovu přepočítám

Kód je div s overflow: hidden a potomkem s negativní margin-top (a animací).

Živá ukázka:

body {
  font-size: 2em;
  font-family: sans-serif;
 }
 
 .animation {
    vertical-align: sub;
    height: 1em;
    overflow: hidden;
    display: inline-block;
    line-height: 2em;
 }
 
ul {
  animation: animation 10s infinite;
  padding: 0;
  margin-top: -0.55em;
  list-style: none;
}

@keyframes animation {
    0%        { margin-top: -0.55em }
    12.5%     { margin-top: -2.54em }
    25%       { margin-top: -4.55em }
    37.5%     { margin-top: -6.55em }
    50%       { margin-top: -8.5em }
    62.5%     { margin-top: -6.55em }
    75%       { margin-top: -4.55em }
    87.5%     { margin-top: -2.54em }
    100%      { margin-top: -0.55em }
}
 Lorem ipsum dolor sit
 
    <div class="animation">
      <ul>
        <li>golfish</li>
        <li>dog</li>
        <li>cat</li>
        <li>hamster</li>
        <li>fox</li>
      </ul>
    </div>
    
, consectetur adipiscing elit. 

Tak...

Myslím, že nemohu vyřešit své problémy, protože jsou to omezení CSS, takže... Je možné to získat pomocí jQuery?

Odpověď č. 1

Tady je pokus o řešení pomocí CSS. Nejsem si úplně jistý, které aspekty referenčního obrázku jsou důležité, takže jsem se snažil ho co nejvíce napodobit. Nicméně jsem musel duplikovat seznam v markup, aby bylo možné změnit barvu z světle šedé na černou, když se posouvá skrz pohledovou oblast.

Vezměte také na vědomí, že snímky animace a časování jsou úzce spjaty s počtem položek v seznamu. Pokud se očekává, že počet položek bude dynamický, pravděpodobně bude potřeba nějaký zásah v JavaScriptu.

body {
  font-size: 2em;
  font-family: sans-serif;
  line-height: 1.2
}

.animation {
  display: inline-block;
  vertical-align: top;
  text-align: center;
  border: 1px solid;
  overflow: visible;
  white-space: nowrap;
  color: lightgray;
  position: relative;
}

.animation ul {
  list-style: none;
  padding: 0 .5ex;
  margin: 0;
  height: 1.2em;
}

.animation li {
  position: relative;
  animation: cycle-5-items 5s ease-in-out alternate infinite;
}

.animation ul.mask {
  color: black;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

@keyframes cycle-5-items {
  0%, 10% {
    transform: translateY(0%);
  }
  
  15%, 35% {
    transform: translateY(-100%);
  }
  
  40%, 60% {
    transform: translateY(-200%);
  }
  
  65%, 85% {
    transform: translateY(-300%);
  }
  
  90%, 100% {
    transform: translateY(-400%);
  }
}
Lorem ipsum dolor sit
 
    <div class="animation">
      <ul class="mask">
        <li>golfish</li>
        <li>dog</li>
        <li>cat</li>
        <li>hamster</li>
        <li>fox</li>
      </ul>
      <ul>
        <li>golfish</li>
        <li>dog</li>
        <li>cat</li>
        <li>hamster</li>
        <li>fox</li>
      </ul>
    </div>
    
, consectetur adipiscing elit.

Odpověď č. 2

Nepotřebujete jQuery. Zde je jednoduché řešení v čistém JS využívající CSS přechod.

function createWordListAnimation(animNode, delay){
  // Fetch the DOM elements.
  var animWindow = animNode.querySelector(".animation-window");
  var ul = animWindow.querySelector("ul");
  var lis = ul.querySelectorAll("li");

  // Copy the animation's window to create the gray list.
  var grayList = animWindow.cloneNode(true);
  var grayUl = grayList.querySelector("ul");
  grayList.classList.remove("animation-window");
  grayList.classList.add("animation-gray-list");
  animNode.insertBefore(grayList, animWindow);

  // This function shows the li number `liNum`.                     
  function goTo(liNum){
    var li = lis[liNum];
    var liTop = li.getBoundingClientRect().top;
    var ulTop = ul.getBoundingClientRect().top;
    var liOffset = liTop - ulTop;
    ul.style.top = -liOffset + "px";
    grayUl.style.top = -liOffset + "px";
  }

  // Set up an interval that changes the current li every `delay` ms.
  var current = 0;
  // We need a boolean to know if the animation is going up or down.
  var ascending = true;
  // Create the interval.
  return setInterval(function(){
    ascending = ascending && current + 1 < lis.length || current === 0;
    current = ascending ? current + 1: current - 1;
    goTo(current);
  }, delay);
}

createWordListAnimation(document.querySelector(".animation"), 1000 /* (ms) */);
body {
  font-size: 2em;
  font-family: sans-serif;
}

.animation {
  vertical-align: sub;
  display: inline-block;
  margin-top: -.1em;
  margin-bottom: -.1em;
  border-style: solid;
  border-color: lightgray;
  border-width: 1px;
  height: 1.2em;
}

.animation-window {
  position: relative;
  height: 100%;
  overflow: hidden;
  background-color: white;
}

.animation-gray-list {
  position: absolute;
  color: lightgray;
}

.animation ul {
  position: relative;
  list-style: none;
  top: 0;
  padding: 0;
  margin: 0;
  transition: top 300ms;
}

.animation li {
  margin: 0 .2em;
  text-align: center;
}
Lorem ipsum dolor sit
 
    <div class="animation">
      <div class="animation-window">
        <ul>
          <li>golfish</li>
          <li>dog</li>
          <li>cat</li>
          <li>hamster</li>
          <li>fox</li>
        </ul>
      </div>
    </div>,

consectetur adipiscing elit.

Nevýhodou tohoto řešení je, že okno nemůže být průhledné (musí skrýt šedý seznam). Stále je možné udělat ho průhledným, ale budete muset vytvořit dva šedé seznamy - jeden nahoře, jeden dole - a začíná to být trochu složité.