83 lines
3.2 KiB
JavaScript
83 lines
3.2 KiB
JavaScript
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();
|
||
});
|