使用PWA构建一个 Three.js 案例

发布于:2025-03-01 ⋅ 阅读:(14) ⋅ 点赞:(0)

使用 PWA(Progressive Web App) 构建一个 Three.js 案例,可以让你创建一个具有离线功能、快速加载和原生应用体验的 3D 网页应用。以下是详细的步骤和代码示例,帮助你实现这一目标。


1. PWA 简介

PWA 是一种现代网页技术,通过 Service Worker、Web App Manifest 等技术,使网页应用具备以下特性:

  • 离线访问:通过缓存资源,用户可以在没有网络的情况下访问应用。
  • 快速加载:通过预缓存和资源优化,提升加载速度。
  • 原生体验:可以添加到主屏幕,像原生应用一样运行。

2. 项目结构

我们将创建一个简单的 Three.js PWA 项目,项目结构如下:

/threejs-pwa
  ├── index.html
  ├── styles.css
  ├── main.js
  ├── service-worker.js
  ├── manifest.json
  └── assets
      ├── icon-192x192.png
      └── icon-512x512.png

3. 实现步骤

3.1 创建 HTML 文件

index.html 中引入 Three.js 库,并设置 PWA 的基本结构。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js PWA</title>
    <link rel="stylesheet" href="styles.css">
    <link rel="manifest" href="manifest.json">
</head>
<body>
    <div id="container"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r146/three.min.js"></script>
    <script src="main.js"></script>
    <script>
        // 注册 Service Worker
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('service-worker.js')
                .then(() => console.log('Service Worker 注册成功'))
                .catch(err => console.error('Service Worker 注册失败:', err));
        }
    </script>
</body>
</html>

3.2 创建 CSS 文件

styles.css 中设置页面样式,确保 3D 场景填满整个屏幕。

body, html {
    margin: 0;
    padding: 0;
    overflow: hidden;
    height: 100%;
}

#container {
    width: 100%;
    height: 100%;
}

3.3 创建 Three.js 场景

main.js 中编写 Three.js 代码,创建一个简单的 3D 场景。

// 场景
const scene = new THREE.Scene();

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

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('container').appendChild(renderer.domElement);

// 立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 动画循环
function animate() {
    requestAnimationFrame(animate);
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene, camera);
}

animate();

// 窗口大小调整
window.addEventListener('resize', () => {
    const width = window.innerWidth;
    const height = window.innerHeight;
    renderer.setSize(width, height);
    camera.aspect = width / height;
    camera.updateProjectionMatrix();
});

3.4 创建 Service Worker

service-worker.js 中编写 Service Worker 代码,用于缓存资源和实现离线功能。

const CACHE_NAME = 'threejs-pwa-v1';
const ASSETS_TO_CACHE = [
    '/',
    '/index.html',
    '/styles.css',
    '/main.js',
    'https://cdnjs.cloudflare.com/ajax/libs/three.js/r146/three.min.js'
];

// 安装 Service Worker
self.addEventListener('install', (event) => {
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then((cache) => cache.addAll(ASSETS_TO_CACHE))
            .then(() => self.skipWaiting())
    );
});

// 拦截网络请求
self.addEventListener('fetch', (event) => {
    event.respondWith(
        caches.match(event.request)
            .then((response) => response || fetch(event.request))
    );
});

// 激活 Service Worker
self.addEventListener('activate', (event) => {
    event.waitUntil(
        caches.keys().then((cacheNames) => {
            return Promise.all(
                cacheNames.map((cacheName) => {
                    if (cacheName !== CACHE_NAME) {
                        return caches.delete(cacheName);
                    }
                })
            );
        }).then(() => self.clients.claim())
    );
});

3.5 创建 Web App Manifest

manifest.json 中定义应用的元数据,使其可以添加到主屏幕。

{
    "short_name": "ThreePWA",
    "name": "Three.js PWA",
    "icons": [
        {
            "src": "assets/icon-192x192.png",
            "type": "image/png",
            "sizes": "192x192"
        },
        {
            "src": "assets/icon-512x512.png",
            "type": "image/png",
            "sizes": "512x512"
        }
    ],
    "start_url": "/",
    "background_color": "#ffffff",
    "display": "standalone",
    "scope": "/",
    "theme_color": "#000000"
}

3.6 添加应用图标

将应用图标(icon-192x192.pngicon-512x512.png)放入 assets 文件夹中。


4. 运行项目

  1. 将项目部署到支持 HTTPS 的服务器(PWA 必须运行在 HTTPS 环境下)。
  2. 打开浏览器访问应用。
  3. 浏览器会提示“添加到主屏幕”,点击后应用会像原生应用一样运行。

5. 测试离线功能

  1. 打开应用并等待 Service Worker 缓存资源。
  2. 关闭网络连接,刷新页面。
  3. 应用仍然可以正常运行,因为资源已被缓存。

6. 总结

通过以上步骤,我们成功构建了一个基于 Three.js 的 PWA 应用。它具备以下特性:

  • 离线访问:通过 Service Worker 缓存资源。
  • 快速加载:通过预缓存和资源优化。
  • 原生体验:可以添加到主屏幕,像原生应用一样运行。

你可以在此基础上进一步扩展功能,例如:

  • 加载复杂的 3D 模型。
  • 添加交互功能(如点击、拖拽)。
  • 使用 WebXR 实现 VR/AR 效果。

希望这篇教程对你有所帮助!如果你有任何问题,欢迎在评论区留言讨论。

注:如若尝试失败不妨前往博主GitHub仓库查看源代码


网站公告

今日签到

点亮在社区的每一天
去签到