TheaterJS:模仿人类打字效果的 JavaScript 动画特效

TheaterJS是一个用于模拟人输入行为的JS库。
下面是一个简单完整的Demo,模拟了两个角色(Vader、luke)的对话,可以打开看一下运行效果和代码,然后复制代码到自己的项目中,试一试。
https://codepen.io/Zhouzi/pen/JoRazP

首先进行准备工作:

1、安装依赖npm install theaterjs
2、在你要写代码的页面引入theaterjs插件import theaterJS from 'theaterjs'

接下来开始看一下代码:

HTML:

<div class="body">
    <main class="scene">
      <!-- 此处有两个角色,vader和luke -->
      <div class="actor">
        <div class="actor__prefix">-</div>
        <div id="vader" class="actor__content"></div>
      </div>
      <div class="actor">
        <div class="actor__prefix">-</div>
        <div id="luke" class="actor__content"></div>
      </div>
    </main>
  </div>

CSS:(只有一部分)

.dark {
  color: $color-white;
  background-color: $color-black;
}
.actor__content--typing::after {//添加打字和删除时的光标
  content: '|';
  animation: blink 500ms infinite;
}

JS:

mounted(){
    //1,初始化一个theaterJS对象
    var theater = theaterJS()    
    //2,将演员添加到选角中。
    theater
      .addActor('vader', { speed: 0.8, accuracy: 0.6 })
      .addActor('luke')
    //3,将场景添加到场景中,options.autoplay为true,则播放场景。
    theater
      .addScene('vader:Luke.', 600)
      .addScene('luke:What?', 400)
      .addScene('vader:I am your father.', 400)
      .addScene('luke:Nooo...', -3, '!!! ', 600, 'No! ', 600)
      .addScene('luke:That\'s not true!', 600)
      .addScene('luke:That\'s impossible!', 400)
      .addScene('vader:Search your feelings.', 1600)
      .addScene('vader:You know it to be true.', 1000)
      .addScene('luke:Noooooooo! ', 600, 'No!', 400)
      .addScene('vader:Luke.', 600)
      .addScene('vader:You can destroy the Emperor.', 1600)
      .addScene('vader:He has foreseen this. ', 800)
      .addScene('vader:It is your destiny.', 1600)
      .addScene('vader:Join me.', 800)
      .addScene('vader:Together we can rule the galaxy.', 800)
      .addScene('vader:As father and son.', 1600)
      .addScene('vader:Come with me. ', 800)
      .addScene('vader:It is the only way.', 2000)
      .addScene(theater.replay.bind(theater))
    //4,添加在发出事件时执行的回调( ( 当场景开始/结束时、) )。
    //效果是当打字(type)和删除(erase)开始时,显示光标
    //当打字(type)和删除(erase)结束时,移除光标。
    //当vader打字(type)时,
    theater
      .on('type:start, erase:start', function () {
        theater.getCurrentActor().$element.classList.add('actor__content--typing')
      })
      .on('type:end, erase:end', function () {
        theater.getCurrentActor().$element.classList.remove('actor__content--typing')
      })
      .on('type:start, erase:start', function () {
        if (theater.getCurrentActor().name === 'vader') {
          document.body.classList.add('dark')
        } else {
          document.body.classList.remove('dark')
        }
      })
  },
先来了解几个单词的意思:

theater:戏剧;
type:打字;
erase:清除;

1、TheaterJS

需要提供一些选项来创建一个新的TheaterJS对象。
var theater = theaterJS(<options>)
参数默认描述{autoplay, locale, minSpeed, maxSpeed}

选项 默认 描述
autoplay true 如果为true,则自动播放场景(调用addScene时)
locale detect 确定在键入随机字符(错误)时使用哪个键盘。注意:"detect"是一种检测用户的语言环境并在受支持的情况下使用的选项。
minSpeed {erase:80, type: 80 } 每个键入字符之间的最小延迟(越低,速度越快)。
maxSpeed {erase:450, type: 450 } 每个键入的字符之间的最大延迟(越大,越慢)。
注意:obj1等效于obj2。
let obj1 = {
  "minSpeed ":80,
  "maxSpeed":450 
}
let obj2 = {
   "minSpeed ":{
     "erase":80,
     "type":80
  },
  
  "maxSpeed"::{
     "erase": 450,
     "type": 450
  }
}
TheaterJS对象具有两个公共(只读)属性:

