document.addEventListener('DOMContentLoaded', function() { // Matter.js 模块别名 var Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite; // 创建一个引擎 var engine = Engine.create(); // 创建一个运行器 var runner = Runner.create(); // 创建一个世界 var world = engine.world; // 设置重力 engine.world.gravity.y = 1; // 标准重力 // 运行引擎 Runner.run(runner, engine); // 函数:获取元素相对于视口的位置和尺寸 function getElementBounds(element) { const rect = element.getBoundingClientRect(); return { x: rect.left + rect.width / 2, // 元素中心点的x坐标 y: rect.top + rect.height / 2, // 元素中心点的y坐标 top: rect.top, // 元素顶边位置 left: rect.left, // 元素左边位置 width: rect.width, // 元素宽度 height: rect.height // 元素高度 }; } // 获取物理效果元素和模块元素 const physicsBallEl = document.querySelector('.physics-ball'); // 选择球元素 const physicsRectEl = document.querySelector('.physics-rect'); // 选择矩形元素 const physicsBadgeEl = document.querySelector('.physics-badge'); // 选择徽章元素 const homeModules = document.querySelectorAll('.home-module'); // 选择所有模块元素 // 数组:用于保存物理物体和它们对应的HTML元素 const physicsElements = []; // 为下落的物体创建物理物体 [physicsBallEl, physicsRectEl, physicsBadgeEl].forEach(el => { if (el) { const bounds = getElementBounds(el); // 将物理物体定位在初始渲染位置上方一点 const body = Bodies.rectangle(bounds.x, bounds.top - 100, bounds.width, bounds.height, { restitution: 0.6, friction: 0.1 }); Composite.add(world, body); physicsElements.push({ body: body, el: el }); el.style.visibility = 'hidden'; // 隐藏原始元素 el.style.position = 'absolute'; // 准备绝对定位 } }); // 为模块创建静态物理物体(着陆表面) homeModules.forEach(moduleEl => { const bounds = getElementBounds(moduleEl); const groundHeight =700; // 显著增加厚度 const groundY = bounds.top + groundHeight - 700; // 定位中心,使顶部边缘在 bounds.top + 10 处 const ground = Bodies.rectangle(bounds.x, groundY, bounds.width, groundHeight, { isStatic: true, friction: 0.8 }); Composite.add(world, ground); }); // 更新HTML元素位置以匹配物理物体 function updateElements() { physicsElements.forEach(({ body, el }) => { // 根据物理物体的位置设置元素的位置 el.style.left = `${body.position.x - el.offsetWidth / 2}px`; el.style.top = `${body.position.y - el.offsetHeight / 2}px`; el.style.transform = `rotate(${body.angle}rad)`; el.style.visibility = 'visible'; // 物理定位后使可见 }); requestAnimationFrame(updateElements); } // 开始更新元素位置 updateElements(); });