前端3D转换效果实现:CSS 和 WebGL
前端语言可以使用 CSS 和 JavaScript 来实现 3D 转换效果。
CSS 3D 转换效果:
CSS 可以通过 transform 属性来实现 3D 转换效果。其中,translateZ 属性用于沿着 z 轴移动元素。
例如,下面的代码实现了一个翻转的立方体效果:
.cube {
width: 100px;
height: 100px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(-50px);
}
.cube div {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
line-height: 100px;
font-size: 24px;
color: #fff;
}
.cube .front {
background-color: red;
transform: translateZ(50px);
}
.cube .back {
background-color: blue;
transform: rotateY(180deg) translateZ(50px);
}
.cube .left {
background-color: green;
transform: rotateY(-90deg) translateZ(50px);
}
.cube .right {
background-color: yellow;
transform: rotateY(90deg) translateZ(50px);
}
.cube .top {
background-color: purple;
transform: rotateX(90deg) translateZ(50px);
}
.cube .bottom {
background-color: orange;
transform: rotateX(-90deg) translateZ(50px);
}
JavaScript 3D 转换效果:
JavaScript 可以使用 WebGL 来实现复杂的 3D 效果。WebGL 是一种基于 OpenGL ES 的 API,它可以让 JavaScript 与 GPU 交互,实现高性能的 3D 渲染。
例如,下面的代码使用 WebGL 实现了一个旋转的立方体效果:
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');
var vertexShaderSource = `
attribute vec3 a_position;
attribute vec3 a_color;
uniform mat4 u_matrix;
varying vec3 v_color;
void main() {
gl_Position = u_matrix * vec4(a_position, 1.0);
v_color = a_color;
}
`;
var fragmentShaderSource = `
precision mediump float;
varying vec3 v_color;
void main() {
gl_FragColor = vec4(v_color, 1.0);
}
`;
var program = createProgram(gl, vertexShaderSource, fragmentShaderSource);
gl.useProgram(program);
var positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
var colorAttributeLocation = gl.getAttribLocation(program, 'a_color');
var matrixUniformLocation = gl.getUniformLocation(program, 'u_matrix');
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setCubePositions(gl);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
setCubeColors(gl);
gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorAttributeLocation);
var matrix = mat4.create();
var projectionMatrix = mat4.create();
var viewMatrix = mat4.create();
mat4.perspective(projectionMatrix, 45 * Math.PI / 180, canvas.width / canvas.height, 0.1, 100.0);
mat4.lookAt(viewMatrix, [0, 0, -5], [0, 0, 0], [0, 1, 0]);
mat4.multiply(matrix, projectionMatrix, viewMatrix);
var angle = 0;
function render() {
angle += 0.01;
mat4.rotateY(matrix, matrix, angle);
gl.uniformMatrix4fv(matrixUniformLocation, false, matrix);
gl.drawArrays(gl.TRIANGLES, 0, 36);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function createProgram(gl, vertexShaderSource, fragmentShaderSource) {
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error('Failed to link program: ' + gl.getProgramInfoLog(program));
}
return program;
}
function createShader(gl, type, source) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error('Failed to compile shader: ' + gl.getShaderInfoLog(shader));
}
return shader;
}
function setCubePositions(gl) {
var positions = new Float32Array([
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Left face
-1.0, -1.0, 1.0,
-1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
// Right face
1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, 1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
// Top face
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
}
function setCubeColors(gl) {
var colors = new Float32Array([
// Front face
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 0.0,
// Back face
1.0, 0.0, 0.0,
1.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
// Left face
0.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
// Right face
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 0.0,
// Top face
1.0, 1.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 0.0,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
// Bottom face
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 0.0,
]);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
}
原文地址: http://www.cveoy.top/t/topic/nUUB 著作权归作者所有。请勿转载和采集!