Option for snap and restrict to be relative to the element's position and dimentions #72

Merged
merged 7 commits into from Sep 4, 2014

Projects

None yet

2 participants

@taye
Owner
taye commented Sep 3, 2014

Snap elementOrigin

interact('*').snap({
  elementOrigin: { x: 0, y: 0 }
});

elementOrigin.x/y are scalars specifying the position on the element to
which snapping should be relative.

{x:   0, y:   0}  is the top left
{x: 0.5, y: 0.5}  is the center
{x:   1, y:   1}  is the bottom right

Restrict elementRect

interact('*').restrict({
  elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
});

For the left and right properties, 0 means the very left of the element
and 1 means the very right. For top and bottom, 0 means the top of the
element and 1 means the bottom.

{ top: 0.25, left: 0.25, bottom: 0.75, right: 0.75 } would result in a
quarter of the element being allowed to hang over the restriction edges.

Closes #47
Closes #59

added some commits Sep 2, 2014
@taye Add snap elementOrign and restrict elementRect
interact('*').snap({
  elementOrigin: { x: 0, y: 0 }
});

elementOrigin.x/y are scalars specifying the position on the element to
which snapping should be relative.

{x:   0, y:   0} is the top left
{x: 0.5, y: 0.5} is the center
{x:   1, y:   1} is the bottom right

interact('*').restrict({
  elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
});

For the left and right properties, 0 means the very left of the element
and 1 means the very right. For top and bottom, 0 means the top of the
element and 1 means the bottom.

{ top: 0.25, left: 0.25, bottom: 0.75, right: 0.75 } would result in a
quarter of the element being allowed to hang over the restriction edges.
fdcb913
@taye Fix bugs in restrict methods 7ca2ad4
@taye
Owner
taye commented Sep 3, 2014

CC @jordandh (#32) @dexusnl (#47) @robertCSN (#59)

Implementing this was tricky and I expect that there are a few bugs. Any help with testing would be fantastic.

If this fix is good then you should be able to remove the workarounds that I suggested for snapping and restricting and use your original settings with the addition of elementOrigin: { x: 0, y: 0 } for snap and elementRect: { top: 0, left: 0, bottom: 1, right: 1 } for restrict.

http://rawgit.com/taye/interact.js/snap-restrict-element-rect/interact.js

Cheers

@jordandh
jordandh commented Sep 3, 2014

@taye I'm trying this branch out but I am having trouble with the settings. I am not really sure how to use them for my slideshow example. Can you explain the settings further or help me nail them down? For say a 3 slide slideshow?

@taye
Owner
taye commented Sep 3, 2014

I tried using your demo at http://codepen.io/jordandh/pen/xlhgG and the snapping seems to work if I remove the code in dragstart that recalculates the snap anchors and instead use normal anchors for snapping.

     .snap({
         mode: 'anchor',
         anchors: [
             { x: -slideWidth * 2, y: 0 },
             { x: -slideWidth, y: 0 },
             { x: 0, y: 0 }
         ],
        elementOrigin: {x: 0, y: 0},
         endOnly: true
     })
    .on('dragstart', function (event) {
      var $target = $(event.target);

      $target.removeClass('slotting');
      $target.closest('.slideshow').find('.slideshow-image').removeClass('slotting');
    })
@jordandh
jordandh commented Sep 3, 2014

I updated my demo to use the changes. It works when the body has zero padding but if you give the body padding (40px in the codepen example) then the snap points appear to be off by 40px. I tried changing the elementOrigin to { x: 40, y: 40 } but it went kinda haywire with that.

You can view the problem with 40px body padding here: http://codepen.io/jordandh/pen/sFDmo

@taye
Owner
taye commented Sep 3, 2014

The x and y values of the elementOrigin are multiplied by the width and height of the element and added to the offset - snapOffset.x = startOffset.left + (rect.width * snap.elementOrigin.x);

{ x: 40, y: 40 } would make mean that snapping is relative to the point at the element's (top, left) plus 40 times the (width, height).

You can instead change the interactable's origin to account for the padding.

.origin({ x: 40, y: 40 }), and .origin('parent') both work in your case.

@jordandh
jordandh commented Sep 3, 2014

Setting the origin totally fixed the problem. The snapping is working well in OSX Chrome but it is not very accurate on iOS. It is evident in the same codepen http://codepen.io/jordandh/pen/sFDmo. If you swipe over to slide 1 and keep swiping in that direction it snaps back to the incorrect coordinate most of the time.

It also does not have a smooth end transition like in pull request #69 but I assume you are going to merge these branches if both prove fruitful.

@taye
Owner
taye commented Sep 3, 2014

Setting the origin totally fixed the problem. The snapping is working well in OSX Chrome but it is not very accurate on iOS. It is evident in the same codepen http://codepen.io/jordandh/pen/sFDmo. If you swipe over to slide 1 and keep swiping in that direction it snaps back to the incorrect coordinate most of the time.

The problem might be the zeroResumeDelta + snapping issue #41. I'm working on a fix for it - #50.

It also does not have a smooth end transition like in pull request #69 but I assume you are going to merge these branches if both prove fruitful.

Yep. But here's what it would look like if I merged all the pending fixes now: http://taye.me/etc/int-merged.js

@jordandh
jordandh commented Sep 3, 2014

Well with those issues being fixed in other branches I would say that the changes in this branch work for my use case.

@taye
Owner
taye commented Sep 3, 2014

Excellent. Thanks for your help!

@taye taye merged commit e7196c9 into master Sep 4, 2014
@taye taye added a commit that referenced this pull request Sep 4, 2014
@taye Add docs for snap/restrict element{Origin,Rect}
Links to #72
872577c
@taye taye deleted the snap-restrict-element-rect branch Sep 8, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment