题外话:
起手式,这个词第一次是从金庸的小说中看到的,通常用来向对手表示礼貌与尊敬,并不具备攻击性;大部分门派的基本功第一招都是起手式,因此也用来表示入门的第一步。
bg:
- 年会抽奖系统
- 头像滚动
- Powered by Three.js Based on WebGL
相关资料:
- Three.js 基础教程 // 比较入门的教程,非常好理解,但是 demo 里头的一些方法已经废弃,建议参照官网文档进行阅读
- 官网 // 官网并不是很适合入门,没有 tutorial,文档当字典用,demo 看看效果,源码也可以看点,但是不是很友好
- Three.js 开发指南.pdf // 电子书,上面俩找不到的东西,可以上这里头翻翻
- 淘宝团队 WebGL 技术储备指南 //有比较多的数学概念,不是很好理解,建议进阶阅读
正文
先上一个 Demo。概念的东西就不提了,在资料里头的教程里就能看到简单易懂的介绍。
首先撇开其他方面的依赖,直接回到最原始的开发环境中,也就是静态的 HTML 页面。
|
|
在这里头画了一个正方形(只是一个面), 调好 camera 与物体之间的距离,就能看到这个正方形。
让场景动起来的方法有两种,
- 移动 camera , 让场景相对动起来。
- 移动场景里头的物体,这是场景真正动起来。
现在我们要让场景动起来,下面 Demo 采用的是第一种方法,让 camera 动起来。在代码里头加入 animate 方法,下面这个 Demo 只改变了 z 轴的值,使 camera 前后移动。requestAnimationFrame
方法不明白自行 Google (之前看过一个很好的博文,找不着了)。
|
|
后来我又在 init 里头往场景里添加了许多物体,然后也是通过移动 camera 来使这些物体看起来像是在往前飞或者往后飞。
接下来我要给这个正方形贴上纹理,也就是把这个蓝色的正方形变成我想要的照片(也就是抽奖系统里的头像)。
教程里头使用是 THREE.ImageUtils.loadTexture
这个方法,但是实际应用后发现这个方法已经被废弃,后经过多方考证后我使用了 THREE.TextureLoader
对象里的 load 方法来载入纹理图片。
代码如下(我把 animate 方法去掉了):
|
|
上面这个代码直接访问是会有问题的。
以踩完坑的角度来看这个问题。这个坑有两个影响因素:
- 本地访问 THML 文件(file:///Applications/MAMP/htdocs/lottery/pic.html) 与 服务器访问 HTML 文件(http://localhost:8888/lottery/pic.html)
- 相对路径访问纹理纹理图片 与 绝对路径访问纹理图片
第一种情况: 本地访问 HTML 文件 + 相对路径访问纹理图片
console 中打出了两条日志:
- three.min.js:606 XMLHttpRequest cannot load file:///Users/poorbug/Desktop/lottery/logo.png. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
- An error happened
跨域错误,于是我把图片放到七牛上。
第二种情况:本地访问 HTML 文件 + 绝对路径( url )访问纹理图片
修改 load 方法中的第一个参数( url );此时从 console 与 network 都可以看出 load 方法已经成功加载图片。但同时也爆出了一个错误:
- three.min.js:119 DOMException: Failed to execute ‘texImage2D’ on ‘WebGLRenderingContext’: Tainted canvases may not be loaded.(…)
纹理并没有成功渲染上,还是有问题,在这一块卡了非常久。
可能是从跨域问题获得了灵感。我把本地服务器启动了。
第三种情况:服务器访问 HTML 文件 + 本地访问纹理图片
通过 localhost 访问 HTML 文件,则纹理能够成功贴上(不管是本地访问纹理图片还是通过服务器访问纹理图片)。
此时,完整代码如下(经过稍微加工,代码与上面 Demo 不完全一致):
总结
经过几天的学习,发现 Three.js 的教程实在是不多,有不少还有点过时。官网的文档又没有教程,demo 晦涩难懂,简直不忍多看。因此学习这个还是需要自己花点时间琢磨;参考网上的资料,自己动手试一试,不轻松,但是会有收获。
That’s all.