seiyria / dropsort.js

A drag/drop/sortable replacement to jQuery UI
MIT License
2 stars 1 forks source link

auto-scroll #3

Open seiyria opened 10 years ago

seiyria commented 10 years ago

hey @j-ro -

could you take a look at the plunk and see if you can get auto-scroll working? For whatever reason it seems like it should be working but it isn't working correctly.

Here's the plunk: http://plnkr.co/edit/qi4tR54Nw0gmI1sP3HZg?p=preview (ninja edit - changed the plunk)

j-ro commented 10 years ago

Hm...seemed to work for me on chrome anyway. I could take the drag me 2 box down the page and more page would open up under it as I went. It wasn't the smoothest, but it did work...

seiyria commented 10 years ago

Right, what I'm trying to do is drag it smoothly to the edge, and have it continuously scroll. The continuous part is what's causing me a bit of grief.

seiyria commented 10 years ago

I've also asked on stackoverflow and didn't get a huge reception, so if you manage to figure it out I'd appreciate it if you posted the answer there too. I won't have a lot of time to look into this for a while as I'm looking at other drag features currently.

j-ro commented 10 years ago

Gotcha. Here's what I implemented the other day to do similar:

//if we're over the bounding box and should scroll up, do so
if (mouseEvent.pageX >= this.$build.position().left && mouseEvent.pageX < (this.$build.width() + this.$build.position().left) && mouseEvent.pageY <= ($('.form_create #fancybox-content').offset().top)) {
     $('.form_create #fancybox-content').animate({scrollTop: 0}, 1300);    
} 
// else if we're below the box and should scroll down, do that instead, setting the box height + box top offset as the scrollTop goal
else if (mouseEvent.pageX >= this.$build.position().left && mouseEvent.pageX < (this.$build.width() + this.$build.position().left) && mouseEvent.pageY >= ($('.form_create #fancybox-content').offset().top + $('.form_create #fancybox-content').height())) {
     $('.form_create #fancybox-content').animate({scrollTop: $('.form_create #fancybox-content > div').height()}, 1300);
} 
//otherwise we're in the box, so cancel the scrolling to stop
else {
     $('.form_create #fancybox-content').stop();
}

The above is obviously jQuery, but you get the idea -- I think what you want are to set the scrolling animation if you detect you're outside of the bounding box, otherwise cancel it to freeze the scroll bar where you are. Works very smoothly for me once I got to this method.

j-ro commented 10 years ago

Well, here's a start of an attempt:

http://plnkr.co/edit/yuI2JE3JJol28XVQOLsl?p=preview

I'll admin that coffeescript is a bit opaque to me at the moment, so we've got errors and I'm not sure why. But that scrollToTop function is apparently an implementation of jQuery's scrollTop and animate but without the jquery, according to:

http://stackoverflow.com/questions/21474678/scrolltop-animation-without-jquery

seiyria commented 10 years ago

Hey, no worries. I can take a look at it tomorrow and see if I can help out with it. Thanks!

j-ro commented 10 years ago

Cool! If you can solve my (probably basic) syntax issues, I can probably give you a hand with the logic. But my jQuery code above is the basic structure -- we want to animate the scroll bar up to the top of the page or down to the bottom (or left or right to either edge) when the plugin detects the box is at the edges, and cancel that animation when the box is moved back to the center.

seiyria commented 10 years ago

Sure, that sounds simple. I'll take a stab at it tomorrow and I'll post back if I make any positive progress.

j-ro commented 10 years ago

Cool -- the key revelation for me was the animation. I first started as you have, incrementing the scroll position, but that's not really what you want. You want to kick off a slow and steady animation to the top/bottom/left/right, and cancel it when the dragged element moves back to the center.

seiyria commented 10 years ago

Ah, your issue was just a misplaced variable declaration: http://plnkr.co/edit/zBvtyUm2JzRXQH4iYvj1?p=preview

You had scrollToTop: -> where it should have been scrollToTop = -> (subtle but important difference - : implies this.variable, whereas = is just a normal variable declaration.

I still can't seem to get it working, but I'll try to work with it some more.

seiyria commented 10 years ago

Brief update: I found this pen that might help. Going to try to implement some of it.

j-ro commented 10 years ago

Getting somewhere here:

http://plnkr.co/edit/u3UxpOwFK4otPTR1DRbh?p=preview

If you drag down to the bottom, it'll scroll (constant speed, doesn't use the option right now). The interval isn't cleared however after (line 127 doesn't work apparently), so you can't scroll back up. And this is only scrolling down...

