【问题标题】:Reveal Text from left with CSS or JS animation使用 CSS 或 JS 动画从左侧显示文本
【发布时间】:2020-11-10 19:39:53
【问题描述】:

我想做一个像这样的文本显示动画: video

.text {
  display: inline;
  font-family: Heebo, Arial, sans-serif;
  font-size: 24px;
  font-weight: 800;
  font-style: normal;
  line-height: 1.5;
  letter-spacing: normal;
  text-align: center;
  color: #000;
  background-color: #fff;
  border-radius: 5px;
  padding: 2px 9px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
<div class="text-block">
  <div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. A cupiditate ea eius obcaecati quasi recusandae vitae. Iure perferendis, unde! Aperiam consequatur ipsum iure nisi tenetur? Cupiditate error fugiat libero repellat.
  </div>
</div>

【问题讨论】:

标签: javascript html jquery css animation


【解决方案1】:

我使用 javascript 来创建解决方案。您只需要循环遍历所有要附加的单词并将附加内容包装在setTimeout 中,如下所示:

const element = document.getElementsByClassName('text')[0];

const words = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. A cupiditate ea eius obcaecati quasi recusandae vitae. Iure perferendis, unde! Aperiam consequatur ipsum iure nisi tenetur? Cupiditate error fugiat libero repellat.";

words.split(" ").forEach((word, index) => {
  setTimeout(() => {
       element.appendChild(document.createTextNode(word + ' '));
  }, index * 300);
});

您还需要清除您的 HTML 以防止附加两次。

【讨论】:

  • Michał,你能告诉我如何更改脚本以使文本按字母显示吗?
  • 当然,您可以将 split 方法中的参数从 " " 更改为 "" 并删除 createTextNode 内的操作并仅使用 word 变量。这将导致在每个可能的位置拆分您的文本。您还可以降低第二个超时参数以使您的文本显示得更快。
【解决方案2】:

使用以下自定义脚本,您只需将类 typewriter-word 添加到您的元素中,其余的工作将由脚本自行完成。

您可以使用属性data-delaydata-initial-delay 自定义单词之间的延迟和初始延迟。有效值必须至少为 0。任何错误的值都将在脚本中更正。

您链接的视频中的文本样式可以通过一些简单的 CSS 来实现。

脚本的工作原理...

  1. 同时获取data-delaydata-initial-delay,并在必要时进行更正
  2. 将元素的内容保存在数组中,并从 HTML 中删除所述内容
  3. 开始在initialDelay之后逐字添加内容
  4. delay 后面重复添加其余单词
  5. 在将所有单词重新插入 HTML 后,消除重复调用,避免再次不必要地调用 (clearInterval(intervalId))
  6. 对所有 .typewriter-word-elements 重复步骤 1 到 5

我的代码的问题是,您不能将其他元素放在您的.typewriter-word-元素中,因为您可能会冒使您的 HTML 无效或完全破坏它的风险。这意味着,你应该只在不包含其他元素的元素上使用这个类,而只在 (text-)content 上使用这个类。

还有什么要补充的?
现在,代码还不够完美。其他可以添加的内容是...

  • 使用Intersection Observer API 仅在元素位于视口内时启动效果
  • 添加新属性以使效果在设定的时间或设定的时间段后重复自身
  • 仅在元素实际可见(位于 DOM 内部)时才开始效果
  • 将嵌套元素视为一个单词,(以及与前面的项目符号一起)使嵌套的.typewriter-word-元素在插入后开始其效果,而无需摆弄它们的data-initial-delay-attribute

旁注
MDN 也有一个打字机效果的例子。但是,他们的方法是per character Typewriter。您可以尝试自定义其代码以满足您的需求。

window.addEventListener("load", () => {
  for (let el of document.querySelectorAll(".typewriter-word")) {
    // Get both delay and initial delay, both greater than or equal to zero
    let delay = parseInt(el.getAttribute("data-delay"));
    if (isNaN(delay) || delay < 0) delay = 500; // Default value == 500
    let initDelay = parseInt(el.getAttribute("data-initial-delay"));
    if (isNaN(initDelay) || initDelay < 0) initDelay = delay; // Default value == 'delay'
    
    // Save words in array, where words are Strings seperated by " "
    let words = [];
    for (let word of el.innerHTML.split(" "))
      words.push(word);
    
    // Remove content of element
    el.innerHTML = "";
    
    let intervalId; // Variable to save the interval's ID,
                    // to remove interval when finished adding all words
    setTimeout(() => {
      function nextWord() {
        if (words.length <= 0) { // When all words are "printed", clear interval
          clearInterval(intervalId);
          return;
        }
        el.innerHTML += " " + words.shift(); // FIFO via 'Array.shift()' -> No index-usage required!
      }
      
      nextWord(); // Call once -before setInterval()- since setInterval starts firing only after its delay
      intervalId = setInterval(nextWord, delay); // Save interval's ID in variable for removing it when finished
    }, initDelay); // setTimeout(func, initDelay) --> Starting after initial delay
  }
});
body {
  display: flex;
  flex-flow: column;
  align-items: flex-start;
  gap: 0.5rem;
  background: black
}
p {
  margin: 0;
  padding: 0.1em;
  border-radius: 0.1rem;
  color: black;
  background: white;
}
p:empty {
  padding: 0;
  width: 0;
  height: 0;
  display: inline;
  background: inherit;
}
<p class="typewriter-word">This text will appear word by word.</p>
<p class="typewriter-word" data-delay="100" data-initial-delay="3500">I will appear faster, but later. Hooray for custom data-attributes!</p>

【讨论】:

  • Oskar,你能告诉我如何更改脚本以使文本按字母显示吗?
  • 要快速更改它,您只需将 string.split-delimiter 替换为“”,这会将每个字母单独推送到数组中
  • 但是创建一个新类typewriter 可能会更好,它可以保存字符串本身,并将其逐个字母添加回来,从而使数组的使用变得不必要地复杂。将其设为另一个类将允许您同时使用逐字和逐字母类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
相关资源
最近更新 更多