Wie kann ich ein gezogenes Element loslassen, wenn die Maus über den Begrenzungsrahmen hinausgeht? [geschlossen]JavaScript

Javascript-Forum
Anonymous
 Wie kann ich ein gezogenes Element loslassen, wenn die Maus über den Begrenzungsrahmen hinausgeht? [geschlossen]

Post by Anonymous »

Ich habe eine Codesandbox erstellt, um mein Problem zu veranschaulichen: https://codesandbox.io/p/sandbox/hvmg69
bubbles.tsx

Code: Select all

import {
Bodies,
Body,
Bounds,
Composite,
Engine,
Events,
Mouse,
MouseConstraint,
Render,
Runner,
} from "matter-js";
import { useEffect, useRef } from "react";

const Bubbles = () => {
const boxRef = useRef(null);
const engine = useRef(Engine.create());
const ballPositions = useRef(
new Map()
);
const ballColors = useRef(new Map());

useEffect(() => {
if (!boxRef.current) return;

// Clear any existing canvas to avoid duplicates
const existingCanvas = boxRef.current.querySelector("canvas");
if (existingCanvas) {
existingCanvas.remove();
}

const engineRef = engine.current;
const world = engineRef.world;

const width = boxRef.current.clientWidth;
const height = boxRef.current.clientHeight;

// Create bounds vertices that match the wall coordinates
const boundsVertices = [
{ x: 0, y: 0 }, // Top-left corner
{ x: width, y: 0 }, // Top-right corner
{ x: width, y: height }, // Bottom-right corner
{ x: 0, y: height }, // Bottom-left corner
];

const bounds = Bounds.create(boundsVertices);

const render = Render.create({
element: boxRef.current,
engine: engineRef,
bounds,
options: {
width: boxRef.current.clientWidth,
height: boxRef.current.clientHeight,
wireframes: false,
background: "transparent",
hasBounds: true,
},
});

// Create a mapping between ball index and bubble state ID
const ballToBubbleId = new Map();

let balls = [];

for (let i = 0; i < 2;  i++) {
// Use stored position if available, otherwise random
const xPos = Math.random() * (width - 100) + 50;
const yPos = Math.random() * (height - 100) + 50;

const color = "red";

const body = Bodies.circle(xPos, yPos, 50, {
frictionAir: 0,
friction: 0,
restitution: 1,
force: { x: 0.1, y: 0.1 },
render: {
fillStyle: color,
opacity: 0.5,
},
collisionFilter: {
group: -1,
},
label: `bubble-${i}`,
});
balls.push(body);
}

// Create walls around the screen - positioned outside the visible area
const walls = [
// Top wall - positioned above the container
Bodies.rectangle(width / 2, -512, width, 1024, {
isStatic: true,
restitution: 1,
collisionFilter: { category: 0x0001, mask: 0x0001 },
}),
// Bottom wall - positioned below the container
Bodies.rectangle(width / 2, height + 512, width, 1024, {
isStatic: true,
restitution: 1,
collisionFilter: { category: 0x0001, mask: 0x0001 },
}),
// Left wall - positioned to the left of the container
Bodies.rectangle(-512, height / 2, 1024, height, {
isStatic: true,
restitution: 1,
collisionFilter: { category: 0x0001, mask: 0x0001 },
}),
// Right wall - positioned to the right of the container
Bodies.rectangle(width + 512, height / 2, 1024, height, {
isStatic: true,
restitution: 1,
collisionFilter: { category: 0x0001, mask: 0x0001 },
}),
];
Composite.add(world, [...walls, ...balls]);

// Create mouse constraint for dragging
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engineRef, {
mouse: mouse,
constraint: {
stiffness: 0.2, // Lower stiffness for more controlled dragging
render: {
visible: false,
},
},
collisionFilter: {
group: 1,
},
});

Composite.add(world, mouseConstraint);

// Keep the mouse in sync with rendering
render.mouse = mouse;
let selectedBubbleIndex: number | null = null;

// Add mouseUp event listener to check for ball overlaps
Events.on(mouseConstraint, "mousedown", ({ source }) => {
const body = source.body;

if (body) {
// Find the index of the selected bubble
selectedBubbleIndex = balls.findIndex((b) => b.id === body.id);
}
});

Events.on(mouseConstraint, "mousemove", ({ source }) => {
const body = source.body;
if (body) {
const { y } = body.position;

console.log(y);
console.log(source.constraint.bodyB);
if (y  {
Render.stop(render);
Runner.stop(runner);
Composite.clear(world, false);
Engine.clear(engineRef);
render.canvas.remove();
};
}, []); // Only depend on bubbles, not refs

return (
style={{
backgroundColor: "blue",
width: "100%",
height: "500px",
overflow: "hidden",
}}
ref={boxRef}
>
);
};

export default Bubbles;
Wenn ich einen Ball aus dem blauen Rahmen ziehe, beginnt er sich schnell zu drehen, und wenn ich die Maustaste loslasse, während ich mich außerhalb des Begrenzungsrahmens befinde, wird das Element weiter gezogen. Ich möchte den Ball loslassen, wenn die Maus den Begrenzungsrahmen berührt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post