通过鼠标事件,来控制立方体的旋转。通过鼠标点击事件
来控制立方体是否旋转,通过键盘键码值来控制立方体的运动方向。
所以在立方体的绘制的demo
里。添加如下代码就行。
# 1、常规方式实现旋转
- 在
init
方法中添加键盘事件,通过键盘事件来控制立方体向左、向右、向下和向上运动。
let rotate = false;
let xaxis = 0, yaxis = 0;
function init() {
...
document.addEventListener('keydown', (event) => {
const keyCode = event.keyCode;
switch (keyCode) {
case 38:
//向上旋转
xaxis = 1;
yaxis=0;
break;
case 40:
//向下旋转
xaxis = -1;
yaxis=0;
break;
case 37:
//想左旋转
yaxis = -1;
xaxis = 0;
break;
case 39:
//想右旋转
yaxis = 1;
xaxis = 0;
break;
}
})
document.addEventListener('click',()=>{
rotate=!rotate;
render(gl,program);
})
}
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
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
- 在
render
函数中添加动画
function render(gl, program, count = 36) {
tranlate(gl, program);
//设置清屏颜色为黑色。
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
if(!rotate) return;
requestAnimationFrame(() => {
render(gl, program, count);
})
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 在旋转函数中修改旋转角度
let angley = 30.0, anglex = 30;;
function tranlate(gl, program, unit = 1) {
const radx = anglex * Math.PI / 180;
const cosx = Math.cos(radx);
const sinx = Math.sin(radx);
const mx = gl.getUniformLocation(program, 'mx');
const mxArr = new Float32Array([
1, 0, 0, 0, 0, cosx, -sinx, 0, 0, sinx, cosx, 0, 0, 0, 0, 1
])
gl.uniformMatrix4fv(mx, false, mxArr);
const rady = angley * Math.PI / 180;
const cosy = Math.cos(rady);
const siny = Math.sin(rady);
const my = gl.getUniformLocation(program, 'my');
const myArr = new Float32Array([
cosy, 0, -siny, 0, 0, 1, 0, 0, siny, 0, cosy, 0, 0, 0, 0, 1
])
gl.uniformMatrix4fv(my, false, myArr);
angley += yaxis;
anglex += xaxis;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2、通过矩阵来实现立方体的旋转
所以这里我们需要创建矩阵,创建矩阵有两种投影方式,正交投影和透射投影。这里采用的是正射投影。这里跟常规方法也就顶点着色器
,init
和translate
中的代码略有不同。
在下面的矩阵运算中用到了一个matrix
的矩阵相关的库。库的链接地址为 (opens new window)
- 顶点着色器中的代码。这里就直接将矩阵相乘后的矩阵传递到顶点着色器中。
<script id="vertexShader" type="x-shader/x-vertex">
//浮点数设置为中等精度
precision mediump float;
attribute vec3 apos;
attribute vec4 acolor;
varying vec4 vcolor;
//uniform mat4 mx;
//uniform mat4 my;
uniform mat4 proj;
void main() {
//两个旋转矩阵、顶点齐次坐标连乘
//gl_Position = mx*my*vec4(apos, 1);
gl_Position = proj*vec4(apos, 1);
vcolor=acolor;
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
init
函数中的不同
let isrotate = false;
let xaxis = 0, yaxis = 0;
let projectionMatrix;
function init() {
...
//创建正交投影矩阵
const aspect = canvas.width / canvas.height;
projectionMatrix = matrix.ortho(-aspect * 1, aspect * 1, -1, 1, 200, -200);
...
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
rotate
函数,通过矩阵运算来实现立方体的旋转。
let angley = 30, anglex = 30;
//单位矩阵
let mvp = matrix.identity();
function rotate(gl, program) {
//先绕 Y 轴旋转矩阵。
matrix.rotationY(angley * Math.PI / 180, mvp);
//再绕 X 轴旋转
matrix.multiply(
mvp,
matrix.rotationX(anglex * Math.PI / 180),
mvp
);
//矩阵相乘
matrix.multiply(projectionMatrix, mvp, mvp);
const proj = gl.getUniformLocation(program, 'proj');
gl.uniformMatrix4fv(proj, false, mvp);
angley += yaxis;
anglex += xaxis;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
参考
WebGL零基础入门教程(郭隆邦) (opens new window) WebGL 入门与实践 (opens new window) WebGL官方文档 (opens new window)