Files
RGKT/rg-09112127/js/physics.js
2025-10-10 19:35:04 +08:00

83 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
});