webgl_animation_waves
文件夹里,有不同波形(正弦波、余弦波)的实现方式,连如何让波浪和鼠标位置互动都写好了注释。index.html
(网页骨架)、script.js
(写动画代码)、package.json
(管理依赖)。npm init -y
生成 package.json
,再输入 npm install three
安装 Three.js 库。index.html
里,引入 Three.js 文件:
,然后把 script.js
也引入:
。// 创建场景,相当于舞台
const scene = new THREE.Scene();
// 创建透视相机,就像观众的眼睛位置
const camera = new THREE.PerspectiveCamera(, window.innerWidth / window.innerHeight, 0.1, );
// 创建渲染器,把内容画到网页上
const renderer = new THREE.WebGLRenderer();
// 设置渲染器尺寸,填满整个窗口
renderer.setSize(window.innerWidth, window.innerHeight);
// 把渲染器的 DOM 元素加到网页 body 里
document.body.appendChild(renderer.domElement);
PlaneGeometry
就行,但得把分段数调高点,不然波浪看起来太生硬:// 创建平面几何,宽度和高度设为 100,宽度分段和高度分段都设为 100,这样顶点足够多
const geometry = new THREE.PlaneGeometry(, , , );
// 材质用 MeshPhongMaterial,能有光影效果,颜色设为浅蓝色
const material = new THREE.MeshPhongMaterial({ color: 0x87ceeb });
// 创建网格对象,把几何和材质绑在一起
const waveMesh = new THREE.Mesh(geometry, material);
// 把网格添加到场景里
scene.add(waveMesh);
// 在动画循环里更新顶点
function animate() {
requestAnimationFrame(animate);
// 遍历每个顶点
for (let i = ; i < geometry.vertices.length; i++) {
const vertex = geometry.vertices[i];
// X 和 Z 坐标决定波浪的位置,用时间戳让波浪移动
const x = vertex.x;
const z = vertex.z;
// 波浪的高度随时间和位置变化,振幅设为 5,频率设为 0.1
vertex.y = Math.sin(x * 0.1 + Date.now() * 0.005) * + Math.sin(z * 0.1 + Date.now() * 0.005) * ;
}
// 更新几何的顶点数据,不然变化不生效
geometry.verticesNeedUpdate = true;
// 渲染场景和相机
renderer.render(scene, camera);
}
// 启动动画
animate();
water_normal.jpg
(法线纹理,让波浪有凹凸感),用 TextureLoader
加载:const textureLoader = new THREE.TextureLoader();
const waterNormal = textureLoader.load('water_normal.jpg');
// 把法线纹理应用到材质上
material.normalMap = waterNormal;
// 环境光,让整个场景有基础亮度
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
// 点光源,模拟阳光,位置放在波浪上方
const pointLight = new THREE.PointLight(0xffffff, );
pointLight.position.set(, , );
scene.add(pointLight);
// 监听鼠标移动
let mouseX = , mouseY = ;
window.addEventListener('mousemove', (e) => {
mouseX = (e.clientX - window.innerWidth / ) / ;
mouseY = (e.clientY - window.innerHeight / ) / ;
});
// 在动画循环里,根据鼠标位置添加额外的波浪扰动
for (let i = ; i < geometry.vertices.length; i++) {
const vertex = geometry.vertices[i];
// 原来的波浪计算
const baseY = Math.sin(x * 0.1 + time) * + Math.sin(z * 0.1 + time) * ;
// 鼠标位置对应的扰动,距离越近振幅越大
const distance = Math.sqrt((x - mouseX * ) ** + (z - mouseY * ) ** );
const disturbY = ( / distance) * ; // 距离越近,扰动越大
vertex.y = baseY + disturbY;
}
AudioContext
读取音乐文件的频率数据:const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const audioElement = new Audio('music.mp3');
const source = audioContext.createMediaElementSource(audioElement);
const analyser = audioContext.createAnalyser();
source.connect(analyser);
analyser.connect(audioContext.destination);
const frequencyData = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(frequencyData);
const lowFrequency = frequencyData.slice(, ).reduce((a, b) => a + b, ) / ;
vertex.y = Math.sin(x * 0.1 + time) * (lowFrequency / * ) + Math.sin(z * 0.1 + time) * (lowFrequency / * );
// 用 MeshBasicMaterial 开启发光效果
const glowMaterial = new THREE.MeshBasicMaterial({
color: 0x00ffff,
emissive: 0x00ffff,
emissiveIntensity: ,
transparent: true,
opacity: 0.8
});
// 给波浪顶点设置不同的颜色,根据 Y 轴高度渐变
for (let i = ; i < geometry.vertices.length; i++) {
const y = geometry.vertices[i].y;
const color = new THREE.Color();
color.setHSL((y + ) / , , 0.5); // 色相随高度变化
geometry.colors[i] = color;
}
glowMaterial.vertexColors = THREE.VertexColors; // 应用顶点颜色
let alpha = , beta = ;
window.addEventListener('deviceorientation', (e) => {
alpha = e.alpha; // 绕 Z 轴旋转角度
beta = e.beta; // 绕 X 轴旋转角度
});
// 在动画循环里,根据倾斜角度调整相机位置,让波浪看起来像在流动
camera.position.x = Math.sin(alpha * 0.01) * ;
camera.position.z = Math.cos(beta * 0.01) * ;
antialias: true
,波浪边缘不会有锯齿,但会稍微影响性能,根据设备性能取舍。{ powerPreference: "high-performance", antialias: true, webgl2: true }
。? 建站速度:从 “等 weeks” 到 “按 days 算” 的颠覆 咱先说说最直观的感受 —— 建站速度。传统建站那流程,跟老辈人做手工似的,得一步步磨。你得先跟设计师碰需求,光沟通品牌调性、页面
? 神赞营销工具:社交媒体管理的核心引擎 社交媒体时代,品牌想要突出重围,就得把社交媒体玩得溜。神赞营销工具在这方面可真是把好手。它能在微信、小红书、抖音、微博这些主流平台上,帮品牌搞全域种草推广,从
?速猫 ERP 如何对接亚马逊?30 + 平台物流跟踪与财税合规指南 做跨境电商的朋友都知道,ERP 系统是管理多平台业务的关键工具。今天咱们就来聊聊速猫 ERP 怎么对接亚马逊,以及如何通过它实现
? 2025 新版 B 站 C4D 教程:从入门到进阶的系统课程,材质灯光渲染实战解析 B 站的 C4D 教程一直是设计爱好者的热门选择,2025 年的新版更是带来了全新的学习体验。今天咱们就来深入聊
?双机位布置:打造360°无死角面试环境力扣模拟面试的双机位要求让不少同学犯难,其实把它想象成给电脑装个「监控搭档」就简单了。主机位就是咱们平时用的电脑摄像头,记得调整到能露出整张脸和桌面的角度——下巴别藏在阴影里,键盘也别只露出半个。副机位一般用手机支架固定,放在身体侧后方45度角,这个位置既能拍
?精准提分黑科技!ExamifyAI如何重塑2025考试备考模式?一、核心功能大揭秘:AI如何让考试准备更高效?ExamifyAI作为新一代智能考试平台,最吸引人的地方就是它的自适应学习引擎。这个系统就像一个贴心的私人教练,能根据你的答题数据自动调整学习路径。比如你在数学几何题上错误率高,系统会优先
你可能觉得公众号注册就是填几个信息的事,殊不知,这里面的每个选择都像蝴蝶扇动翅膀,未来三年的运营轨迹可能就被悄悄改变了。很多人刚开始没当回事,等到后面想调整,才发现处处受限,那叫一个后悔。今天就跟你好好聊聊,注册时那些看似不起眼的选择,到底能给未来的运营带来多大影响。📌账号类型选不对,三年运营路难
上周帮同事核查一篇AI写的行业报告,发现里面把2023年的用户增长率写成了2025年的预测数据。更离谱的是,引用的政策文件号都是错的。现在AI生成内容速度快是快,但这种硬伤要是直接发出去,读者信了才真叫坑人。今天就掰开揉碎了说,AI写作怎么做好事实核查,别让你的头条文章变成 误导重灾区 。📌AI写
🎯维度一:选题像打靶,靶心必须是「用户情绪储蓄罐」做内容的都清楚,10w+爆文的第一步不是写,是选。选题选不对,后面写得再好都是白搭。高手选选题,就像往用户的「情绪储蓄罐」里投硬币,投对了立刻就能听到回响。怎么判断选题有没有击中情绪?看三个指标:是不是高频讨论的「街头话题」?是不是藏在心里没说的「抽
📌135编辑器会员值不值得买?AI模板库和秀米H5谁更胜一筹?🔍135编辑器会员的核心价值解析企业级商用保障与效率提升135编辑器的企业会员堪称新媒体运营的「合规保险箱」。根据实际案例,某团队通过企业会员节省了大量设计费用,完成多篇内容创作,单篇成本从千元降至百元内。这得益于其海量正版模板和素材库,
新公众号被限流怎么办?粉丝增长影响分析及2025恢复指南🔍新公众号限流的核心原因解析新公众号被限流,往往是多个因素叠加的结果。根据2025年最新数据,超过70%的限流案例与内容质量直接相关。比如,有些新手喜欢用“震惊体”标题,像“惊!某公众号三天涨粉十万”,这类标题在2025年的算法里已经被明确标记
⚠️AI内容重复率高的3大核心原因现在用AI写东西的人越来越多,但很多人都会遇到同一个问题——重复率太高。明明是自己用工具生成的内容,一检测却显示和网上某些文章高度相似,这到底是为什么?最主要的原因是AI训练数据的重叠性。不管是ChatGPT还是国内的大模型,训练数据来源其实大同小异,都是爬取的互联
🌟135编辑器:公众号运营者的效率革命做公众号运营的朋友都知道,排版是个费时费力的活。一篇文章从内容到排版,没几个小时根本搞不定。不过现在好了,135编辑器的出现,彻底改变了这一现状。135编辑器是提子科技旗下的在线图文排版工具,2014年上线至今,已经成为国内新媒体运营的主流工具之一。它的功能非常
现在做内容的人几乎都离不开AI,但最头疼的就是原创度。平台检测一严格,那些模板化的AI文很容易被打回,甚至判定为“非原创”。但你知道吗?同样是用AI写东西,换个prompt指令词,原创度能差出天壤之别。我最近拿不同的prompt测了好几次,结果真的吓一跳——好的指令能让AI内容原创度直接从“及格线”