博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个炫酷大屏展示页的打造过程
阅读量:6528 次
发布时间:2019-06-24

本文共 5057 字,大约阅读时间需要 16 分钟。

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

今年的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;}复制代码

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

  • 1 1
  • , ,
  • 4 1
  • 5 5
  • 6 2
复制代码
.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 += ('
  • ' + '' + formArr[i] || '' + '' + '' + toArr[i] || '' + '' + '
  • '); } else { numberHTML += ('
  • ' + '' + formArr[i] || '' + '' + '' + toArr[i] || '' + '' + '
  • '); } } 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个。此外还有其他参数,就不再逐一列出了。 最后,一起来看看效果吧!

    转载地址:http://mgtbo.baihongyu.com/

    你可能感兴趣的文章
    JAVA多线程的问题以及处理【转】
    查看>>
    【Java面试题】10 abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?...
    查看>>
    简单记录一次ORA-00600 kcratr_nab_less_than_odr
    查看>>
    如何新建UML2项目?详细操作步骤介绍
    查看>>
    [精讲17] 组策略
    查看>>
    控制流
    查看>>
    interlij的快捷键
    查看>>
    如何在Rancher上运行Elasticsearch
    查看>>
    shell 找出数组元素中的最大值
    查看>>
    Vmware虚拟机linux系统混合模式上网
    查看>>
    MySQL在导入的时候遇到的错误
    查看>>
    LINUX 常用命令整理
    查看>>
    iOS 位枚举
    查看>>
    德国禁止Facebook利用WhatsApp用户信息:没法律基础
    查看>>
    全球太阳能产业掣肘在哪儿?
    查看>>
    “灾备全生态”全揭秘
    查看>>
    CSS盒子模型
    查看>>
    Zeppelin Prefix not found.
    查看>>
    ubuntu中eclipse安装svn插件问题
    查看>>
    linux 的网络设置
    查看>>