SU7原来是这歌原理!!

628 阅读5分钟
  1. HTML5 Canvas基础
  2. 2D绘图上下文
  3. WebGL简介
  4. 三维地球的实现
  5. 性能优化与最佳实践
  6. 现代Web图形技术的发展

下面我们将逐步展开这些主题,并结合你的代码示例进行详细解释。


HTML5 Canvas基础

什么是Canvas?

<canvas> 是HTML5引入的一个新元素,用于通过脚本(通常是JavaScript)绘制图形。它提供了一个可以通过JavaScript进行像素级操作的绘图表面,支持2D和3D(WebGL)绘图上下文。

基本结构

在你的代码中,我们看到如下结构:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D earth</title>
</head>
<body>
    <!-- html5画布 -->
    <canvas id="webglcanvas"></canvas>
    <script>
        //DOM 3D 绘制的容器
        const canvas = document.getElementById('webglcanvas')
        //绘制的上下文 2d su7 webgl
        const ctx = canvas.getContext('2d')
        ...
    </script>
</body>
</html>

这段代码定义了一个 <canvas> 元素,并通过 JavaScript 获取其绘图上下文。接下来,我们将详细介绍如何使用 canvasgetContext 方法。


2D绘图上下文

获取上下文

获取2D绘图上下文的方式如下:

const ctx = canvas.getContext('2d');

这将返回一个 CanvasRenderingContext2D 对象,该对象提供了用于在 <canvas> 上绘制2D图形的方法和属性。

绘制基本形状

在你的代码中,你使用了以下方法来绘制一个圆形:

ctx.beginPath();
let x = canvas.width / 2;
let y = canvas.height / 2;
let radius = 70;
let startAngle = 0;
let endAngle = 2 * Math.PI;
let counterClickwise = false;

ctx.arc(x, y, radius, startAngle, endAngle, counterClickwise);

ctx.fillStyle = 'green';
ctx.strokeStyle = 'blue'; // 注意这里应该是 'blue' 而不是 'bule'

ctx.lineWidth = 5;

ctx.fill();
ctx.stroke();

ctx.closePath();

beginPath()

开始一个新的路径,清除任何当前路径。

arc()

绘制一个圆弧或完整的圆。参数包括:

  • 圆心坐标 (x, y)
  • 半径 radius
  • 起始角度 startAngle
  • 结束角度 endAngle
  • 是否逆时针绘制 counterClockwise

fillStylestrokeStyle

设置填充颜色和描边颜色。在你的代码中,填充颜色被设置为绿色,描边颜色被设置为蓝色。

lineWidth

设置线条的宽度。

fill()stroke()

分别填充路径和描边路径。

closePath()

结束当前路径,使其闭合。

错误修正

注意到你在代码中有一个拼写错误:ctx.stokeStyle = 'bule'; 应该是 ctx.strokeStyle = 'blue';


WebGL简介

什么是WebGL?

WebGL 是一种用于渲染交互式3D和2D图形的JavaScript API,无需插件即可在任何兼容的现代浏览器中运行。WebGL 使用 OpenGL ES 2.0 API 来绘制图形,并且可以利用 GPU 加速。

获取WebGL上下文

虽然你在代码中使用了 getContext('2d'),但如果你想要绘制3D图形,应该使用 getContext('webgl')getContext('experimental-webgl')

const gl = canvas.getContext('webgl');

WebGL的基本步骤

  1. 初始化上下文:获取 WebGL 上下文。
  2. 创建着色器程序:编写顶点着色器和片段着色器,并将其链接到一个程序。
  3. 准备缓冲区:将顶点数据传递给 GPU。
  4. 绘制图形:调用 gl.drawArraysgl.drawElements 进行绘制。

实现3D地球

要实现一个简单的3D地球,你需要使用WebGL并加载纹理贴图。以下是一个简化的步骤:

  1. 加载纹理:从图像文件加载地球的纹理。
  2. 创建球体几何体:使用三角形网格创建一个球体。
  3. 应用光照模型:添加光源以增强真实感。
  4. 旋转地球:通过不断更新旋转矩阵来模拟地球自转。

三维地球的实现

创建球体几何体

你可以使用库如 three.js 来简化这个过程。以下是一个使用 three.js 的简单示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Earth with three.js</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        let scene, camera, renderer, geometry, material, mesh;

        init();
        animate();

        function init() {
            // 创建场景
            scene = new THREE.Scene();

            // 创建相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.z = 2;

            // 创建渲染器
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // 创建球体几何体
            geometry = new THREE.SphereGeometry(0.5, 32, 32);

            // 创建材质并加载纹理
            const textureLoader = new THREE.TextureLoader();
            const texture = textureLoader.load('earth.jpg'); // 替换为实际的地球纹理图片
            material = new THREE.MeshBasicMaterial({ map: texture });

            // 创建网格并将几何体和材质组合在一起
            mesh = new THREE.Mesh(geometry, material);
            scene.add(mesh);

            // 监听窗口大小变化
            window.addEventListener('resize', onWindowResize, false);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);

            // 旋转地球
            mesh.rotation.y += 0.01;

            renderer.render(scene, camera);
        }
    </script>
</body>
</html>

解释

  • THREE.Scene():创建一个场景,所有物体都添加到场景中。
  • THREE.PerspectiveCamera():创建一个透视相机,参数包括视野角度、宽高比、近裁剪面和远裁剪面。
  • THREE.WebGLRenderer():创建一个WebGL渲染器,负责将场景渲染到屏幕上。
  • THREE.SphereGeometry():创建一个球体几何体。
  • THREE.TextureLoader():加载纹理图像。
  • THREE.MeshBasicMaterial():创建一个基本材质,并应用纹理。
  • THREE.Mesh():将几何体和材质组合成一个网格对象。
  • requestAnimationFrame():用于创建动画循环,每帧都会调用一次 animate 函数。

性能优化与最佳实践

性能优化技巧

  1. 减少绘制调用:尽量合并绘制调用,减少GPU的工作量。
  2. 使用缓存:对于静态内容,可以使用缓存来避免重复计算。
  3. 减少状态切换:频繁的状态切换(如更改颜色或纹理)会影响性能。
  4. 使用低分辨率纹理:对于远处的物体,可以使用较低分辨率的纹理。
  5. 启用深度测试:确保正确处理遮挡关系,避免不必要的绘制。

最佳实践

  1. 模块化代码:将代码拆分为小的模块,便于维护和重用。
  2. 错误处理:添加适当的错误处理机制,确保代码的健壮性。
  3. 使用工具:利用调试工具(如Chrome DevTools)来分析性能瓶颈。
  4. 文档注释:为关键部分添加详细的注释,方便他人理解。

WebAssembly

WebAssembly(简称Wasm)是一种新的二进制格式,可以在现代浏览器中高效执行。它允许开发者使用C、C++等语言编写高性能代码,并在浏览器中运行。

WebGL 2.0

WebGL 2.0 提供了更多的功能和更好的性能,包括更强大的着色器语言(GLSL ES 3.0)、多采样抗锯齿(MSAA)等。

Three.js 和其他库

Three.js 是一个流行的3D图形库,简化了WebGL的使用。除此之外,还有许多其他库,如 Babylon.js 和 PlayCanvas,它们也提供了丰富的功能和易用的API。

AR/VR

随着增强现实(AR)和虚拟现实(VR)技术的发展,Web图形技术也在不断进步。WebXR API 允许开发者创建沉浸式的AR和VR体验。