But progress!

seiyria commented 10 years ago

Hmm. What browser are you using? Chrome still? I can't seem to get autoscrolling, haha. Or maybe I'm looking at an outdated version.

j-ro commented 10 years ago

yeah, chrome. It only works in one scenario -- drag a box to the bottom of the screen.

seiyria commented 10 years ago

Right - that's what I tried. Hm. Did you save / freeze so I could view the version you were working on?

j-ro commented 10 years ago

ah, try that link now -- plunk didn't save apparently...

seiyria commented 10 years ago

Great. Yeah, that is smooth, I like it. I'm currently experimenting with scrollLeft and offsetLeft and other numbers.

j-ro commented 10 years ago

Yeah, we need to implement detection and scrolling for each direction, and need to figure out how to cancel that interval...

j-ro commented 10 years ago

and there's some weirdness when you get to the end of the page...

j-ro commented 10 years ago

also, this is detecting the window right now, but we probably want to generalize it so it can detect a parent scrollable element instead (as part of our parent detection thing). Like, if this is in a scrollable div, it should detect those edges and scroll that instead of the window.

seiyria commented 10 years ago

I think that is easily doable via element.offsetParent.

seiyria commented 10 years ago

Here's my attempt: http://plnkr.co/edit/vDHEzoEZwmkIGtKh91DR?p=preview

It's pretty terrible, because it moves the scrollbar too far, too fast. It might be a helpful starting point for you.

j-ro commented 10 years ago

Yes, though we'll have to think about how our options work -- I'd suggest perhaps taking a container option, where you pass in an element to be the container, because it might not be a direct parent.

seiyria commented 10 years ago

That's how I have it setup. It will default to the current parent element, otherwise it will use whatever you specify.

j-ro commented 10 years ago

Nice -- re: your link, I'd say the method by which you add an offset to the scroll position is not the one you want. Doing it that way means you continually make the window bigger as you keep scrolling, which is not expected nor desired behavior I think. Rather, you want to scroll to the already existing bounds. That's what my example attempts to do.

seiyria commented 10 years ago

Hmm. However, one thing that I will need is the ability to infinitely scroll in a direction if there are no containment bounds -- that's what I'm going for with my example.

j-ro commented 10 years ago

Oh really? Can you go into that use case a bit more? Not something I envisioned needing, rather my thought was you'd want to be able to place an element at the beginning or end of a list that potentially needs to scroll.

seiyria commented 10 years ago

Sure. So in a part of the app I'm developing at work, one of the requirements is to have it bounded on left, top, and right, but have it infinitely scale downwards (this is why the box parameter is created). It's a drag and drop application where people can drag things in and create a "dashboard", and how it's created is how it's viewed. People should be able to expand the viewport by dragging downwards if they need more space.

Does that make sense? Not sure how well I explained it.

j-ro commented 10 years ago

Ah, yes, I think I see -- and a requirement here is to do this in a freeform way, rather than snapping to invisible rows or something?

seiyria commented 10 years ago

It actually also snaps to grid -- I was planning on adding that feature next, after autoscroll.

j-ro commented 10 years ago

If you're doing the grid thing, I'd maybe recommend it happening the other way. Here's a quick screencast video I took of our form builder, which displays similar behavior:

http://jasonandmelinda.com/can/dragdrop.swf

What this is doing is creating the drop target DOM element first, which has the nice side effect of extending the window farther down, rather than doing it the other way around. I think doing it with incrementing the scroll bar for true, unbounded and unsnapped infinite scroll is probably always also going to be fairly jerky...

seiyria commented 10 years ago

Hm, I see. I guess I'm not really sure how to proceed. I mean - it could probably be capped at a certain px size, but I wouldn't want it to always display that large if it didn't necessarily need to, hence why I felt like it should expand / contract infinitely.

It would seem I'm not really sure how to go forward with that idea. I think I'll let you handle the autoscroll aspect since you seem to know how to do it. I'll work on snapping it to a grid.

j-ro commented 10 years ago

