<div class="shapes"></div>
HTML
格式化
支持Emmet,输入 p 后按 Tab键试试吧!
<head> <script src="https://cdn... </head>
<body>
</body>
.shapes {
width:100vw;
height: 100vh;
}
body {
background: #e572b0;
margin: 0;
}
// 从Matter.js引入需要的模块
const { Engine, Events, Body, Render, Bodies, World, MouseConstraint, Composites, Query, Common, Mouse } = Matter
// 获取DOM容器元素
var sectionTag = document.querySelector(".shapes");
// 设置画布宽高
let w = sectionTag.offsetWidth;
let h = sectionTag.offsetHeight;
// 创建物理引擎实例
const engine = Engine.create();
// 设置重力参数
engine.world.gravity.x = 0 // X轴重力为0
engine.world.gravity.y = 0.001 // Y轴微弱重力
engine.world.gravity.scale = 0.1 // 重力比例缩小
// 创建渲染器
var renderer = Render.create({
element: sectionTag,
engine: engine,
options: {
width: w,
height: h,
background: "transparent", // 透明背景
wireframes: false, // 关闭线框模式
pixelRatio: window.devicePixelRatio // 适配设备像素比
}
});
// 设置墙壁属性
const wallOptions = {
isStatic: true, // 静态物体
render: {
visible: true,
fillStyle: "#e572b0", // 墙壁颜色
},
friction: 0, // 无摩擦力
restitution: 1.1, // 弹性系数(大于1表示会增加能量)
}
// 创建四面墙壁
const ceiling = Bodies.rectangle(w / 2, -1, w, 50, wallOptions) // 天花板
const ground = Bodies.rectangle(w / 2, h+50, w, 50, wallOptions) // 地面
const leftWall = Bodies.rectangle(-50, h / 2, 50, h, wallOptions) // 左墙
const rightWall = Bodies.rectangle(w+50, h / 2, 50, h, wallOptions) // 右墙
// 添加鼠标控制
const mouseControl = MouseConstraint.create(engine, {
element: sectionTag,
constraint: {
render: {
visible: false // 隐藏鼠标约束显示
}
}
})
// 将墙壁和鼠标控制添加到世界
World.add(engine.world, [
ground,
ceiling,
leftWall,
rightWall,
mouseControl,
]);
// 设置小球颜色
var color = "#9bc459";
// 计算小球数量
var peasize = 1225; // 35*35,给最大小球留出空间
var width = window.innerWidth;
var height = window.innerHeight;
var area = width * height;
var areatocover = area * 0.85; // 覆盖85%的屏幕面积
var numberofpeas = areatocover / peasize;
// 在随机位置添加小球
for (let i = 0; i < numberofpeas; i++) {
var radius = gsap.utils.random(10, 25); // 随机半径
var radius2 = (radius * 2.5);
var posx = gsap.utils.random(radius2, w - radius2, radius2, true); // 随机X坐标
var posy = gsap.utils.random(radius2, h - radius2, radius2, true); // 随机Y坐标
var scaleFactor = radius * -0.013; // 计算图片缩放比例
// 创建圆形物体
World.add(engine.world, Bodies.circle(
posx(),
posy(),
radius,
{
frictionAir: 0, // 空气阻力为0
frictionStatic: 0, // 静摩擦力为0
friction: 0, // 动摩擦力为0
restitution: 1.01, // 弹性系数略大于1
mass: 1, // 质量为1
slop: 0, // 无重叠容差
render: {
fillStyle: color,
sprite: {
texture: "https://assets.codepen.io/588944/pea3.svg", // 小球贴图
xScale: scaleFactor,
yScale: scaleFactor
}
}
}
))
}
// 运行物理引擎和渲染器
Matter.Runner.run(engine);
Matter.Render.run(renderer);
// 监听窗口调整大小事件
window.addEventListener('resize', () => {
// 更新渲染器尺寸
renderer.bounds.max.x = sectionTag.clientWidth;
renderer.bounds.max.y = sectionTag.clientHeight;
renderer.options.width = sectionTag.clientWidth;
renderer.options.height = sectionTag.clientHeight;
renderer.canvas.width = sectionTag.clientWidth;
renderer.canvas.height = sectionTag.clientHeight;
Matter.Render.setPixelRatio(renderer, window.devicePixelRatio);
// 更新地面和右墙的位置
Matter.Body.setPosition(
ground,
Matter.Vector.create(
sectionTag.clientWidth / 2,
sectionTag.clientHeight + 50 / 2
)
);
Matter.Body.setPosition(
rightWall,
Matter.Vector.create(
sectionTag.clientWidth + 50 / 2,
sectionTag.clientHeight / 2
)
);
});