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

server/2025/3/1 4:59:52/

使用 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>javascript">// 注册 Service Workerif ('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 场景。

javascript">// 场景
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 代码,用于缓存资源和实现离线功能。

javascript">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仓库查看源代码。


http://www.ppmy.cn/server/171153.html

相关文章

Vue 3 搭建前端模板并集成 Ant Design Vue(2025)

一、环境安装 截止2025.2.6 &#xff0c;官网发布的vue 3 稳定版本是 V 3.5.13 根据此时的官方文档要求&#xff0c;node 版本需要大于等于 V 18.3 于是使用 nvm 安装 v 20.18.0 二、创建项目 使用 Vue 官方推荐的脚手架 create-vue 快速创建 Vue3 的项目: 快速上手 | Vue.js…

每天五分钟深度学习pytorch:使用Inception模块搭建GoogLeNet模型

本文重点 前面我们学习了Incetption模块,它的作用类似于vgg块对于VGG网络模型一样,本文我们使用Inception搭建GoogLeNet网络,如果使用卷积层开始从头开始搭建GoogleNet,那么这样看起来会很不清晰,我们使用已经封装好的Inception来搭建GoogLeNet网络 关键点 关键点在于I…

蓝桥杯---数组里面的第k大的元素(leetcode第215题)题解

文章目录 1.题目重现2.案例说明3.思路介绍4.代码分析 1.题目重现 之前是对于数组排序&#xff0c;找出来这个数组里面的最大的或者是最小的元素&#xff0c;但是这个题目是找出来排序之后的这个数组里面的第k大的元素&#xff1b; 2.案例说明 我觉得这个题目上面的解释足够清…

Linux内核自定义协议族开发指南:理解net_device_ops、proto_ops与net_proto_family

在Linux内核中开发自定义协议族需要深入理解网络协议栈的分层模型。net_device_ops、proto_ops和net_proto_family是三个关键结构体,分别作用于不同的层次。本文将详细解析它们的作用、交互关系及实现方法,并提供一个完整的开发框架。 一、核心结构体的作用与层级关系 struct…

爬虫基础入门之爬取豆瓣电影Top250-Re正则的使用

网址:豆瓣电影 Top 250 本案例所需要的模块 requests (用于发送HTTP请求)re (用于字符串匹配和操作) 确定需要爬取的数据 &#xff1a; 电影的名称电影的年份电影的评分电影评论人数 一. 发送请求 模拟浏览器向服务器发送请求 准备工作 -分析页面: F12 or 右击点击检查 查看…

蓝桥杯训练 补题

P8605 [蓝桥杯 2013] 网络寻路 这个题之前写过&#xff0c;但是后面数据加强了&#xff0c;直接dfs是会超时的&#xff0c;这是就要用另外的解法了&#xff0c;题目要求只要三条边&#xff0c;那么就可以找中间的边&#xff0c;对于每组边&#xff0c;把他们作为中间边&#xf…

spring boot 连接FTP实现文件上传

spring boot 连接FTP实现文件上传 maven&#xff1a; <!--ftp--><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.8.0</version></dependency>接口示例&#xff1a; ApiO…

本地部署 DeepSeek-R1大模型详细教程(桌面客户端美观UI)

大家好&#xff01;今天我来分享一篇超级详细的教程&#xff0c;教你如何在本地部署 DeepSeek-R1 大模型&#xff0c;让你的电脑也能成为一个强大的 AI 工作站&#xff01;这篇文章会从零开始&#xff0c;手把手带你完成所有步骤&#xff0c;适合小白操作。废话不多说&#xff…