脚本宝典收集整理的这篇文章主要介绍了

css3d-engine源码学习简析

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

开始

从这里开始准备攻略webgl(准备挖新坑),Flutter框架当然也会继续补充,但是今天学习的不是webgl,而是css3d-engine这个库,因为之前搞活动看到了一个全景旋转活动就是使用这个库完成,颇为惊艳(一开始以为是webgl实现的,但是看了代码才知道用CSS3就可以完成,虽然觉得还是应该用webgl做比较合适),抱着好奇心于是学习一下,嗯,这个库设计相当精简,整个库的代码才800多行,所以代码看下来没啥压力,今天顺着一个例子来分析一下。

全景旋转

首先学习一下基础坐标系:
css3d-engine源码学习简析-脚本宝典
这个只要记住一下x,y,z轴各自方向就可以,下面分析会用到。

接下来就是今天分析的例子,也是来自css3d-engine的例子:
图片描述

一个不停旋转的全景图,当然我们把镜头拉开一点,发现其实它是一个圆柱体不停在旋转:
图片描述

只是我们的镜头刚好在圆柱体的里面,所以就看到全景图不停在旋转了。

再接着分析构建整个场景的代码:

 var s = new C3D.Stage();
 s.size(window.innerWidth, window.innerHeight).material({
    color: "#cccccc"
 }).update();

这里会初始化整个舞台,也会创建默认的摄像机:

initialize: function (params) {
    ...
    this.el.style[prefix + 'Perspective'] = '800px';
    this.el.style[prefix + 'TransformStyle'] = 'flat';
    this.el.style[prefix + 'Transform'] = '';
    this.el.style.overflow = 'hidden';
    
    this.__rfix = new C3D.Sprite();
    this.el.appendChild(this.__rfix.el);
    
    this.__pfix = new C3D.Sprite();
    this.__rfix.el.appendChild(this.__pfix.el);
    
    this.setCamera(new C3D.Camera());
}

Stage初始化的时候,设置默认的perspective是设为800px,而且会创建两个Sprite辅助构建场景(这两个Sprite作用相当的大,场景旋转,拉进拉远都是靠这两个Sprite),最后设置摄像机;当调起update方法然后会顺着调起Stage的updateT方法:

updateT: function () {
            this.fov = fixed0(0.5 / Math.tan((this.camera.fov * 0.5) / 180 * Math.PI) * this.height);
            this.el.style[prefix + 'Perspective'] = this.fov + 'px';
            this.__rfix.position(fixed0(this.width / 2), fixed0(this.height / 2), this.fov).rotation(-this.camera.rotationX, -this.camera.rotationY, -this.camera.rotationZ).updateT();
            this.__pfix.position(-this.camera.x, -this.camera.y, -this.camera.z).updateT();
            return this;
        },

这里可以算是整个Stage计算的核心了,首先是Stage的fov计算,它依赖了Camera的fov,而Camera的fov默认就是75(因为人的有效视角就是75度),接着整个计算其实就是一个已知角度和对边求邻边的公式:
图片描述

这里计算方式其实出自Three.js,github上的讨论
回到Stage刚才初始化的时候,一开始一口气创建三个嵌套的div: