-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathcanvas_lines_dashed.html
261 lines (215 loc) · 9.36 KB
/
canvas_lines_dashed.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - dashed lines</title>
<meta charset="utf-8">
<!--
如果没有设置viewport的width的话,网页很可能会超出手机屏幕宽度,具体多宽,要看浏览器定义的默认宽度是多少
user-scalable=no,规定了用户不能缩放网页,但有些浏览器对该项支持不是很好,故需要设置minimum-scale和maximum-scale相同来限制用户缩放
-->
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #ffffff;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
z-index:100;
}
</style>
</head>
<body>
<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - dashed lines example</div>
<div id="container"></div>
<script src="../build/three.js"></script>
<!--
想要使用CanvasRenderer,必须添加如下两个js文件
Projector.js顾名思义上将3d图像投影到Canvas("2d")上,如果没有该文件会报如下错误
THREE.Projector has been moved to /examples/js/renderers/Projector.js. three.js:42883:3
TypeError: THREE.RenderableVertex is not a constructor
-->
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<!--
希尔伯特3D曲线
-->
<script src="js/geometries/hilbert3D.js"></script>
<!--
检测支持(canvas,webgl,workers,fileApi)
-->
<script src="js/Detector.js"></script>
<!--
统计插件(FPS,渲染时间,chrome内存使用率),min表示js代码经过压缩
-->
<script src="js/libs/stats.min.js"></script>
<script>
//如果不支持webgl,则会在当前的父布局上添加一个不支持的提示信息DIV
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var renderer, scene, camera, stats;
var objects = [];
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
init();
animate();
function init() {
/*
透视相机
PerspectiveCamera(fov, aspect, near, far)
fov(视场):从相机位置能够看到的部分场景。推荐默认值45
aspect(长宽比):渲染结果输出区域的横向长度和纵向长度的比值。推荐默认值window.innerWidth/window.innerHeight
near(近面):定义从距离相机多近的地方开始渲染场景。推荐默认值0.1
far(远面):定义相机可以从它所处的位置看多远。默认值1000
*/
camera = new THREE.PerspectiveCamera( 60, WIDTH / HEIGHT, 1, 200 );
camera.position.z = 150;
scene = new THREE.Scene();
/*
场景的两种雾化效果(这里没有打光,因此雾不会显示出来)
1. scene.fog = new THREE.Fog(color, near, far)
第一个参数是雾化效果或者颜色(0xffffff),后面两个属性用来调节雾的显示,重什么地方开始到什么地方结束
2. scene.fog = new THREE.Fog(color, concentration)
第一个参数是雾化效果或者颜色(0xffffff),第二个参数是雾的浓度(0.015)
*/
scene.fog = new THREE.Fog( 0x111111, 150, 200 );
root = new THREE.Object3D();
//样条曲线分的段数
var subdivisions = 6;
//希尔伯特曲线递归的次数
var recursion = 1;
/*
希尔伯特曲线
hilbert3D
* @param center Center of Hilbert curve.
* @param size Total width of Hilbert curve.
* @param iterations Number of subdivisions.
curve's count -> 4 ^ iterations 个首尾相连两边竖起的凹线
* @param v0 Corner index -X, +Y, -Z. 从上矩形的第二象限开始,先以逆时针画左矩形,再连到右侧,以顺时针画右矩形
* @param v1 Corner index -X, +Y, +Z.
* @param v2 Corner index -X, -Y, +Z.
* @param v3 Corner index -X, -Y, -Z.
* @param v4 Corner index +X, -Y, -Z.
* @param v5 Corner index +X, -Y, +Z.
* @param v6 Corner index +X, +Y, +Z.
* @param v7 Corner index +X, +Y, -Z.
*/
var points = hilbert3D( new THREE.Vector3( 0,0,0 ), 25.0, recursion, 0, 1, 2, 3, 4, 5, 6, 7 );
/*
样条曲线(CatmullRomCurve3)与贝赛尔曲线的区别(CubicBezierCurve、QuadraticBezier)
贝塞尔曲线只会穿过首尾两个控制点而不过中间的控制点,在某些场合希望曲线穿过所有控制点的话可以使用catmull-rom spline(简称CR-Spline)
CR-Spline需要至少4个控制点,首尾两个控制点为辅助点,曲线不会穿过,其余控制点在t=[0,1]之间平滑地穿过,t=0时值等于第2个顶点,而t=1时值等于倒数第2个顶点
如果传入的控制点首尾相等形成闭合环,那么不用计算,直接取值p0=pN-1,pN=p1就会成为一条光滑的曲线了。
*/
var spline = new THREE.CatmullRomCurve3( points );
var geometrySpline = new THREE.Geometry();
for ( var i = 0; i < points.length * subdivisions; i ++ ) {
//index是当前点占分段后的点索引的百分比
var index = i / ( points.length * subdivisions );
//通过插值得到的新点
var position = spline.getPoint( index );
geometrySpline.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
}
var geometryCube = cube( 50 );
//计算相邻两点的距离,目前还没发现有什么实际用途
//geometryCube.computeLineDistances();
//geometrySpline.computeLineDistances();
/*
THREE.Line使用WebGL中的gl.LINE_STRIP(一系列的连续直线,即折线)渲染
THREE.LineSegments使用WebGL中的gl.LINES(每一对顶点被解释为一条直线,即线段)渲染
LineDashedMaterial是虚线材质,dashSize定义了短划线的长度,gapSize定义了间隔的宽度
*/
var object = new THREE.LineSegments( geometrySpline, new THREE.LineDashedMaterial( { color: 0xffffff, dashSize: 1, gapSize: 0.5 } ) );
objects.push( object );
scene.add( object );
var object = new THREE.LineSegments( geometryCube, new THREE.LineDashedMaterial( { color: 0xffaa00, dashSize: 3, gapSize: 1, linewidth: 2 } ) );
objects.push( object );
scene.add( object );
renderer = new THREE.CanvasRenderer();
//设置渲染器的"清除色"和"透明度"
renderer.setClearColor( 0x111111 );
//设置屏幕像素比,与Android上的DIP相仿,作用是在所有设备上的显示效果都相近
renderer.setPixelRatio( window.devicePixelRatio );
//设置待渲染场景的大小
renderer.setSize( WIDTH, HEIGHT );
var container = document.getElementById( 'container' );
//将渲染器的DOM元素(即Canvas)添加到HTML中
container.appendChild( renderer.domElement );
//左上角的统计信息(FPS,渲染时间,chrome内存使用率)
stats = new Stats();
//这里注意,统计插件的dom元素是"dom",而不是domElement
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
}
//通过线段来构建一个边长为size的立方体
function cube( size ) {
var h = size * 0.5;
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, -h, h ),
new THREE.Vector3( h, -h, h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( h, -h, h )
);
return geometry;
}
function onWindowResize() {
//重新设置相机的宽高比。如果宽高比不对,那么正方形可能就不是正方形了
camera.aspect = window.innerWidth / window.innerHeight;
//更新透视相机的投影矩阵
camera.updateProjectionMatrix();
//更新待渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
//这里可以在render前后使用stats.begin和stats.end,也可以在每次渲染的时候调用一次stats.update
stats.update();
}
function render() {
//Date.now()得到的是当前时间戳,单位毫秒
var time = Date.now() * 0.001;
for ( var i = 0; i < objects.length; i ++ ) {
var object = objects[ i ];
/*
将旋转的角度按右手螺旋定则更新到原旋转角上
rotation.y是绕Y轴旋转
*/
//object.rotation.x = 0.25 * time * ( i%2 == 1 ? 1 : -1);
object.rotation.x = 0.25 * time;
object.rotation.y = 0.25 * time;
}
renderer.render( scene, camera );
}
</script>
</body>
</html>