Jump to content
Search Community

draggable within a draggable

mallanaga test
Moderator Tag

Recommended Posts

I guess I should have been more descriptive, apologies, it was late. 

  1. move the draw area - the child element moves with it (at intentioned)
  2. grab just the card, and move it outside of the draw area, and let go. All good still.
  3. grab the card again and put it inside the draw area. 
  4. notice the card position itself what seems to be 2 times what the x and y positions of the .area element are. 

 

OHHHHHH. 0,0 is the correct position because it's nested. by setting x and y of the parent it is moving it twice in both directions. 

Link to comment
Share on other sites

btw, you guys are amazing, but you already know that. I refreshed the pen to zeros, and modified it slightly to more closely resemble my project's code. The zeros seem to be exposing something else.

 

When I drop the card into the area, I'm prepending it to the area, so that it's a proper child, or if it's not in an area, I prepend the element to the "table". This makes the card jump around quite a bit. I tried update() on the card element, but that didn't seem to do anything.

Link to comment
Share on other sites

Dude! Thank you. Resetting the position is where my head was going to, but you beat me to it. Also, TIL

 

Quote

forEach() : There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behaviour, the . forEach() method is the wrong tool, use a plain loop instead.

 

I owe you a beer... Hit me up if you're ever in San Francisco.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

So... I haven't actually seen this working yet, and I've spent more hours than I'd like to admit working on it. The client that's doing the moving seems to be working fine, but it's the other clients that I can't seem to stop from blipping. I can't post a snippet, since the pub/sub nature won't be reflected, but here's the code.

 

Starts on the draggable callback:

 

onDragEnd: function() {
  let dropArea = document.getElementById('table');
  const areas = document.querySelectorAll('.Area');

  for (let i = 0; i < areas.length; i++) {
    if (this.hitTest(areas[i], "51%")) {
      dropArea = areas[i];
      if (dropArea.dataset.role === 'player') {
        cardEvents.conceal({target: cardRef, roomCode: props.roomCode});
        cardEvents.reveal({target: cardRef, playerUuid: dropArea.id, roomCode: props.roomCode});
      }
      break;
    }
  };

  cardEvents.sendPosition({
    draggable: this,
    oldParent: cardRef.parentElement,
    dropArea: dropArea,
    roomCode: props.roomCode
  });
},
const sendPosition = ({ draggable, oldParent, dropArea, roomCode }) => {
  const data = {
    event: "positionCard",
    id: draggable.target.id,
    oldParentId: oldParent.id,
    dropAreaId: dropArea.id,
    x: draggable.x,
    y: draggable.y,
    r: Draggable.get(draggable.target.querySelector(".Card")).rotation,
  };
  api.publish({ data, roomCode });
};

 

This is now sent to the server, and broadcasted to the clients (including the client doing the action!)

 

eventSource.addEventListener("positionCard", (e) => {
  const message = JSON.parse(e.data);
  const target = document.getElementById(message.id);
  const oldParent = document.getElementById(message.oldParentId);
  const dropArea = document.getElementById(message.dropAreaId);

  const a = dropArea.getBoundingClientRect();
  const b = oldParent.getBoundingClientRect();

  cardAnimations.move({
    target,
    dropArea,
    position: {
      x: parseFloat(message.x) + (b.left - a.left),
      y: parseFloat(message.y) + (b.top - a.top),
      r: parseFloat(message.r)
    }
  });
});
const move = ({ target, dropArea, position }) => {
  dropArea.append(target);
  Draggable.get(target).update(true, true);

  let x, y, rotation;
  if(dropArea.id !== 'table') {
    x = `random(-10, 10, 1)`;
    y = `random(-10, 10, 1)`;
    rotation = `random(-20, 20, 1)_short`;
  } else {
    x = position.x || 0;
    y = position.y || 0;
    rotation = `${(position.r || 0)}_short`;
  }

  gsap.to(target, {x, y, duration: 0.3});
  gsap.to(target.querySelector('.Card'), {rotation, duration: 0.3});
};

Sorry if that seems like a lot... 

 

I feel like this has something to do with the fact that when I'm moving the card, its position is being updated locally (obviously). For the other clients, it feels like they should be moved to the coordinates on the table before being appended? I've tried moving Draggable.get(target).update(true, true) above the append, and below the gsap.to call. No change in behavior.

 

I'm sorry to keep bugging you folks. This feels so close...

Link to comment
Share on other sites

The video looks like it's zeroing out every time at the start. I'm guessing that's because you're creating a new card each time?

dropArea.append(target);

If you're going to create a new target each time then you need to set its initial position to the position of the previous card. So you'd need to pass in two sets of position values and use .fromTo(). 

 

If you can reuse the same (old) target then you could use a relative .to() tween like what you're using.

Link to comment
Share on other sites

Hey Zach! Does append create a new target? Or is the reference lost, rather? I thought append specifically didn't create a new object, but actually moved it within the tree?

 

Tried this, which seems to do what you're suggesting, but the behavior is the same.

 

const move = ({ target, dropArea, position }) => {
  const draggable = Draggable.get(target);
  const oldX = draggable.x;
  const oldY = draggable.y;

  dropArea.append(target);

  let x, y, rotation;
  if(dropArea.id !== 'table') {
    x = `random(-10, 10, 1)`;
    y = `random(-10, 10, 1)`;
    rotation = `random(-20, 20, 1)_short`;
  } else {
    x = position.x || 0;
    y = position.y || 0;
    rotation = `${(position.r || 0)}_short`;
  }

  gsap.fromTo(target, {x: oldX, y: oldY}, {x, y, duration: 0.3});
  gsap.to(target.querySelector('.Card'), {rotation, duration: 0.3});
  draggable.update(true, true);
};

 

Link to comment
Share on other sites

No jQuery here, just JS within React. The inline styles seem to be retained. It's quick, but chrome shows the numbers "scrolling", so to speak, and I don't see them resetting to zero.

 

The nesting has to do with dragging. The "draw" area in the video is draggable, and I need all the cards within it to move with it (without firing a drag event for all the cards within it).

Link to comment
Share on other sites

26 minutes ago, mallanaga said:

At this point it feels like gsap can't accommodate this type of animation?

I doubt it's a matter of GSAP not being able to accommodate. It's likely in regards to not properly calculating the values or something along those lines. Thus far I haven't seen anything to make it seem like it's a bug in GSAP. If you have evidence of that not being true please let us know :) 

Link to comment
Share on other sites

There's obviously some logic/calculation problems in your code because the card doesn't always snap to same position inside the draw box. It should behave like this.

 

See the Pen 94f3c5032960e8b95a527b70cfd22afa by osublake (@osublake) on CodePen

 

 

The easiest thing to do is to make sure everything is absolutely positioned at 0, 0. Stuff like border width can also throw off getBoundingClientRect. If you need a border, then do it in another layer.

 

  • Like 2
Link to comment
Share on other sites

Oh, well the border is still a slight 2px problem.

 

I don't have time to go through all your code right now, but I think you have a problem somewhere. Like why is every scene being looped through, and why is append being called every time?

 

 

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...