作者:韩永豪 移动开发部 前端开发工程师

今年的11月初,我们公司参加了「2017年亚洲幼教年会(APEAC)」并取得了很不错的成果。本人有幸负责关于这次展示页的前端开发,特以此文记录开发过程中的关键环节。

展示页分为三大模块:数据展示、动态展示和地图展示。效果如下:

数据展示

此模块展示我们公司至今为止的各项数据,通过异步请求定时更新。

数字过渡的动态效果为类似于老虎机的效果,对应数位的新数字从下至上替换旧数字,如果该位数的数字没有发生变化,则没有过渡效果。

要实现这种效果,第一步要把数字按位切分:

// 分离每个数字
function split(num) {return (num || 0).toString().split('');
}

然后,增加千分位,即从个位开始,每隔三位插入一个逗号,实现代码如下:

function toThousands(num) {var num = (num || 0).toString(), result = '';while (num.length > 3) {result = ',' + num.slice(-3) + result;num = num.slice(0, num.length - 3);}if (num) { result = num + result; }return result;
}

最后利用样式控制过渡动画,关键代码如下:

<ul id="main" class="number"><li class="group"><span class="old">1</span><span class="new">1</span></li><li class="group"><span class="old">,</span><span class="new">,</span></li><li class="group"><span class="old">4</span><span class="new">1</span></li><li class="group"><span class="old">5</span><span class="new">5</span></li><li class="group"><span class="old">6</span><span class="new">2</span></li></ul>
.number li {width: 0.18rem;height: 0.24rem;line-height: 0.24rem;display: inline-block;overflow: hidden;
}.number li span {display: block;transform: translateY(0%);
}.number li.active span {animation: move 0.3s;animation-fill-mode: forwards; // 让动画结束后保持最后一帧
}@keyframes move {from {transform: translateY(0);}to {transform: translateY(-100%);}
}
var $main = document.querySelector('#main');// 填充数字
function update(fromArr, toArr) {// 从个位数开始对齐位数fromArr = fromArr.reverse();toArr = toArr.reverse();if (fromArr.length > toArr.length) {toArr.length = fromArr.length} else {fromArr.length = toArr.length}fromArr = fromArr.reverse();toArr = toArr.reverse();// 渲染节点并激活动画var numberHTML = ''for (var i = 0; i < toArr.length; i++) {// 如果该位数的数字没有发生变化,则没有过渡效果if (formArr[i] !== toArr[i]) {numberHTML += ('<li class="group active">' +'<span class="old">' + formArr[i] || '' + '</span>' +'<span class="new">' + toArr[i] || '' + '</span>' +'</li>');} else {numberHTML += ('<li class="group">' +'<span class="old">' + formArr[i] || '' + '</span>' +'<span class="new">' + toArr[i] || '' + '</span>' +'</li>');}}if (numberHTML) {$main.innerHTML = numberHTML;}
}

动态展示

此模块是游客现场互动的区域,只要扫一下二维码点赞,就会新增一条动态。 页面运行过程中,可能同时有多个人发动态,所以要有一条线程定时请求数据,并把数据保存在队列中:

同时,要有另一条线程读取队列的数据进行渲染:

关键代码如下:

