高仿QQ Xplan的H5页面(1):threejs创建地球

上个月底,在朋友圈看到一个号称“这可能是地球上最美的h5”的分享,点进入后发现这个h5还很别致,思考了一会,决定要不高仿一个?

到今天为止,高仿基本完成,

除了手机端的media控制没有去兼容,其他的基本都给仿了。 那为了让你觉得是高仿,最好使用chrome的手机调试模式进行访问。微信打开将听不见声音看不到视频... (后面再有时间看是不是仿的再进一步)

之所以要仿它,因为觉得这个h5还挺酷,想看看自己需要花多长时间找到并实现它的技术路径。

需求分析

这个h5的主要玩法很简单:地球自转的时候会播放背景音乐(比如海浪声),为了找到这个声音是从哪个地球上哪个地方传来的,需要长按下方的按钮,这时地球会自动转动到目标地点,然后镜头拉近,穿过云层,最后你会看到和这段声音相关的视频内容;松开手之后,上面的过程会倒退回去,地球又开始自转,播放着下段神秘的背景音乐。

个人觉得这个设计还是很新颖的,不是说用了3D的效果,而是将一个看起来很复杂的动画(从宇宙拉近到地表的过程),使用最基础的3D效果和其他一些常规的动画手法去实现,并且能流畅的运行在手机浏览器上。另外还有声音和视频的完美搭配,用户体验不错。

反复观察,理清页面功能:

  1. 加载:加载进度百分比,饶椭圆轨道运行的小行星作为loading动画(这个动画我没有做)
  2. 地球:3D球体,旋转入场动画,自转,漂移的云层,城市的坐标点,镜头的旋转与拉近,穿越云层动画
  3. 星空背景:静态星空背景图,动态(闪烁的)星星,划过的流星
  4. 隐藏的音频和视频:按内容(地理位置)划分的音频和视频内容
  5. 其他:操作指引示意动画,地球上方会显示当前城市的经纬度,“了解更多”的结语页面等

寻找技术路径

打开chrome inspect一下。

首先是这个地球,得看看它是真3D还是假3D(因为很多3D效果是拿雪碧图做的,比如这里的旋转的3D飞机),结果找到了:

<div class="ns-webgl-page">
    <canvas width="750" height="1200" style="width: 375px; height: 600px;"></canvas>
</div>

并且在网站source文件中搜到了THREE,那就是threejs没跑了。

然后是那个穿越云层的效果,猜测可能是GIF,可能是SpriteSheet Animation,也有可能是一段视频。但是考虑到这个穿越的动画可以正反双方播放,那么就很可能是是SpriteSheet Animation了,否则GIF或者视频文件需要两个动画方向各准备一份。这个从chrome debug工具的network下找到了证据—— 页面下载了一系列名为kf_cloud_0000X.jpg的图片文件。顺手就把它们down下来,备用。

再就是背景音乐和隐藏视频的问题,同样在network下,找到了两个文件,一个mp3一个mp4,每个文件都包含了所有片段,就像是media的雪碧图,只在需要的时候控制播放对应片段而已。

其他的内容都没什么问题,CSS动画或者CANVAS都好做。那么到此,技术路径都清楚了,准备开始写代码。

难点突破

对于我而言,用threejs绘制地球可能会是难点,threejs没有用过,而且印象中对3D的东西,一直比较敬畏。如果3D的地球弄不出来,这个项目其他的都做完了,在浩瀚的宇宙中是怎么也找不到“声音来自何方”了。

OK,来看threejs怎么能弄出个地球来。(这个阶段并没有开始项目代码,而是尽量的在一个临时文件中进行涂鸦,快速随意的达到绘制出地球的目的就行了)

官网

对于新的技术,首先得看官网。这里并不是来全面学习threejs的,而是抱着很强的目的性去实现特定功能,因此直接去示例中找,是否有类似实现可以借鉴。在官网首页中,通过缩略图,找到了下面三个关于地球的例子。

可惜,貌似这里的例子都是一些产品应用,代码都是压缩过的。于是开始去寻找官方示例,最后在examples里找到了canvas_geometry_earth,最棒的是在github上有源码

