三维效果的展示可以使用WebGL来实现,而全景展示可以使用360度全景图实现。以下是一个简单的示例代码,使用html、css、js和WebGL技术来展示一个360度全景图:
HTML代码:
```html
<!DOCTYPE html>
<html>
<head>
<title>3D Antique Panorama</title>
<meta charset="utf-8">
<style>
#canvas {
width: 800px;
height: 600px;
margin: auto;
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="main.js"></script>
</body>
</html>
```
CSS代码:
```css
/* 无特殊样式 */
```
JS代码:
```javascript
// 图片资源
const IMAGE_SRC = 'antique.jpg';
// 创建WebGL上下文
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
// 顶点着色器
const VS_SOURCE = `
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_texcoord;
}
`;
// 片段着色器
const FS_SOURCE = `
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main() {
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
// 创建着色器
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
// 创建着色器程序
function createProgram(gl, vsSource, fsSource) {
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success) {
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
// 加载纹理
function loadTexture(gl, url) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
const level = 0;
const internalFormat = gl.RGBA;
const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE;
const image = new Image();
image.onload = function() {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image);
gl.generateMipmap(gl.TEXTURE_2D);
};
image.src = url;
return texture;
}
// 创建顶点缓冲数据
const positionData = [
-1.0, 1.0,
1.0, 1.0,
-1.0, -1.0,
1.0, -1.0,
];
const texcoordData = [
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionData), gl.STATIC_DRAW);
const texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoordData), gl.STATIC_DRAW);
// 创建着色器程序
const program = createProgram(gl, VS_SOURCE, FS_SOURCE);
// 获取属性和Uniform变量
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
const texcoordAttributeLocation = gl.getAttribLocation(program, 'a_texcoord');
const textureUniformLocation = gl.getUniformLocation(program, 'u_texture');
// 启用属性
gl.enableVertexAttribArray(positionAttributeLocation);
gl.enableVertexAttribArray(texcoordAttributeLocation);
// 设置属性指针
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.vertexAttribPointer(texcoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);
// 加载纹理
const texture = loadTexture(gl, IMAGE_SRC);
// 绘制函数
let angle = 0;
function draw() {
// 清空画布
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 设置视角
const aspect = canvas.clientWidth / canvas.clientHeight;
const fov = 60 * Math.PI / 180;
const zNear = 0.1;
const zFar = 100.0;
const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, fov, aspect, zNear, zFar);
// 设置模型矩阵
const modelMatrix = mat4.create();
mat4.rotateY(modelMatrix, modelMatrix, angle);
// 设置视图矩阵
const viewMatrix = mat4.create();
mat4.translate(viewMatrix, viewMatrix, [0, 0, -2]);
// 计算矩阵
const matrix = mat4.create();
mat4.multiply(matrix, projectionMatrix, viewMatrix);
mat4.multiply(matrix, matrix, modelMatrix);
// 设置Uniform变量
gl.useProgram(program);
gl.uniformMatrix4fv(textureUniformLocation, false, matrix);
// 绘制
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
// 更新角度
angle += 0.01;
if (angle > 2 * Math.PI) {
angle -= 2 * Math.PI;
}
// 循环调用
requestAnimationFrame(draw);
}
// 开始绘制
draw();
```
代码中的纹理加载使用了一个简单的图片资源,可以通过设置`IMAGE_SRC`变量来指定图片路径。这里使用`loadTexture`函数来加载纹理,然后通过`gl.uniform1i`函数将纹理传递给片段着色器。
在绘制过程中,我们通过计算相应的矩阵来实现视角变换和模型变换,并将矩阵传递给Uniform变量。然后,我们使用`gl.drawArrays`函数来绘制顶点缓冲数据。
最后,我们使用`requestAnimationFrame`函数来循环调用`draw`函数,使得全景图可以自动进行逆时针旋转。
需要注意的是,这里的代码只是一个示例,展示了如何使用WebGL技术来实现一个简单的全景图展示效果。如果要实现更复杂的三维效果,需要更加深入地掌握WebGL技术,并使用更加高级的算法和技巧来实现。