上边有一个标题栏,表现与 XXX 谈天。
中心是谈天信息面板,包罗着两边发送的消息,每条消息由发送者头像和消息内容构成,我发送的在右侧,对方发送的在左侧。
下方是底部信息,有心情选择按钮、编辑消息文本框和发送按钮。
那么根据这个布局编写的 HTML 代码如下所示:
各个元素所对应的界面部门为:
<main />元素是一个团体的容器,用于把谈天窗口居中对齐
<div class="chat">是谈天应用的容器,用于结构标题栏、谈天面板和底部发送框。
<div class="titleBar">用于表现标题栏。
<div class="panel">是消息面板,用于结构此中的消息。
<div class="message">为消息容器,利用差别的 class 来区分发送方, mine代表我发送的, yours代表对方发送的。每条消息里边利用 <img class="avatar" >来展示头像,利用 <p>元向来表现文本, <p>元素里边的 <span>元素将会作为 lottie 的容器来播放心情动画。
<footer>用于结构底部操纵按钮和消息发送框。此中:
<main />元素是一个团体的容器,用于把谈天窗口居中对齐
<div class="chat">是谈天应用的容器,用于结构标题栏、谈天面板和底部发送框。
<div class="titleBar">用于表现标题栏。
<div class="panel">是消息面板,用于结构此中的消息。
<div class="message">为消息容器,利用差别的 class 来区分发送方, mine代表我发送的, yours代表对方发送的。每条消息里边利用 <img class="avatar" >来展示头像,利用 <p>元向来表现文本, <p>元素里边的 <span>元素将会作为 lottie 的容器来播放心情动画。
<footer>用于结构底部操纵按钮和消息发送框。此中:
<button class="chooseSticker">是心情选择按钮,利用一个笑容 svg 图片表现,里边的 <div class="stickers">是心情选择框弹出层,里边的心情将在 JS 中动态加载,目标是为了实现动画预览。
<input class="messageInput" />是谈天消息输入框,没什么特殊的。
<button class="send">是发送按钮
<button class="chooseSticker">是心情选择按钮,利用一个笑容 svg 图片表现,里边的 <div class="stickers">是心情选择框弹出层,里边的心情将在 JS 中动态加载,目标是为了实现动画预览。
<input class="messageInput" />是谈天消息输入框,没什么特殊的。
<button class="send">是发送按钮
<button class="chooseSticker">是心情选择按钮,利用一个笑容 svg 图片表现,里边的 <div class="stickers">是心情选择框弹出层,里边的心情将在 JS 中动态加载,目标是为了实现动画预览。
<input class="messageInput" />是谈天消息输入框,没什么特殊的。
<button class="send">是发送按钮
这个是 HTML 的根本布局,接下来看一下 CSS 样式。
2. CSS 部门
在项目根目次下创建一个 style.css 文件并在 index.html 的<head> 标签中引入:
2.1 全局样式
起首界说一些 CSS 变量,CSS 变量是为了方便我们引用同一属性值的,后边假如更新样式时,可以制止多次修改:
这些变量的寄义分别是:
--primary-color: hsl(200, 100%, 48%),主色调,比方我发送的消息的蓝色配景。
--inverse-color: hsl(310, 90%, 60%),反色调,或夸大色调,与主色调形成光显对比,比方发送按钮的配景色。
--shadow-large: 0 0px 24px hsl(0, 0%, 0%, 0.2),大阴影,比方标题栏、底部栏的阴影。
--shadow-medium: 0 0 12px hsl(0, 0%, 0%, 0.1),小阴影,比方输入框和心情选择弹出层。
--primary-color: hsl(200, 100%, 48%),主色调,比方我发送的消息的蓝色配景。
--inverse-color: hsl(310, 90%, 60%),反色调,或夸大色调,与主色调形成光显对比,比方发送按钮的配景色。
--shadow-large: 0 0px 24px hsl(0, 0%, 0%, 0.2),大阴影,比方标题栏、底部栏的阴影。
--shadow-medium: 0 0 12px hsl(0, 0%, 0%, 0.1),小阴影,比方输入框和心情选择弹出层。
接下来是一些重置样式:
这些样式对全部元素都有用,设置盒子模子为 border-box,如许内边距、边框都算在宽高之内,设置内间距和外间距为 0,末了设置默认字体。
2.2 Main 容器
Main 容器用于定位谈天应用容器到欣赏器中心,利用 grid 结构,宽高分别设置为欣赏器可视地区的 100%,并把配景色设置为黑灰色:
2.3 谈天应用容器
谈天应用容器设置了固定宽高,模仿手机屏幕,并利用 grid 结构来控制标题栏、谈天面板和底部操纵栏的位置:
这里利用了 grid-template-rows把谈天应用分成了 3 行,第一行的标题栏和末了一行的标底部操纵栏的高度分别为内容的最大高度,中心的谈天面板则是浮动高度。
2.4 标题栏
标题栏简朴的设置了一个内间距、笔墨居中方式和阴影:
界面优化提示:内间距用来增长留白,在视觉上引起放松,阴影则为了和下边的谈天面板区分开
界面优化提示:内间距用来增长留白,在视觉上引起放松,阴影则为了和下边的谈天面板区分开
谈天面板利用 flex 结构对此中的消息举行分列,并设置方向为按列排布,然后设置 overflow 为 auto,在消息团体高度超出头板高度时,出现滚动条:
界面优化提示:这里的 padding 同样是为了留出充足多的空缺,来与别的元素隔开一段间隔,以制止拥挤感。
界面优化提示:这里的 padding 同样是为了留出充足多的空缺,来与别的元素隔开一段间隔,以制止拥挤感。
消息分为消息容器、头像和消息体 3 个部门。此中消息体和头像包罗在消息容器中,先来看消息容器的样式。消息容器利用 flex 结构来把消息体和头像放在一行,宽度最大为面板宽度的 80%,并设置字体和外边距:
这里的 position设置为 relative 是为了定位后边的全屏殊效动画。
头像简朴设置了宽高、圆角和间隔消息体的间距:
界面优化提示:这里不得不再提一下间距的紧张性,肯定不要把各个元素安排的太过紧凑,否则非常影响视觉结果,最直接的影响就是引起视觉上的拥挤感,造成视觉疲惫。
界面优化提示:这里不得不再提一下间距的紧张性,肯定不要把各个元素安排的太过紧凑,否则非常影响视觉结果,最直接的影响就是引起视觉上的拥挤感,造成视觉疲惫。
消息体同样的设置了间距和圆角,这里的圆角和头像的保持同等,以增长调和感。它还设置了阴影,并利用 flex 结构,把里边的笔墨或心情消息居中对齐:
这些样式默认都是基于对方的消息的,假如是我发送的消息必要放到右边,并作一些调解。起首对于我发送的消息,把 flex-flow 改为 row-reverse 如许头像和消息体的位置就交换了,然后利用 align-self 对齐到面板的右边:
调解头像的外边距,如今应该是间隔左边的消息体的边距了:
设置消息体的配景色为蓝色,笔墨为白色:
2.7 底部操纵栏
先看底部操纵栏容器的团体结构,利用 grid 结构把心情选择按钮、消息发送框和发送按钮分成 3 列,此中除消息发送框为浮动宽度外,别的的两个按钮为固定宽度,默认居中对齐,末了设置阴影和间距:
心情选择按钮把本身举行了靠左对齐,并设置相对定位,用于定位心情选择弹出层,然后设置按钮图标的巨细:
心情选择弹出层的 CSS 代码比力多但都很简朴,先看一下代码:
border-radius: 8px; background-color: white; box-shadow: var(--shadow-medium); padding: 6px12px; font-size: 24px;
position: absolute; top: calc(-100% - 18px); width: 300px; opacity: 0; }
这段代码的寄义是:
弹出层利用 grid 结构,repeat(auto-fill, 24px) 指的是在宽度答应的条件下,在一行中尽大概放置最多的列元素,每列的宽度固定为 24px。然后设置列间距为 18px。
设置圆角、配景色、阴影、内间距和字体巨细。
定位设置为绝对定位,把它向上移动 包罗元素高度(也就是 .chooseSticker 的高度)的 100% 并减去 18px,调解到符合的位置。宽度设置为 300px,透明度设置为 0 把它隐蔽。
弹出层利用 grid 结构,repeat(auto-fill, 24px) 指的是在宽度答应的条件下,在一行中尽大概放置最多的列元素,每列的宽度固定为 24px。然后设置列间距为 18px。
设置圆角、配景色、阴影、内间距和字体巨细。
定位设置为绝对定位,把它向上移动 包罗元素高度(也就是 .chooseSticker 的高度)的 100% 并减去 18px,调解到符合的位置。宽度设置为 300px,透明度设置为 0 把它隐蔽。
消息输入框和按钮的样式比力简朴,消息输入框的宽度占满整列,发送按钮利用 justify-self: end把本身举行靠右对齐。这里把代码一次性贴出来:
末了再添加一个 .show样式,用于在点击发送心情按钮时,给心情弹出层添加该样式以表现出来:
3. JS 部门
在给谈天界面加上功能之前,先编写一些底子的 JS 代码。在项目根目次创建一个 index.js 文件,并在 index.html 中引用,留意放到 </body> 关闭标签的上方,如许当 HTML DOM 加载完成之后才会实行 js 中的代码,防止找不到元素:
在 index.js 中,先获取要操纵的 DOM 元素:
此中:
panelEle是消息面板元素,用于追加新消息。
chooseStickerBtn是选择心情按钮,点击它会弹出心情选择框。
stickersEle就是弹出的心情选择框。
msgInputEle是消息输入框。
sendBtn为发送按钮。
然后引入 Lottie 的 js 库,可以到示例代码堆栈中下载,也可以在 http://cdnjs.com/libraries/bodymovin中下载 lottie.min.js,下载完成之后放到项目根目次,然后在 index.html 中,在引入 index.js 的上方引入它:
下载心情动画资源文件,它们都是 json 格式的文件,下载完成之后直接放到项目根目次即可:
南瓜心情:http://lottiefiles.com/43215-pumpkins-sticker-4
炸弹心情:http://lottiefiles.com/3145-bomb
爆炸动画:http://lottiefiles.com/9990-explosion
南瓜心情:http://lottiefiles.com/43215-pumpkins-sticker-4
炸弹心情:http://lottiefiles.com/3145-bomb
爆炸动画:http://lottiefiles.com/9990-explosion
接下来看一下各部门功能是怎么实现的。
发送平凡消息
发送平凡消息时,用户在输入框输入完消息之后,点击发送,就会把该条消息追加到消息列表中,并清空输入框中的内容。那么这里先给发送按钮添加点击变乱:
在变乱处置惩罚函数中:
判定用户是否输入了消息。
假如输入了就追加到消息列表中。
判定用户是否输入了消息。
假如输入了就追加到消息列表中。
来看一下 appendMsg函数的代码:
函数吸收两个参数,msg 和 type,分别是要追加的消息内容和范例,type 为可选的,不传则以为是平凡文本消息,假如通报了 "stickers" 则为心情消息,如今还用不到它。在这个函数中重要做了下面几件事变:
按照消息的 HTML 布局创建一个新的消息元素 msgEle,并追加到消息列表中。
把消息的样式设置为我发送的。
内部的元素分别为头像和文本消息,利用模板字符串的情势赋值给 msgEle 的 innerHTML 属性中,并在 <p>中利用 msg 变量的值。
末了把滚动条滚动到最新的消息处,并清空输入框中的消息。
按照消息的 HTML 布局创建一个新的消息元素 msgEle,并追加到消息列表中。
把消息的样式设置为我发送的。
内部的元素分别为头像和文本消息,利用模板字符串的情势赋值给 msgEle 的 innerHTML 属性中,并在 <p>中利用 msg 变量的值。
末了把滚动条滚动到最新的消息处,并清空输入框中的消息。
如许就可以发送平凡的文本消息了。
发送动画心情
在发送动画心情之前,必要先加载动画心情。在 index.js 的最上方先界说心情名称和心情动画文件路径的键值对信息:
我们会根据 bomb、 pumkin如许的 key 来找到对应的动画路径。接着初始化弹出层中的心情以供用户选择:
这里的代码分别作了下边这些操纵:
遍历存储心情信息的对象。
创建一个 lottie 的容器,利用 span 元素,由于 lottie 动画的播放器必要挂载到一个详细的 html 元素中。
调用 lottie 的 loadAnimation 加载动画,它必要通报如许几个参数:
container: 播放器要挂载到的容器。
renderer:可以选择是利用 svg 照旧 canvas 渲染动画。
loop: 是否循环播放,由于此处是在心情选择弹出层中预览动画,以是支持循环播放。
autoplay:是否主动播放,这里设置为了否,后边让它在鼠标划过期再播放动画。
path:动画 json 文件路径,直接从对象中获取。
container: 播放器要挂载到的容器。
renderer:可以选择是利用 svg 照旧 canvas 渲染动画。
loop: 是否循环播放,由于此处是在心情选择弹出层中预览动画,以是支持循环播放。
autoplay:是否主动播放,这里设置为了否,后边让它在鼠标划过期再播放动画。
path:动画 json 文件路径,直接从对象中获取。
container: 播放器要挂载到的容器。
renderer:可以选择是利用 svg 照旧 canvas 渲染动画。
loop: 是否循环播放,由于此处是在心情选择弹出层中预览动画,以是支持循环播放。
autoplay:是否主动播放,这里设置为了否,后边让它在鼠标划过期再播放动画。
path:动画 json 文件路径,直接从对象中获取。
loadAnimation 会返回 lottie 的实例,把它生存在 player 中。
然后后边则注册了几个变乱:
当 lottieEle 也就是心情被点击时,发送心情消息,给 appendMsg 的 msg 参数设置为心情的 key,type 参数设置为 "sticker"。
当鼠标划过心情时,开始播放动画。
当鼠标划出心情时,制止动画。
接着给发送心情按钮添加变乱,点击时,切换心情弹出层的表现状态:
这时点击发送心情按钮就可以看到心情选择弹出层了。如今还不能发送心情,由于还没在 appendMsg 函数中处置惩罚,如今来修改一下它里边的代码。起首判定:假如是心情消息,则不在消息中的 <p>元素里添加任何信息:
然后在它的下方,调用 playSticker 函数来播放动画:
playSticker 函数吸收两个参数,一个是心情的 key,一个是消息元素。此时的 msg 变量的内容就是在 lottieEle 点击变乱中通报过来的心情 key。函数中的代码如下:
在这个函数里重要做了下边几项操纵:
获取消息中的 span 元素,它将作为 lottie 的动画容器。
设置心情动画的宽高为 40px。
利用 lottie 加载动画,并设置循环播放为 false,主动播放为 true,来让心情发送时主动播放动画,且只播放一次。
如今可以发送心情消息了,相干的动画也会主动播放,接下来看一下怎么实现炸弹的全屏动画和对消息元素的晃动结果。
发送带全屏殊效的心情
对于这种带全屏殊效的心情可以单独举行判定,也可以在生存心情的对象中界说相干的操纵,这里为了简朴起见,我们单独判定用户是否发送了炸弹心情,然后施加相应殊效。
起首在 appendMsg 函数里,举行判定,假如发送的消息是心情消息,且心情为炸弹,则播放全屏动画并晃动消息:
这里爆炸全屏动画耽误了 800 毫秒之后再实行,目标是在炸弹心情播放到符合的时间时,再播放全屏动画,播放动画利用了 playExplosion 函数,并通报了消息元素进去。在爆炸全屏动画竣事之后,调用 shakeMessages 来晃动消息。这里先看一下 playExplosion 函数的代码:
playExplosion 函数吸收一个 anchor 锚点,就是说基于哪个位置开始播放全屏动画,由于示例中的动画画幅比力小,以是把它固定在了最新发送的消息的下方,这里爆炸动画的 anchor 就是消息元素,之后函数做了下边的这些操纵:
添加全屏动画元素,设置为绝对定位,宽度 200px,高度 100px,放在最新消息元素的右下角。
加载 lottie 动画,不循环、主动播放。
由于原动画速率过快,这里调用 lottie 实例的 setSpeed 方法,把速率设置为 0.3 倍速。
之后给 lottie 实例设置变乱监听:"complete",它会在动画实行完成时触发,里边烧毁了 lottie 实例和全屏动画元素。
添加全屏动画元素,设置为绝对定位,宽度 200px,高度 100px,放在最新消息元素的右下角。
加载 lottie 动画,不循环、主动播放。
由于原动画速率过快,这里调用 lottie 实例的 setSpeed 方法,把速率设置为 0.3 倍速。
之后给 lottie 实例设置变乱监听:"complete",它会在动画实行完成时触发,里边烧毁了 lottie 实例和全屏动画元素。
如许全屏动画的结果就实现了。接下来看消息晃动的代码:
这个函数的操纵是:
利用 reverse 和 slice 对最新的 5 条消息举行晃动,也可以把 5 改大一点,对更多消息举行晃动。
然后在循环中,分别给头像和消息添加 shake class 实行晃动动画,这个 class 的内容稍后再先容。
要留意的是,在添加 shake class执举措画前,必要先删除 shake,由于有的消息大概在之前已经晃动过了,比方当一连发了多个炸弹心情时。后边在添加 shake class 时,利用 setTimeout 耽误了 700 毫秒,目标是在全屏动画实行到肯定水平时再晃动消息。
利用 reverse 和 slice 对最新的 5 条消息举行晃动,也可以把 5 改大一点,对更多消息举行晃动。
然后在循环中,分别给头像和消息添加 shake class 实行晃动动画,这个 class 的内容稍后再先容。
要留意的是,在添加 shake class执举措画前,必要先删除 shake,由于有的消息大概在之前已经晃动过了,比方当一连发了多个炸弹心情时。后边在添加 shake class 时,利用 setTimeout 耽误了 700 毫秒,目标是在全屏动画实行到肯定水平时再晃动消息。
接下来看一下 shake class 的界说,在 style.css 中添加下方代码:
.shake中利用了 shake keyframes 界说的动画,实行时间为 0.8s,动画实行函数为 ease-in-out。Keyframes 里的代码比力多,但是都是很简朴的,就是模仿了爆炸时的结果,移动 x 轴和 y 轴的偏移,每次的偏移幅度越来越小,而且越来越快,可以看到百分比的隔断越来越小。在动画举行到 42% 的时间,加了一些旋转动画,如许就有了落地时的震惊结果。由于利用 rotate 旋转时的轴心在元素中心,我们可以把消息气泡的轴心修改一下来实现更真实的结果:
这里把对方发送的消息的轴心设置在左下角,本身发送的消息则设置在了右下角。
总结
如今,这个模仿微信 8.0 动画心情的功能就实现了。重要就是下边几点:
利用 lottie 库加载并播放动画。
确定全屏动画的位置和播放机遇。
消息晃动动画的 CSS 实现。
利用 lottie 库加载并播放动画。
确定全屏动画的位置和播放机遇。
消息晃动动画的 CSS 实现。
你学会了吗?假如有题目或发起可以留个批评,喜好此文章请点个赞或关注我,后边另有更多更出色的文章,感谢!
作者:峰华,简介:前端工程师,以直观、专业的方式分享编程知识。Bilibili UP@峰华前端工程师
作者:峰华,简介:前端工程师,以直观、专业的方式分享编程知识。Bilibili UP@峰华前端工程师
本文全部地点:
示例地点:http://codechina.csdn.net/mirrors/zxuqian/html-css-examples
代码地点:http://codechina.csdn.net/mirrors/zxuqian/html-css-examples/-/tree/master/31-05-wechat-emoji-effect
lottie: http://cdnjs.com/libraries/bodymovin,下载 lottie.min.js
南瓜心情:http://lottiefiles.com/43215-pumpkins-sticker-4
炸弹心情:http://lottiefiles.com/3145-bomb
爆炸动画:http://lottiefiles.com/9990-explosion
Lottie 官网:http://airbnb.io/lottie
示例地点:http://codechina.csdn.net/mirrors/zxuqian/html-css-examples
代码地点:http://codechina.csdn.net/mirrors/zxuqian/html-css-examples/-/tree/master/31-05-wechat-emoji-effect
lottie: http://cdnjs.com/libraries/bodymovin,下载 lottie.min.js
南瓜心情:http://lottiefiles.com/43215-pumpkins-sticker-4
炸弹心情:http://lottiefiles.com/3145-bomb
爆炸动画:http://lottiefiles.com/9990-explosion
Lottie 官网:http://airbnb.io/lottie
步伐员怎样制止陷入“内卷”、选择什么技能最有远景,中国开辟者近况与技能趋势毕竟是什么样?快来到场「2020 中国开辟者大观察」,更有丰富奖品送不绝!
☞百架无人机“失控撞楼”,步伐员写的 Bug? ☞ 百度推出开辟者搜刮 Beta;雷军手机利用时长曝光;苹果败诉,电脑上可以模仿 iOS 体系 | 极客头条 ☞ 我们差点就用不上 Java 了!
☞ 印度永世封禁了微信、百度、TikTok 等 59 款中国 App…… 返回搜狐,检察更多