简体   繁体   中英

Adding Links into a P5.js ball physics simulation

I built an environment on p5.js, where basically a class of Balls is instanced to have them subjected to gravity and potentially dragged and thrown around.

I want to replace them with links instead.

I'm a bit confused about my next steps.

I managed to make this code:

 let numBalls = 13; let spring = 0.05; let gravity = 0.05; let friction = -0.9; let balls = []; let menuData; function setup() { createCanvas(400, 400); for (let i = 0; i < numBalls; i++) { balls[i] = new Ball( random(width), random(height), random(30, 40), i, balls ); } noStroke(); fill(255, 204); balls.forEach(ball => { ball.display(); }) } function draw() { background(0); balls.forEach(ball => { ball.collide(); ball.move(); ball.display(); }); } function mousePressed() { balls.forEach(ball => { if (ball.onBall(mouseX, mouseY)) ball.startDrag(); }); } function mouseDragged() { balls.forEach(ball => { if (ball.dragging) { ball.x = mouseX; ball.y = mouseY; } }); } function mouseReleased() { balls.forEach(ball => { if (ball.dragging) { // Calculate the ball's new velocity based on how fast the mouse was moving when it was released ball.vx = (mouseX - ball.mousex) / 10; ball.vy = (mouseY - ball.mousey) / 10; // Set the ball's dragging property to false to indicate that it is no longer being dragged ball.dragging = false; } }); } class Ball { constructor(xin, yin, din, idin, oin) { this.x = xin; this.y = yin; this.vx = 0; this.vy = 0; this.diameter = din; this.id = idin; // questo non c'è bisogno per la fisica this.others = oin; this.dragging = false; } onBall(x, y) { let dx = x - this.x; let dy = y - this.y; let dist = Math.sqrt(dx * dx + dy * dy); return dist <= this.diameter / 2; } startDrag() { this.dragging = true; this.mousex = mouseX; this.mousey = mouseY; } collide() { for (let i = this.id + 1; i < numBalls; i++) { // Calculate distance and minimum distance between balls let dx = this.others[i].x - this.x; let dy = this.others[i].y - this.y; let distance = sqrt(dx * dx + dy * dy); let minDist = this.others[i].diameter / 2 + this.diameter / 2; // Check if balls are colliding if (distance < minDist) { // Calculate angle between balls let angle = atan2(dy, dx); // Calculate target position for balls to avoid overlap let targetX = this.x + cos(angle) * minDist; let targetY = this.y + sin(angle) * minDist; // Calculate force of collision using mass and elasticity let ax = (targetX - this.others[i].x) * spring; let ay = (targetY - this.others[i].y) * spring; this.vx -= ax; this.vy -= ay; this.others[i].vx += ax; this.others[i].vy += ay; } } } move() { if (this.dragging) { this.x = mouseX; this.y = mouseY; } else { // gravità this.vy += gravity; // update ball's position based on its velocity this.x += this.vx; this.y += this.vy; if (this.x + this.diameter / 2 > width) { this.x = width - this.diameter / 2; this.vx *= friction; } else if (this.x - this.diameter / 2 < 0) { this.x = this.diameter / 2; this.vx *= friction; } if (this.y + this.diameter / 2 > height) { this.y = height - this.diameter / 2; this.vy *= friction; } else if (this.y - this.diameter / 2 < 0) { this.y = this.diameter / 2; this.vy *= friction; } } } display() { ellipse(this.x, this.y, this.diameter, this.diameter); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

Now I want to replace those ellipses and have some HTML anchors instead in order to have a bunch of links bouncing around. What I mean by that is that now the object created is the ellipse, and I used that as a "placeholder" while I was building the rest of the code. My final aim is to have instead links created, I was thinking using creatA instead of ellipse could work, but apparently, it doesn't. here's the codepen for that: https://codepen.io/giambrodo/pen/poZeOgO

the issue in the codepen is that they are clearly getting created (the links) in a different way than the ellipses i don't get why and how tho. Within my project, that is bigger and presents actually multiple sketches (i use the instance p5.js method there) somehow the links are produced inside the first sketch, but that's another story i guess.

let as = createA('www.moodnothing.baby', 'baby');
as.position(this.x, this.y);

I also thought that I could just make the anchor outside, in the setup function, and modify the class within the display() method, using the class() function, but I'm not getting any results either.

Codepen if you need it:

https://codepen.io/giambrodo/pen/LYBxMZZ

Maybe try adding HTML elements for every ball you add:

var linkElement = document.createElement("a");

linkElement.innerHTML = menuData.links[i].label;
linkElement.className = "link-element";
linkElement.id = "link-element";
linkElement.href = menuData.links[i].href;

document.body.appendChild(linkElement);

Then you can set the CSS of the link-elements. You'll want position: absolute so that they will overlay with the canvas.

#link-element {
  position: absolute;
  top:  0;
  left: 0;
}

Then to move the links around you can get each one and set its position equal to the balls:

const links = document.getElementsById("link-element");
for (let i = 0; i < links.length; i++) {
  links[i].style.left = this.x;
  links[i].style.top = this.y;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM