一个炫酷大屏展示页的打造过程
来源:互联网 发布:超牛手机数据恢复软件 编辑:程序博客网 时间:2024/06/16 22:24
作者:韩永豪 移动开发部 前端开发工程师
今年的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个。此外还有其他参数,就不再逐一列出了。 最后,一起来看看效果吧!
- 一个炫酷大屏展示页的打造过程
- 从零开始打造一个新闻订阅APP之Android篇(三、关于图片加载、展示的那些事)
- tableView展示数据的过程
- 一个形象展示浏览器事件冒泡与捕获过程的demo
- 一个listview列表的展示
- 打造一个实用的Ubuntu
- 打造一个实用的Ubuntu
- 打造一个精简的BaseActivity
- 打造一个通用的TitleView
- 一个随机显示风格的DIV+CSS展示页
- 使用CoordinatorLayout打造一个炫酷的详情页
- 使用 CoordinatorLayout 打造一个炫酷的详情页
- 使用CoordinatorLayout打造一个炫酷的详情页
- 一种tab效果展示的实现过程
- 使用MFC做的汉诺塔过程展示
- web页面展示的部分过程
- 展示如何用证书签名一个存储过程
- 给我一个展示自己的机会
- HDU-1255 覆盖的面积 (线段树 求矩形覆盖面积)
- cs231n笔记(5)--传统神经网络,激活函数
- 网络Cisco实验-同一交换机不同VLAN通信
- Til the Cows Come Home POJ
- 哈尔滨理工大学第七届程序设计竞赛决赛 B 幸运大奖
- 一个炫酷大屏展示页的打造过程
- java的整数类型,浮点类型,字符类型
- py3爬虫项目
- LeetCode题解:188. Best Time to Buy and Sell Stock IV
- Hibernate中持久化对象的三种状态
- 三个线程轮流执行顺序打印ABC(三):使用Lock实现
- poj 2175 费用流+消圈
- Visual Studio 2017 配置OpenCV 3.3教程
- 数据结构实验之查找二:平衡二叉树