theater.options:对象的选项。
theater.status:对象的状态(“正在播放”,“正在停止”或“准备就绪”)。

2、addActor

将演员添加到演员表中。

theater.addActor(<name>, <options>, <callback>)

参数默认描述

参数 默认 描述
name 用于标识角色的名称
options 0.8 accuracy (0到1之间的数字):用来决定演员犯错误的频率。speed (0到1之间的数字):用于确定actor打字的速度。
callback 角色的显示值更改时调用的函数。

注意:actor回调是在设置其显示值时调用的函数。它也可以是字符串,在这种情况下,TheaterJS将假定它是DOM选择器并查找相应的元素。然后,当值更改时,将设置元素的innerHTML。如果为目标元素指定了具有参与者名称的id,则可以放心地忽略此参数。

theater.addActor('vader')
//在这种情况下,TheaterJS将查找 #vader 元素的元素。 另外,当使用选择器字符串时,actor将有一个引用DOM元素的附加 $element 属性。

3、addScene

将场景添加到场景中,如果 options.autoplay 为 true,则播放场景。

theater.addScene(<scene>)

<scene>有五种类型

theater
.addScene('vader:Luke...') //擦除演员显示值的当前值,然后键入新值。
.addScene(800) //在播放下一个场景之前,先中断800毫秒。
.addScene('I am your father!') //将值追加到参与者值的当前显示。
.addScene(-7) //擦除7字符。
.addScene(fn) //调用fn,它接收完成的回调作为第一个参数( 调用 done() 将播放场景中的下一个场景)。

注意,addScene实际上接受了无限数量的参数,因此你可以执行以下操作:

theater
. addScene('vader:Luke... ', 800, 'I am your father!')
. addScene(-7, 'mother!')
. addScene(fn)

4、监听事件

添加在发出事件时执行的回调( ( 当场景开始/结束时的比如 ) )。

theater.on(<eventName>, <callback>)

例子:

theater
      .on('type:start, erase:start', function () {
        theater.getCurrentActor().$element.classList.add('actor__content--typing')
      })
      .on('type:end, erase:end', function () {
        theater.getCurrentActor().$element.classList.remove('actor__content--typing')
      })
      .on('type:start, erase:start', function () {
        if (theater.getCurrentActor().name === 'vader') {
          document.body.classList.add('dark')
        } else {
          document.body.classList.remove('dark')
        }
      })

参数默认描述

参数 描述
eventName 要侦听的事件的NAME
Callback 事件发布时调用的函数,回调函数将事件的NAME 作为第一个参数接收

注意:
通过使用快捷方式来侦听所有事件: theater.on('*', callback)。
事件在序列启动( sequence:start ) 并结束( sequence:end )。
比如 时发出 theater.addScene('vader:Luke.', 'vader:I am your father.') 是一个序列。
当方案开始和结束时,分别为 scenario:start 和 scenario:end 发出事件。
场景是 :end 事件侦听器中的stoppable。 表示在侦听场景 :end的回调内调用 theater.stop() 将停止场景。 这对于异步回调(。比如 动画) 非常有用。

5、播放

theater.play()

例子:

var theater =theaterJS({ autoplay:false })
theater
. addActor('vader')
.addScene('vader:Luke...')
document.querySelector('button').addEventListener('click', function () {
 theater.play()
}, false)

6、重播

theater.replay()

例子:

var theater =theaterJS();
theater
. addActor('vader')
. addScene('vader:Luke...')
. addScene(theater.replay)

7、停止

theater.stop()

例子:

var theater =theaterJS()
theater
. addActor('vader')
. addScene('vader:Luke... ', 'I am your father...')
document.querySelector('button').addEventListener('click', function () {
 theater.stop()}, false)

8、getCurrentActor

返回当前正在播放的演员。

var theater =theaterJS()
theater
. addActor('vader')
. addScene('vader:Luke...')
. addScene(function (done) {
 var vader = theater.getCurrentActor()
 vader.$element.classList.add('dying')
   done()
 })
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 一 Activity 1 Activity 生命周期 1.1 Activity 的四种状态 running 当前...
    _执_念__阅读 10,273评论 0 91
  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,467评论 1 11
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,155评论 1 23
  • 【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...
    Rtia阅读 6,075评论 1 38
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,617评论 0 15