var cacheList = []; // 队列列表var CHECK_INTERVAL = 2000; // 每个两秒检查一下队列
var UPDATE_INTERVAL = 1000; // 插入数据间隔
var MIN_CACHE = 10; // 储备数// 检查队列
function checkCache() {if (cacheList.length < MIN_CACHE) {// 异步请求数据ajax(function(res) {if (res && res.length) {cacheList = cacheList.concat(res); // 把新的数据合并到队列列表setTimeout(checkCache, CHECK_INTERVAL); // 轮询检查数据}}}
}// 开始加载
function loadData() {if (cacheList.length > 0) {render(cacheList[0]);cacheList = cacheList.splice(0, 1);}setTimeout(start, UPDATE_INTERVAL); // 轮询读取数据
}loadData(); // 数据启动
checkCache(); // 队列启动

地图展示

此模块由中国地图、固定的光点、闪烁的光点和动态气泡构成。 因为光点和气泡都与地理位置(精确到省份)有关联,所以首先要在地图上划分出每一个省份。然而,省份的占位是不规则的,划分起来会有一定的难度。 刚开始的想法是每个省份有固定几个点,气泡和光点只会固定出现在那几个位置。虽然能实现效果,但是看起来比较僵硬,并没有达到设计的效果。因此,又换了一种方案。 微积分在计算不规则图形的面积时,就是把一大块不规则图形切分成若干块小矩形,以此铺满整个不规则图形。同理,只需要按省份画出其对应的几个小矩形,并记录下来,就可以根据这些坐标让光点和气泡出现在对应省份的位置。为了便于画出这些小矩形,我做了一个小工具,效果如下图:

因为页面是根据屏幕分辨率自适应宽高的,因此地图在页面上的尺寸是不固定的(但是比例是固定的),所以这里做了一点调整,生成的坐标为百分比而不是像素值。例如:

// 记录的省份数据
var positionData = {新疆: [{startX: '6.7164179104477615%',endX: '34.07960199004975%',startY: '8.602941176470589%',endY: '19.77941176470588%'},{startX: '25.37313432835821%',endX: '35.69651741293532%',startY: '3.5049019607843137%',endY: '8.602941176470589%'},...],广东: [{...},...],...
};

最后,只需要在划分好的小矩形中选取某一块,然后从这块小矩形的面积中随机抽一个点显示光点和气泡:

// 地图
var $map = document.querySelector('#map');// 随机获取一个点
function getPosition(province) {// 获取省里面随机一个小矩形function getPositionArea(areaArray) {return areaArray[Math.round(Math.random() * areaArray.length)];}// 选定一个小矩形var area = getPositionArea(positionData[province]);var x = parseFloat(area.endX) - parseFloat(area.startX);var y = parseFloat(area.endY) - parseFloat(area.startY);return {x: parseFloat(area.startX) + (Math.random() * x) + '%',y: parseFloat(area.startY) + (Math.random() * y) + '%'};
}// 获取新的光点
function getPoint($point, province) {if (!$point) {$point = document.createElement('div');// 如果动画结束则移除光点,并重新开始$point.addEventListener('animationend', function() {$point.classList.remove('active');start($point);});}// 更新节点坐标和其他样式var position = getPosition(provice);...return $point;
}// 刷新样式并随机加入地图
function start($point) {$point = getPoint($point);setTimeout(function() {$point.classList('active');}, Math.round(Math.radom() * 1000))
}// 创建六百个光点
var POINT_COUNT = 600;
for (var i = 0; i < POINT_COUNT; i++) {start();
}

这样就完成了。

应急处理

由上可见,页面上的数据和动画都非常多,展会的设备未必能满足这样的性能要求。如果遇到性能比较低的机器,就需要减少数据或减弱动画效果。为了能让现场工作人员方便地调整,此页面支持通过URL参数指定性能选项。例如:

/exhibition?pointCount=300

pointCount参数是用于修改光点数量,默认为600个。此外还有其他参数,就不再逐一列出了。 最后,一起来看看效果吧!

一个炫酷大屏展示页的打造过程相关推荐

  1. 太帅了,我用炫酷大屏展示爬虫数据

    大屏有时纯粹是为了好看,领导的说法是"花花绿绿的效果不错".尤其放到展厅里,整面墙壁都是大屏那种,色彩十分艳丽. 我尝试了一下.不是专业的前端,所以用vue模板修改,前后端分离. ...

  2. 太帅了!我用炫酷大屏展示爬虫数据!

    作者 | 派森酱 来源 | Python技术 大屏有时纯粹是为了好看,领导的说法是"花花绿绿的效果不错".尤其放到展厅里,整面墙壁都是大屏那种,色彩十分艳丽. 我尝试了一下.不是专 ...

  3. 深度盘点:这20套可视化炫酷大屏真香啊(附源码)

    由于公司项目里面用到一个数据可视化大屏页面,自己网上各种谷歌百度,发现资源良莠不齐,而且大多数都是收费的,甚至一个页面一收费的那种,前前后后自己不管是付费的还是免费的收集了不少,于是自己打算整理下,免 ...

  4. 炫酷大屏demo_只要10分钟,教你配置出炫酷的数据可视化大屏

    在电影<摩天营救>中,监控中心的全方位展示屏幕给人印象深刻.现在这种立体化大屏幕似乎成了好莱坞大片的标配.其实,这种逼格很高的镜头就是一个数据可视化大屏. 随着社会信息化的高速增长,数据可 ...

  5. 新图表请查收!看够了炫酷大屏,这次来点小清新风格!

    提到数字大屏,你的第一反应是什么?酷炫风.科技感,还是3D动态效果? 在酷炫大屏盛行的今日,仍然有一部分朋友需要朴实平淡的模板风格.尤其是在年度汇报.决策分析等场景下,汇报人站在会议室的大电视机前讲解 ...

  6. 炫酷大屏demo_20套大屏模板,教你3分钟制作出酷炫的可视化大屏

    犹记得好莱坞大片<摩天营救>中,监控中心的全方位展示屏幕给人印象深刻,而这种立体化大屏幕似乎已成了科幻电影大片的标配.其实,这种逼格很高的镜头就是一个数据可视化大屏.如今在会议展厅.园区管 ...

  7. 炫酷大屏demo_可视化大屏动态效果

    大屏设计虽然效果震撼,能带给观众无与伦比的视觉冲击,尤其是做好可视化大屏动态效果demo真的不容易.过大的屏幕面积,如何进行用色才能保持恰到好处的视觉冲击呢?下面这几招就需要掌握. 一.可视化大屏动态 ...

  8. 炫酷大屏demo_那些炫酷高端的可视化大屏,是如何开发出来的?

    最近,我不止一次地听到来自粉丝的需求--可视化大屏怎么做? 难道是大家年底都在冲业绩? 既然说到可视化驾驶舱大屏,必然是我很感兴趣的了,下面是自己多年的教程和心得分享给大家. 工具选择 Excel.p ...

  9. cesium 经纬度绘制点_炫酷大屏地图自定义绘制(一)

    现在数据中台的概念炒的火热,那在收集到数据后就要想办法去设计大屏,可视化展现.往往大屏都会涉及到地理位置的显示.对于常见的省市区,网上都已经提供了地理json数据,那对于需要定制化的我们要怎么处理呢? ...

最新文章

  1. go where 不等于_go基础之map迭代(四)
  2. 【QM-04】Inspection Characteristic(检验特征)
  3. unity3d软阴影和硬阴影的原理_Unity3D中两种默认阴影的实现
  4. http 请求默认时间_JMeter接口测试之HTTP请求默认值
  5. 耗时1年的前端技术框架切换之旅
  6. 为什么选择react?为前端开发选择React的六大理由
  7. JavaScript——BOM知识
  8. 代码流程图_助力理解js代码,进阶JavaScript代码能力——js2flowchart
  9. 降维系列之 LTSA 局部切空间排列
  10. 算法竞赛入门经典(刘汝佳版)例题与解答
  11. DDoS是什么意思?
  12. ESP32 ESP-IDF 获取GPS北斗模块的经纬度和日期时间
  13. 电脑变慢,电脑运行速度 突然变慢是怎么回事
  14. CE扫雷20211031
  15. 如何拿到阿里offer的?面试流程及面试题
  16. 【观察】星环科技重构数据云平台,持续释放数据红利和价值
  17. java实现打字母小游戏
  18. 评估通用社区测试计划的性能并预测结果
  19. 如何在微信小程序中使用ECharts图表
  20. 远程控制网吧服务器,方便维修,电脑坏了不用愁,向日葵电脑远程维修省时又省力...

热门文章

  1. python定时开关机的代码_python自动循环定时开关机(非重启)测试
  2. 浙江大学计算机应用基础登录,浙江大学远程教育计算机应用基础1.计算机基础知识题...
  3. 【笔记】ubuntu 中 移动硬盘无弹出选项的解决办法:sudo ntfsfix /dev/move_disk_name
  4. 为什么中国需要职业经理人?
  5. Windows 将Tomcat开机自启(配置到Local Service中)
  6. 智慧城市背景下Python机器学习项目实战案例分享
  7. 分享个人常用的十款软件免费下载
  8. 利用vscode stylelint插件实现ctrl+s自动格式化vue项目中的css、scss
  9. 洛谷 P1104生日 C语言
  10. TimesTen 应用层数据库缓存学习:8. 配置Sliding Window(滑动窗口)