示例代码

clone下threejs的项目代码,找到上面的示例文件。示例代码不到200行,阅读之后发现其实threejs和之前接触过的一些2D的游戏引擎(createjs,pixijs)等比较类似,都需要有场景(scene),要有渲染循环(render loop),在scene上添加对象(Mesh)或者是group;而Mesh由形状(Geometry)和材质(Material)组成,Material则又是由图片创建的纹理(Texture)而来。不同的是,这里有相机(Camera),有光线(Light),还有一些一直都不明白的距离单位问题。

稍微改动一下示例代码,就能创建出来了earth。但是从使用的资源来看,只有一个地表纹理贴图(earth4.jpg),而xplan中还有3个关于earth的图片文件:

不确定bump和spec是什么,我的思路是先在官方文档中找这些关键词,如果找不到,就加上threejs一起去做google。官网上找到了bump相关的东西,但帮助最大的是google出来的一篇详细的如何使用threejs创建earth的教程。(如果这个教程早点冒出来,也省了前面改示例代码的时间了。主要也源于对threejs不熟悉,没有想到哪些示例可能已经有很多教程了)

换上了earth4.jpg贴图之后:

教程中的步骤不再这里重复,下面仅仅对一些关键东西作简单的解释。

earth_bump

了解到bumpmap:

Bump mapping is a technique to simulate bumps and wrinkles on the surface of an object. The result is an apparently bumpy surface rather than a smooth surface although the surface of the underlying object is not actually changed. I'm sorry, you can't tilt the camera to see 3D mountains with this technique. You can adjust the bump effect (how much the map affects lighting) with the bumpScaleparameter

threejs中bumpmap是调节对光线的感知,来使人能明显感觉到不光滑的表面,而并没有在mesh中添加起伏,即没有真的改变形状。

官方bumpmap示例效果图如下:

其实这里的earth_bump.jpg就是一个DEM,在threejs中称作bumpmap,在其他一些地方也有被叫做heightmap。即用灰度图表达高程,越黑表示高程越低,越亮表示高程越高。GIS专业中常用,unity3D中创建地形也会用到这个。

添加了earth_bump之后:

earth_spec

了解到了earth_spec.jpg是specular map,用来调节镜面反射的,这里主要是调节海洋对光线的反射,增加真实性。

添加了earth_spec之后:

漂移的云层

云层的添加, 前面的教程里已经很详细了,其实就是一个同心,半径大一点的球体而已。

添加了云层之后:

浮动的标签

xplan中地球表面有城市标签,会随着地球的自转而移动,同时又保持了水平的方向。google关键词:threejs floating label。于是找到:

找到方向就好办,稍微参考一下官方API文档和找到的示例代码,能够很容易的在earth上添加上浮动标签。

小结

到这里,3D地球的绘制基本差不多了。虽然threejs是新东西,但是绝大部分功能都容易找到方向,并且改动一下示例代码都够快速的实现我们想要的效果,所这个过程并不难。重点是如何在一个未知的领域内找到想要的东西,并且快速的为自己所用。

但过程中我碰到一个性能问题,耽误了很久。xplan的页面在chrome的PC和手机模式都有近60的FPS,但是我创建的earth在PC有60,但是在手机模式却不到30!最后逐一调试代码,修改参数,花了好久才找到原因:

renderer.setPixelRatio(window.devicePixelRatio)

threejs的示例代码中都有这么一行,就是这一行导致了我的代码比xplan的代码在手机上绘制的像素点翻倍,从而导致了性能成倍的下降。

另外,前面也提到,我对于3D框架中的距离单位和坐标问题,很模糊。于是这里,关于earth的大小,camera朝向,每个城市标签的三维坐标和其他关与三维坐标的问题,我都硬抄了xplan的参数(幸好他们的代码没有压缩...)。还有一个要承认的,就是地球后面的淡蓝色光晕效果,貌似用了一些高级的渲染技术,我也就硬搬了xplan这部分代码。

下一篇将介绍如何制作多步骤可进可退的动画,在我看来这个才是技术难点。

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

推荐阅读更多精彩内容