深入理解three.js对svg的支持(二):SVGRenderer
来源:互联网 发布:内存卡数据恢复软件 编辑:程序博客网 时间:2024/06/07 00:13
前言:SVG作为一种优秀的矢量图形格式在Web得到广泛应用,three.js作为知名的WebGL库自然也对其提供了支持。然而,官方文档中对此的说明十分单薄,网上与此相关的资源也不多。经过多次试验之后,在此分享我的一点理解,包括SVGLoader,SVGObject,SVGRenderer,svg和THREE对象的互相转化等内容。
2 SVGRenderer
上文说到了SVGRenderer
的机制,那么这一节就来看看源码。源码不长,只有500多行。
2.1 THREE对象转svg
SVGRenderer
代码的核心在this.render
方法上。渲染的数据从投影得来:
_projector = new THREE.Projector(),..._renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );_elements = _renderData.elements;_lights = _renderData.lights;
至于Projector.js
就复杂多了,单单projectScene
方法代码的行数就和整个SVGRenderer.js
一样多,不再深究,有兴趣的自行研读。
_renderData
包含了元素和光照信息。撇开光照不谈,数组_elements
是核心数据,对其进行遍历渲染。这里将元素分为了3种类型,是根据Projector.js
制定,但不完全对应。3种类型分别是THREE.RenderableSprite
、THREE.RenderableLine
、THREE.RenderableFace
,每个类型的判断中分别调用各自的render函数,如renderLine
等,各自的render函数大同小异,核心流程和函数定义的伪代码如下:
//遍历元素将数据放入_svgfor e in elements: if e是3种的某一种: 处理数据 调用自己的render方法flushPath()//将最后一条路径数据存入_svg,因为addPath机制的原因,最后一条路径不会调用flushPath,因此_currentPath中的数据不会保存到_svg中,得手动来一下//函数定义3种render: 将数据按照svg path格式编码到path、处理style; addPath(style,path);addPath: if style == _currentStyle: path放入_currentPath; else: flushPath(); 清空_currentPath和_currentStyle;flushPath(): _currentPath和_currentStyle数据放入_svg; 清空_currentPath和_currentStyle;
注意到这里有一个_svg对象,它在一开始就被定义为DOM元素,所有的内容都在此对象下显示,其构建完成之后就是一个完整的svg图像。
SVGRenderer
的功能还是很强大的,可以将视口中的三维物体转为二维svg显示(统一使用<path>
编码)。如官方的例子就是将一组动态的THREE.Line
转为了svg的path在SVGRenderer中显示。
2.2 SVGObject
等等,前面的这些都是三维对象转svg的例子,那么SVGObject
是怎样在SVGRenderer
中显示的呢?
其实SVGRenderer.js
的源码首先就给出了SVGObject
的定义:
THREE.SVGObject = function ( node ) { THREE.Object3D.call( this ); this.node = node;};THREE.SVGObject.prototype = Object.create( THREE.Object3D.prototype );THREE.SVGObject.prototype.constructor = THREE.SVGObject;
可见SVGObject
确实是继承自Object3D
,但是注意构造函数,有个传入参数node
,并且还动态扩展了一个属性this.node
,这个就是SVG文件的根节点啊,有种不好的预感……
先不管,看它是如何渲染的呢?render的最后有这么一段代码:
scene.traverseVisible( function ( object ) { if ( object instanceof THREE.SVGObject ) { _vector3.setFromMatrixPosition( object.matrixWorld ); _vector3.applyMatrix4( _viewProjectionMatrix ); var x = _vector3.x * _svgWidthHalf; var y = - _vector3.y * _svgHeightHalf; var node = object.node; node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' ); _svg.appendChild( node ); } } );
原来渲染流程的最后会通过遍历查找scene中的SVGObject对象,单独处理SVGObject!对,2.1小节部分的render代码你怎么改都和SVGObject的显示没关系……,读取其node——合着是把我们的svg图像放到了_svg里,再放到DOM里而已,纯粹是多套了一层啊——坑爹呢是!
怪不得不能用变换,因为数据都在node属性里,又没有提供任何操作node的方法,你变transform和这个扩展出来的node没有任何关系。想变的话。。。改源代码吧——但又回到svg蛋疼的变换上去了。(我想静静)
下篇中,将对svg于THREE对象的关系进行进一步的探索。
- 深入理解three.js对svg的支持(二):SVGRenderer
- 深入理解three.js对svg的支持(三):svg转three对象
- 深入理解three.js对svg的支持(一):SVGLoader
- FLEX2对SVG的支持
- IE对SVG的支持
- js深入理解(二)
- Three.js学习计划(二)
- 深入理解svg的描边
- SVG:textPath深入理解
- 二.js中对this的理解
- 深入探讨SQL Server 2000对XML的支持(二)
- 我的three.js学习记录(二)
- Three.js(二)LOD源码注释
- js语法深入三:对js函数的理解及深入讨论
- QTP关键技术(二) - 对Check Point的较为深入理解
- QTP关键技术(二)---对Check Point的较为深入理解【转】
- IE对SVG支持不好
- node.js学习之路(二)之“深入理解面向对象的JavaScript”
- Rootkit
- [JZOJ2368]. 【SDOI2011】黑白棋
- HDU-2578 Dating with girls(1) (map/set/折半法)
- 12.8线程和信号
- Android利用阴影让标题栏出现层次感
- 深入理解three.js对svg的支持(二):SVGRenderer
- Java之数组
- 个人所得税计算
- 2017.7 13 NOIP模拟赛
- bzoj2190: [SDOI2008]仪仗队
- MUI前端框架轮播图片+九宫格(左右滑动)
- BZOJ 1054 [HAOI2008]移动玩具
- 初识线段树
- linux C学习之实现简单的web服务器