从底部CSS动画中提升文字(显示)

时间:2019-07-19 10:52:13

标签: javascript html css

我刚浏览网络时,发现了一些很酷的文字动画over here. 所以我想加入其中并加以扩展。 当我知道首先要做什么时,我仔细检查了一下是否有任何问题与我的想法有关,令我惊讶的是,我发现了一个可以解释我所需要的内容,但未得到正确回答的问题。我想主要原因是因为没有正确解释。所以我会尽力解释这个想法。

Previously asked question

想法。

让我们假设我有一个需要制作动画的标题标签。我想从图像中的位置(从行中)抬起/显示/抬起单词enter image description here

我从获得的源代码中更改了一些现有代码。但是文本是从整个块的底部开始显示/显示的。

代码:

// Wrap every letter in a span
$('.ml16').each(function() {
  $(this).html($(this).text().replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>"));
});

anime.timeline({
    loop: true
  })
  .add({
    targets: '.ml16 .letter',
    translateY: [100, 0],
    easing: "easeOutExpo",
    duration: 1400,
    delay: function(el, i) {
      return 30 * i;
    }
  }).add({
    targets: '.ml16',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
.wrap {
  width: 700px;
  margin: 100px auto;
}

.ml16 {
  color: #402d2d;
  padding: 40px 0;
  font-weight: 800;
  font-size: 2em;
  text-transform: uppercase;
  letter-spacing: 0.5em;
  overflow: hidden;
  text-transform: uppercase;
  font-family: sans-serif;
}

.ml16 .letter {
  display: inline-block;
  line-height: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>

<div class="wrap">
  <h1 class="ml16"><span>Made with love for a testing purpose</span></h1>
</div>

有人可以帮我把不完整的想法推到目的地吗?

1 个答案:

答案 0 :(得分:7)

您需要做的是将每个单词包裹在另一个范围内(例如tree.findall('.//creator', { None : 'http://xspf.org/ns/0/' })),并为此设置一个<span class="word"></span>-参见此小提琴:https://jsfiddle.net/w5uz4mex/

这将确保每个单词在动画时都独立地被“隐藏”。

overflow: hidden
// Wrap every word in a span
$('.ml16').each(function() {
  let text = $(this).text();
  let words = text.split(' ');
  
  // Clear current element
  this.innerHTML = '';
  
  // Loop through each word, wrap each letter in a span
  for(let word of words) {
    let word_split = word.replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>");
    
    // Wrap another span around each word, add word to header
    this.innerHTML += '<span class="word">' + word_split + '</span>';
  }
});

anime.timeline({
    loop: true
  })
  .add({
    targets: '.ml16 .letter',
    translateY: [100, 0],
    easing: "easeOutExpo",
    duration: 1400,
    delay: function(el, i) {
      return 30 * i;
    }
  }).add({
    targets: '.ml16',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
.wrap {
  width: 700px;
  margin: 100px auto;
}

.ml16 {
  color: #402d2d;
  padding: 40px 0;
  font-weight: 800;
  font-size: 2em;
  text-transform: uppercase;
  letter-spacing: 0.5em;
  overflow: hidden;
  text-transform: uppercase;
  font-family: sans-serif;
}

.ml16 .word {
  display: inline-block;
  overflow: hidden;
  height: 2em;
  margin: 0 0.4em;
}

.ml16 .letter {
  display: inline-block;
  line-height: 2em;
}

编辑: 作为奖励(无关),可以非常简单地使用jQuery,而无需使用jQuery,而是使用CSS动画。这也给您带来的好处是,可以很容易地通过CSS添加新的动画,而无需触摸JS。这只是一个快速演示,因此应仅作为起点(即,尚未针对任何生产环境进行过测试)。

请参见下面的slideUp,slideDown和zoomIn的示例

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="wrap">
  <h1 class="ml16">Made with love for a testing purpose</h1>
</div>
/**
 * Create new class for sliding text
 *
 * @params {Element} wrapper - HTML element with text content
 */
class TextSliderUpper {
  constructor(wrapper) {
    this.wrapper = wrapper;

    // Set delay between characters (in ms)
    this.delay = 40;

    // Wrap content in relevant wrappers
    this._wrapContent();
  }

  _wrapContent() {
    let words = this.wrapper.textContent.split(' ');
    let delay = 0;
    let content = '';

    // Loop through each word, wrap each character in a span
    words.forEach((word, multiplier) => {
      let word_split = word.split(/([^\x00-\x80]|\w)/g);
      let word_content = '';

      // Look through each letter, add a delay (incremented)
      word_split.forEach((char, index) => {
        delay += this.delay;

        word_content += `<span style="animation-delay: ${delay}ms">${char}</span>`;
      });

      // Add spacing between words
      if (content !== '') content += ' ';

      // Add wrapped words to content
      content += `<span>${word_content}</span>`;
    })

    // Add content to wrapper
    this.wrapper.innerHTML = content;
  }

  init() {
    this.wrapper.classList.add('show');
  }
}

// Get a list of all headers
let headers = document.querySelectorAll('[data-animate]');

// Loop through, add relevant class
Array.from(headers).forEach(header => {
  let slideHeader = new TextSliderUpper(header);

  // Allow for delays? Sure!
  let delay = header.dataset.delay || 0;

  // Delay class (if necessary)
  setTimeout(() => {
    slideHeader.init();
  }, delay)
})
body {
  font-family: sans-serif;
}

h1 {
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 0.1em;
}

[data-animate] {
  line-height: 1.2em;
}
[data-animate] > span {
  display: inline-block;
  height: 1.2em;
  overflow: hidden;
}
[data-animate] > span > span {
  display: none;
  animation: 3s cubic-bezier(0, 1.2, 0.1, 0.9);
  animation-fill-mode: backwards;
}
[data-animate].show > span > span {
  display: inline-block;
}

[data-animate=slideup] > span > span {
  animation-name: slideUp;
}

[data-animate=zoomin] > span > span {
  animation-name: zoomIn;
}

[data-animate=slidedown] > span > span {
  animation-name: slideDown;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translate(0, 1.2em);
  }
}
@keyframes zoomIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
}
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translate(0, -1.2em);
  }
}