“从前有座山,山里有座庙,庙里有个......”我们喜欢这样讲故事,有头有尾,一个调用接一个,特别因为JS本身的一些特点,往往我们会发现,半路杀出个“程咬金”,一些对象变量临场出现让人迷糊,这里面弄清楚整个流程显得尤为重要,搞清楚这个引擎流水线,我们才能把控这里面的机制。Cesium实时刷新,就是说每一帧都在更新,这就像最原始的动画制作一样,一页翻完翻另一个,只是刷新间隔快了,我们眼皮没发觉(但这也是一般状态下,如果场景完全静悄悄也可请求渲染模式,这时就不是每一帧都更新了,这个我们后面再说,先认为是动起来的)。
我们在初始化一个球的时候,比较常用的个方式是创建一个Viewer容器,如下:
var viewer = new Cesium.Viewer('cesiumContainer', {
shadows : true
});
然后可以在里面初始化一堆参数,很多人就误以为这个球的开口就是Viewer,其实不然;Viewer只是一个简单的启动器,帮忙携带了一些球启动的参数,但归根结底它仍然是一个二次封装的产物。Cesium球的大门在CesiumWidget里。在Viewer里我们可以看到,经过一通传递和组合,用户传入的参数,最终还是构建给了CesiumWidget:
var cesiumWidget = new CesiumWidget(cesiumWidgetContainer, {
imageryProvider: createBaseLayerPicker || defined(options.imageryProvider) ? false : undefined,
skyBox : options.skyBox,
scene3DOnly : scene3DOnly,
shadows : options.shadows,
mapMode2D : options.mapMode2D,
requestRenderMode : options.requestRenderMode
......
});
options就是在外围Viewer传入进来的,包括最基础的影像、阴影设置等,一个widget包含一个三维场景。我们转入来看CesiumWidget,这里面也洋洋散散为自己也为外围调用封装了一堆东西,可谓是细致入微,但我们最终要看的是startRenderLoop函数
function render(frameTime) { if (widget._useDefaultRenderLoop) { try { ...... requestAnimationFrame(render); } } catch (error) { ...... } } } requestAnimationFrame(render);<