Yeah, I'd say that makes sense -- you can make the snap flexible I'd imagine (append different size temporary dom elements for different sizes if you have different situations for it). This way, the scrolling can happen within the window and its height and width, rather than expanding it. If you want to expand the height/width, that's where the temporary drop target dom elements come in.

That said, we may end up with two scroll methods if we determine that we do want the infinite behavior because snap and temporary drop targets doesn't work for us.

seiyria commented 10 years ago

That's fine too, so long as we provide options to do so. I was thinking of implementing snap like jQuery UI does it. I think it just makes it so you can only be on a numerical value and it doesn't use any temporary elements or anything.

j-ro commented 10 years ago

Yeah, might, not sure how jQuery works

seiyria commented 10 years ago

Fair enough. I'll work on implementing that and I'll send you the new plunk.

seiyria commented 10 years ago

Here's the axis example: http://plnkr.co/edit/vDHEzoEZwmkIGtKh91DR?p=preview

It's a bit clunky currently, but it works. I'm going to work on making drop zones a thing next.

j-ro commented 10 years ago

ok, autoscrolling working, at least for the basic case:

http://plnkr.co/edit/u3UxpOwFK4otPTR1DRbh?p=preview

Few notes -- first, we're only looking at the window here, we'll have to implement the parent element thing later. Second, the box does not scroll with the pointer -- maybe this has to do with how we're doing tracking on the box's css or something? Probably should though. And, it's a bit strange at the edges but good enough for jazz for now I'd say...

seiyria commented 10 years ago

For sure. It doesn't seem to expand the document when it gets to that edge, but that's the only oddity you didn't mention.

The reason I'm tracking the box like I am is because if the mouse desyncs with the dragged item (ie, if you drag off of the screen and move the mouse back on, your mouse position will still be the same so you're not dragging an item 100px away). I think that's the most user-friendly way to do it to be honest.

j-ro commented 10 years ago

Well it does, kind of, but it's not supposed to! I think we'll handle that on your end, with the dom and snap and whatnot. Re: the box movement, sure, let's see how it develops, it seems fine as it is.

seiyria commented 10 years ago

Great. I had hoped you'd like the movement, because I'm not too keen on the way jQuery does it - I really, really don't like how I can be dragging something 100px away from me.

Sure, I have snap all set up, it's just a bit of math. Feel free to merge your changes into mine, too. Right now I'm working on a few more jQuery options (axis first, then zIndex). I think then I was going to work on droppable stuff (unless you'd prefer to do that).

Where would you like to go from here?

j-ro commented 10 years ago

Great! I've gotta get on a flight and I'll be at a conference through the weekend, so that's probably about it for me this week. I'd say re-ordering and drop targets are probably next, yeah?

seiyria commented 10 years ago

Sure, I'm thinking actually that multi-select / drag would be a good place to start as well. I think I'm going to further enhance dragging before moving on yet.

j-ro commented 10 years ago

created PR, probably worth closing this for now? there's more work to do on the issue, but we probably want to get a bit farther along before we come back to it.

seiyria commented 10 years ago

Yeah, for now. I was thinking of trying to implement scrollSensitivity from jQuery, that might smooth things out a bit.

seiyria commented 10 years ago

Currently it only scrolls like 5 times for me: http://plnkr.co/edit/vDHEzoEZwmkIGtKh91DR?p=preview

I'm going to merge the plunk back into github now that more progress has been made, as well.

I'll also close this because it will have to get worked on more later. I have an idea that I'm going to try out with it.

j-ro commented 10 years ago

Sounds good to me -- this really shouldn't scroll much at all, because the page isn't larger than the window, but the dragged elements expand the page and cause some scrolling as a side effect.

seiyria commented 10 years ago

Hmm, I see. Yeah, I have one idea to try and we'll see how that turns out. After that, I'm going to stop for a while - I think the draggable aspect is pretty solid for now. I'll be moving on to drop then. Would you like to start working on sortable? I'll be doing that probably within a week, since drop is pretty easy.

j-ro commented 10 years ago

Sure, yeah -- I'm basically assuming we want to take a regular set of items (say, li tags or divs or something) and allow you to drag and drop between them, horizontally or vertically?

seiyria commented 10 years ago

Yeah. I should be able to easily do multi-drag / drop with the dragAnchorElements stuff I have set up, then the only thing left to do after drag / drop / sort is to make sure it works in IE9.