javascript 使用 CSS 逐个字母的文本外观动画

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19767069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 16:43:31  来源:igfitidea点击:

Letter-by-letter text appearance animation with CSS

javascripthtmlcssanimation

提问by Alexander Gladysh

I have a <div>with text.

我有一个<div>带文字的。

Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

I'd like the text in this <div>to appear on page one character at a time:

我希望此中的文本<div>一次出现在第一个字符上:

L

Lo

Lor

... and so on, until the full text is visible

Acceptable alternative: do that one word at a time, to avoid problems with HTML entities and jumpy words due to soft hyphenation.

可接受的替代方法:一次一个单词,以避免由于软断字而导致 HTML 实体和跳跃的单词出现问题。

If user clicks on the <div>, it should cancel the animation and display the full text instantly.

如果用户点击<div>,它应该取消动画并立即显示全文。

In short, I want to imitate an animation that is frequently seen in Japanese-style adventure games. (I think that this is sometimes called a typewriter or teletype effect.) Here is a good example:

总之,我想模仿一个在日式冒险游戏中经常出现的动画。(我认为这有时被称为打字机或电传效果。)这是一个很好的例子:

http://www.youtube.com/watch?feature=player_detailpage&v=SasgN0lim7M#t=418

http://www.youtube.com/watch?feature=player_detailpage&v=SasgN0lim7M#t=418

Obviously, I can script the animation using JavaScript —?just set up a timer and append letters (or words) one-by-one.

显然,我可以使用 JavaScript 编写动画脚本——只需设置一个计时器并一个一个地附加字母(或单词)即可。

But is it possible to do what I need with CSS in modern browsers? (Of course, I'd need to at least change element class in the onclickwith JS, but that's OK.)

但是有可能在现代浏览器中用 CSS 做我需要的吗?(当然,我至少需要在onclickwith JS 中更改元素类,但这没关系。)

Update:To clarify on characters vs. letters and problems with HTML entities:

更新:澄清字符与字母以及 HTML 实体的问题:

My text is littered with the HTML:

我的文本中充斥着 HTML:

Lo&shy;rem <i>ip&shy;sum</i>.

Na?ve approach with appending text to the innerHTMLcharacter-by-character wouldn't work:

将文本附加到innerHTML逐个字符的幼稚方法不起作用:

L

Lo

Lo&

...Doh!

采纳答案by musefan

Unfortunately you cannot do this with CSS so you will have to revert to a pure JS approach.

不幸的是,你不能用 CSS 做到这一点,所以你将不得不恢复到纯 JS 方法。

As your comments have explained, you require your text to contain some HTML markup so I would suggest a word-by-word animation being the easiest way to handle that. Something like this:

正如您的评论所解释的,您需要文本包含一些 HTML 标记,因此我建议逐字动画是处理该问题的最简单方法。像这样的东西:

var timer, fullText, currentOffset, onComplete, wordSet;

function Speak(person, text, callback) {
    $("#name").html(person);
    fullText = text;
    wordSet = text.split(" ");
    currentOffset = 0;
    onComplete = callback;
    timer = setInterval(onTick, 300);
}

function onTick() {
    currentOffset++;
    if (currentOffset == wordSet.length) {
        complete();
        return;
    }
    var text = "";
    for(var i = 0; i < currentOffset; i++){
     text += wordSet[i] + " ";   
    }
    text.trim();
    $("#message").html(text);
}

function complete() {
    clearInterval(timer);
    timer = null;
    $("#message").html(fullText);
    if (onComplete) onComplete();
}

$(".box").click(function () {
    complete();
});

Speak("Simon",
    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",

function () {
    setTimeout(function () {
        Speak("Javascript", "Simon has finished speaking!");
    }, 2000);
});

Here is a working example

这是一个工作示例

NOTE: This code can likely be vastly re-factored to be more efficient and concise, but it should demonstrate the concept in full.

注意:这段代码可能会被大量重构以提高效率和简洁性,但它应该完整地展示这个概念。



I also created a letter-by-letter example. Although it doesn't support you html markup needs, it does look nicer so perhaps you can adapt it to work for you.

我还创建了一个逐个字母的示例。虽然它不支持您的 html 标记需求,但它确实看起来更好,所以也许您可以调整它以适合您。

回答by Charles Ingalls

You can achieve this with a bit of jQuery.

您可以使用一些 jQuery 来实现这一点。

Check out my fiddle: http://jsfiddle.net/kA8G8/7/

看看我的小提琴:http: //jsfiddle.net/kA8G8/7/

HTML

HTML

<p class="typewriter">Nullam id dolor id nibh ultricies vehicula ut id elit. Maecenas faucibus mollis interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>

JS

JS

var text = $('.typewriter').text();

var length = text.length;
var timeOut;
var character = 0;


(function typeWriter() { 
    timeOut = setTimeout(function() {
        character++;
        var type = text.substring(0, character);
        $('.typewriter').text(type);
        typeWriter();

        if (character == length) {
            clearTimeout(timeOut);
        }

    }, 150);
}());

回答by user2451013

There is a pure CSS trick to do this.

有一个纯 CSS 技巧可以做到这一点。

Use a mask element, even a pseudo element p:beforeor p:afterwith a higher z-index than your text element. Give it the same color as the text background and the height of a line. Place it with absolute position just above the text.

使用掩码元素,甚至是伪元素p:beforep:after具有比文本元素更高的 z-index。赋予它与文本背景相同的颜色和线的高度。将其放置在文本正上方的绝对位置。

Then you just have to animate it to make it move to the right, unmasking letter by letter. It's just a workaround, because if you have a complex background under the text, like an image, then this trick is difficult to reproduce because you will have to map the background image on the masking element.

然后你只需要设置动画,让它向右移动,一个字母一个字母地揭开。这只是一种解决方法,因为如果文本下方有复杂的背景,例如图像,那么此技巧很难重现,因为您必须将背景图像映射到遮罩元素上。