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