let matterFlag = true; // set true if you want animation to run function initMatter() { if (!matterFlag) return; const matterContainer = document.getElementById("brand-drop-box"); if (!matterContainer) return; // module aliases const { Engine, Render, Runner, Bodies, Composite } = Matter; let size = { w: matterContainer.clientWidth, h: matterContainer.clientHeight, offset: 100 }; // create an engine let engine = Engine.create(); engine.world.gravity.y = 0.4; // reduced gravity (default 1) // create a renderer let render = Render.create({ element: matterContainer, engine: engine, options: { width: size.w, height: size.h, background: "transparent", wireframes: false, showAngleIndicator: false, pixelRatio: window.devicePixelRatio } }); createshapes(); // walls let ground = Bodies.rectangle(size.w / 2, size.h + size.offset / 2 - 1, 50000, size.offset, { isStatic: true, label: "wall", render: { opacity: 0 } }); let leftWall = Bodies.rectangle(0 - size.offset / 2, size.h / 2, size.offset, size.h * 5, { isStatic: true, label: "wall", render: { opacity: 0 } }); let rightWall = Bodies.rectangle(size.w + size.offset / 2, size.h / 2, size.offset, size.h * 5, { isStatic: true, label: "wall", render: { opacity: 0 } }); Composite.add(engine.world, [ground, leftWall, rightWall]); Render.run(render); let runner = Runner.create(); Runner.run(runner, engine); function createshapes() { const cr_paths = matterContainer.querySelectorAll(".brand-circle-img"); if (cr_paths.length) { cr_paths.forEach((e) => { let circleDiameter = size.w * (window.innerWidth < 767 ? 0.18 : 0.15); let scaleSize = circleDiameter / e.width; let scale = Math.min(scaleSize, scaleSize); // Random X spawn position (so they don’t overlap at start) let randomX = gsap.utils.random(circleDiameter, size.w - circleDiameter); // Create circle body with tuned physics let circle = Bodies.circle(randomX, 0, circleDiameter / 2, { friction: 0.10, // more surface friction frictionAir: 0.0001, // stronger air drag → slower fall restitution: 0.8, // less bounce label: "circle", render: { fillStyle: "transparent", sprite: { imgSize: e.width, texture: e.src, xScale: scale, yScale: scale } } }); Composite.add(engine.world, circle); }); } } } // Wait for all images to load, then run MatterJS function loadImagesAndRun() { const images = document.querySelectorAll(".brand-circle-img"); let loadedCount = 0; images.forEach(img => { if (img.complete) { loadedCount++; if (loadedCount === images.length) initMatter(); } else { img.addEventListener("load", () => { loadedCount++; if (loadedCount === images.length) initMatter(); }); img.addEventListener("error", () => { loadedCount++; if (loadedCount === images.length) initMatter(); }); } }); } window.addEventListener("load", loadImagesAndRun);