Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is snap relative to ? #1

Closed
jide opened this issue Feb 3, 2014 · 10 comments
Closed

What is snap relative to ? #1

jide opened this issue Feb 3, 2014 · 10 comments

Comments

@jide
Copy link

jide commented Feb 3, 2014

I do not understand to what element snap coordinates are relative.

There are 2 ways to define snap : By directly setting interact.snap or interact(element).snap. Does the first one sets a global snap, whereas the second one sets the snap for the element ? (I guess so).

When setting a snap, we can set "x" and "y" coordinates for each point, but are these coordinates relative to the document ? To the first positioned parent from the element ? To the element itself ?

Thanks for your help, interact.js is a really good work, doing just what it should.

@taye
Copy link
Owner

taye commented Feb 3, 2014

Does the first one sets a global snap, whereas the second one sets the snap for the element ?

Yep. That's how all the settings (should) work.

are these coordinates relative to the document ? To the first positioned parent from the element ? To the element itself ?

Snap coordinates are relative to the top-left of the page. If you want to change this you can use the origin setting - http://interactjs.io/docs/#Interactable.origin.

For example, I used it in a post on path snapping To keep all coordinates relative to the canvas' top-left corners - https://github.com/taye/blog/blob/gh-pages/js/ijs-demo.js#L122-L135.

Now that I think about it, it would probably be convenient to allow an Element to be passed to Interactable#origin so that it's offset will be calculated and used.

Thanks for your help, interact.js is a really good work, doing just what it should.

I'm glad to hear that you like it. Let me know if you need any more info.

@jide
Copy link
Author

jide commented Feb 3, 2014

Thank you for your answer taye.

I did not digg into the code too much, but seeing how my DOM nodes (I'm using interact with the DOM) are positioned when using event.snap.x and event.snap.y I have the impression that the position is actually relative to the first positioned parent - Do you take into account parents that have position set to relative ? (Okay I will look at the code a little closer).

Thanks for the example, it may be useful.

I'll let you know if I need more info, and I'm going back to have some fun with interact.js !

@taye
Copy link
Owner

taye commented Feb 3, 2014

I'm not sure of what you mean. Could you give a sample of the code you're using if you still would like some help?

@jide
Copy link
Author

jide commented Feb 4, 2014

Here we go, this is a sample I made to show you what I mean.
Depending on the CSS position value, the snap is relative to the element or the document.
In the end, it does make sense, however it is not obvious in the docs.

<!DOCTYPE html>
<html>
<head>
    <title>Interact demo</title>
    <script type="text/javascript" src="interact.js"></script>
    <style>
        #container {
            margin-top: 100px;
            margin-left: 50%;
            padding: 30px;
            height: 300px;
            position: relative;
            border: 1px solid blue;
        }

        .draggable {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>

<div id="container">
    <div class="draggable">Drag me</div>    
</div>

<a id="switch">position:relative</a>

<script type="text/javascript">

interact('.draggable')
    .snap({
        mode: 'anchor',
        anchors: [
            {x: 0,  y: 0},
            {x: 20, y: 0},
            {x: 40, y: 0},
            {x: 60, y: 0},
            {x: 0,  y: 10},
            {x: 20, y: 10},
            {x: 40, y: 10},
            {x: 60, y: 10}
        ],
        range: 10
    })
    .draggable({
        onmove: function(event) {
            event.target.style.left = event.snap.x + "px";
            event.target.style.top = event.snap.y + "px";
        }
    });

var relative = true;
document.getElementById('switch').onclick = function() {
    if (relative) {
        this.innerHTML = 'position:static';
        document.getElementById('container').style.position = 'static';
    }
    else {
        this.innerHTML = 'position:relative';
        document.getElementById('container').style.position = 'relative';
    }

    relative = !relative;
};

</script>

</body>
</html>

@taye
Copy link
Owner

taye commented Feb 4, 2014

Aah, thank you. I understand now.

You're right; the styles of the element and it's parent aren't considered by interact.js. In this case it still gives you the position relative to the top-left of the page even though the element is being position relative to it's parent. You would have to set the origin of interact('.draggable') to the top-left of #container.

var container = document.getElementById('container');

interact('.draggable').origin({
  x: container.offsetLeft,
  y: container.offsetTop
});

@taye
Copy link
Owner

taye commented Feb 4, 2014

Also, you should probably use event.pageX/Y even if you're snapping.

event.snap.x/y gives the coordinates of the closest snap point even if it is not in range. If you want snap points to always be in range use rage: Infinity or range: -1

@jide
Copy link
Author

jide commented Feb 4, 2014

Ok, thanks for the tips ! Did not get that pageX/Y would snap too.

@jide
Copy link
Author

jide commented Feb 4, 2014

Something I don't understand is that when using range: Infinity, all coordinates in event are snapped ? Whether I use pageX, realX, x, dx, they all are snapped. Am I missing something ?

@jide
Copy link
Author

jide commented Feb 4, 2014

Sorry, my mistake, I was using event.snap !

@taye taye closed this as completed Feb 6, 2014
taye pushed a commit that referenced this issue May 5, 2015
@taye
Copy link
Owner

taye commented Jul 15, 2015

Snapping can now be relative to different points on the target element. See #133 and http://interactjs.io/docs/snapping/#relativepoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants