Code Monkey home page Code Monkey logo

muuri's People

Contributors

alexays avatar aslakhellesoy avatar derega avatar esaruoho avatar happier2 avatar indigane avatar jholland918 avatar kaocy avatar niklasramo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

muuri's Issues

Velocity.js vs alternatives

Originally I picked velocity for this project as I was familiar with it and I knew it to be fast, but lately I've been exploring other alternatives. The v0.3.0 is refactored in way that allows you to change the animation engine, although it is still a bit of a hassle, so in that sense there's no need to change the default animation engine. However, I really like what Popmotion, mo.js and anime are doing.

The plan is to try out each engine, do a little benchmarking and possibly change the default animation engine for the v1.0.0 release. Or better yet, make plugins for each engine so the user can choose which engine to use ;)

Two Suggestions

Have to say, it looks very promising! Would be interesting to see a selected event for the items. Also, being tied to hammer, not providing your own touch and drag engine is in my opinion, a downside.

Unit tests

Currently there are some basic smoke tests in place that check the existence of the methods, but we need to do a bit better than that. Now is time to add basic tests for all the methods and events.

Prevent native drag for images and anchors

If the item element or the item child element is an anchor element or an image element Muuri's dragging breaks since browsers provide native dragging (the ghost image) for those elements. It would be good if we prevented native drag for those elements automatically so users don't need to apply the hacks.

Improved drag and drop heuristics

Problem

When an item is dragged slowly on the grid the items sometimes bounce back and forth wildly when the layout method is triggered repeatedly before the element reaches the position it's been dragged to. There should definitely be smarter algorithm to handle these kind of scenario. Due to this problem the only really usable dragOverlapTolerance values are between 60 and 40.

Solution

When dragging check the direction and velocity of the event and take them into account when deciding on which element is targeted. Needs some testing to and tinkering to figure out a proper algorithm.

Position items relative to the container element's content

The gutter between the items is fully controlled via CSS, so if you wanted to have a gutter of 1px between the items you would probably do something like this:

.grid {
  border-right: 1px solid transparent;
  border-bottom: 1px solid transparent;
}
.item {
  margin: 1px 0 0 1px;
}

If we would give padding to the grid element it would do us no good since absolute positioned elements are always positioned relative to the outer edge of the containing element's padding. So using border is needed here. The problem is, however, that if we wanted the grid to have a visual border we would need wrap it in another element.

So, to overcome this annoyance I think the padding could be made useful by making the item elements position themselves relative to the inner edge of the containing element's padding. This way the CSS could be written like this:

.grid {
  padding: 0 1px 1px 0;
}
.item {
  margin: 1px 0 0 1px;
}

And we could also use border for other purposes on the grid element :)

Combine swap and move method

muuri.move(itemA, itemB) -> muuri.move(itemA, itemB, 'move')
muuri.swap(itemA, itemB) -> muuri.move(itemA, itemB, 'swap')

Handling massive amounts of items

I'm not sure if there exists yet a dynamic grid library which can handle a massive amount of items (10000+). Kinda like what SlickGrid is doing, but with dynamic grids. I have high hopes that I can make Muuri handle tons of items with decent responsiveness.

The rendering part will actually be the easiest part (although not easy to implement by any means). The simplest solution is just to add "display:none" to all items that are outside the viewport, which should be enough to keep the UI responsive. Sure, there are going to be problems with animating and it's going to require a lot of hair-pulling to get it right, but it's doable.

The hard part is getting the layout algorithm work fast in this kind of scenario. I have no clue how I'm gonna pull that off at the moment, but I think we can pull a rabbit or two out of the hat if we really try ;)

This kind of functionality is needed in infinitely scrolling grid layouts with lots of data, like Instagram or Pinterest for example.

Let's see if we can pull this off. Help and ideas are appreciated!

Muuri prevents container from scrolling on Mobile Safari

Since the touch events are handled by Hammer, I am unable to scroll the container that I have muurified, on mobile safari on iOS.

I believe it has to do with touch-actions = none.

One solution I can think of for this problem is to require that the user taps and holds a post before the dragging starts. That way swiping a post will continue to scroll the container per normal, and a tap+hold would activate dragging.

Scrolling while dragging

At least With Chrome this already happens automatically if the dragged element is within a scrollable element. However, it would be nice if Muuri allowed scrolling element(s) specified by the user when dragging occurs.

Allow defining hide/show styles

Currently Muuri only allows defining the duration and easing for hide and show animations, but it would be nice if one could also define the animated styles.

Add .filterItems() method

In the upcoming v0.3.0 version filtering can be done by first getting all the items and then looping them and calling the muuri.hideItems() and muuri.showItems() methods. As an example let's imagine we want to show all the items which has class "foo". In it's most simplistic form it would be done something like this:

muuri.getItems().forEach(function (item) {
  if (item.getElement().classList.contains('foo')) {
    muuri.showItems(item);
  }
  else {
    muuri.hideItems(item);
  }
});

Not too bad, but what if we had a filter method? It would probably look something like this:

muuri.filterItems(function (item, element) {
  return element.classList.contains('foo');
});

Much simpler and nicer. Although filtering can be easily accomplished without a specific filter method I think having it in the library would make filtering more approachable to Muuri's users. Also there is the fact that we can add optimizations to the filter method under the hood.

Going a bit further with the idea and example we could also add built-in support for filtering by class names and data-attributes. So the above example could be also written as:

muuri.filterItems('.foo');

Nice and short!

So, let's add the filter method to the v0.3.0 API shall we? =)

Layout speed optimizations

Try to make layout/overlap check as fast as possible by using smart heuristics. For example change the algorithm based on the item sizes. If all items are same size the algorithm can be simplified. Do heavy lifting only when necessary.

  • If move action is "swap" and the items are identical in size we can use the current layout and just swap the item positions. No recalculation needed. Big perf win!
  • For some use cases (lists and kanban boards) a grid layout is overkill (not to mention bin-packing algorithm). We should also have a simple layout algorithm for lists (vertically and horizontally stacking) which can be enabled via the options.

Optimizations

  • Don't store item list in the layout data.
  • Do layout dirty checking so that if we are sure that the layout has not changed we do not create a new layout.
  • When calculating the layout check if all elements have same width and/or height (this info can be leveraged in optimizations).
  • If a single element is swapped with another element of same size let's not do a full layout, but just switch the places of the element in the layout.
  • If a single element is moved in place of it's neighbouring element of the same size let's not do a full layout, but just switch the places of the element in the layout.

Keep the currently used Layout instance cached

Future performance optimizations in mind, I think it would be a good idea to keep the currently active Muuri.Layout instance stored in the Muuri instance so we can diff it with the next layout and possibly make some layout speed optimizations.

Add public item methods

Currently Muuri.Item has an undocumented prototype method .inspect() which returns data about the item. I though it would be useful to split the returned data into smaller methods and document them. So here's the new item methods:

  • item.getElement()
  • item.getWidth()
  • item.getHeight()
  • item.getMargin()
  • item.getPosition()
  • item.isActive()
  • item.isVisible()
  • item.isShowing()
  • item.isHiding()
  • item.isPositioning()
  • item.isDragging()
  • item.isReleasing()

Tips for Creating Filter Buttons

Sorry, JS noob and serial js plugin leverager here...I can usually write enough JS to gain access to a plugin, but I am having a ton of trouble creating filter buttons for Muuri. I have the plugin installed just fine, just need some examples to customize my grid based on button interactions.

Any help would be greatly appreciated!

LOVE MURRI BTW...it is a great piece of code.

Remove .indexOf() method

This one is probably not necessary to have in the API. Getting the index is not too hard and I don't see this being used so often.

Ideas for v1.0.0

I just released v0.3.0 and it was a big release: API rewrite, performance optimizations, tons of bug fixes a lot of new features (including dragging items between grids). I hope the API won't change too much for the upcoming 1.0.0 version, but let's see.

In any case I'll start working on the 1.0.0 version very soon and was hoping that I would get as much feedback on the 0.3.0 version as possible so when you have the time please give me some feedback. Also, I'm very open to any feature ideas you guys have =)

Drag sort predicate

Currently the drag sort predicate is hard coded and can only be configured using the dragSortAction and dragSortTolerance options. However, there might be cases where the default drag predicate is not sufficient, for example if the user provides a custom layout algorithm. With this in mind I though it might be a good idea to provide a way to allow the user to define a custom drag sort predicate.

The idea is to provide a new option called dragSortPredicate, which accepts either an object or a function. When an object is provided Muuri uses the default drag sort predicate, which can be configured by adding threshold and action properties to the configuration object. By default the object would be something like {threshold: 50, action: 'move'}.

When a function is provided Muuri calls the function during each drag event with the dragged Muuri.Item instance as it's first (and only) argument and expects the function to return a falsy value if no sorting is wanted and an object if sorting is wanted. The returned object should contain target item's current and new index and how information on how to move it (move or swap). Basically the data should be something like this: {action: 'move', from: 0, to: 1}.

Connected muuri instances

This is a big feature, we need to make it possible to connect Muuri instances to allow dragging items from a container to another.

Initial specs:

  • Allow moving and swapping items between two Muuri instances.
  • The Muuri instance that from which the item is moved to another Muuri instance should trigger a "send" event.
  • The Muuri instance that receives an item from another Muuri instance should trigger a "receive" event.

How to build own demo?

Hi!
Just found Your script from eWebDesign Newsletter Issue #178 ๐Ÿ‘
Looks very promissing but forgive my noob question

Where is the content of the grid in demo? :O
i see only

in index.html but on the browser i see filled grid container...
I want to try adapt it into Prestashop bootstrap theme. Masonry/Packery works fine. I will give muuri a chance :)

Drag placeholder

Currently there is no built-in drag placeholder. Would probably be a good usability enhancement.

Investigate if memory is leaked

So the code base is getting pretty heavy and I haven't had the chance to thoroughly test if memory is leaked. I have noticed that after dragging the memory is leaked a bit, but that might be also an issue with Hammer, don't know yet.

Ideally we would have automated memory leak tests and thankfully it appears there's already a library (drool) for making that happen.

If anyone is interested I'd be interested to hear reports of memory leaks. Also, pull requests are always appreciated if you're up for fixing the leaks you find ๐Ÿ˜‰

Add .sortItems() method

Currently Muuri's items can be sorted by mutating the muuri._items property, which is always an array of all the items in the Muuri instance. So just calling muuri._items.sort(function (a ,b) { ... }) does the trick. Define your own sorting logic and you're good to go.

However, this way of sorting has some concerns. The _items property is meant for internal use only, so it's a bit of a hacky approach, although it works nicely. It would probably be nicer for the users if we created a public API method for the above snippet, which would go something like this:

  muuri.sortItems(function (a, b) { ... });

Internally this method would just call muuri._items.sort(function (a ,b) { ... }), but now it's more approachable for the users and can be documented.

Also later on we could add more functionality to the method by allowing it to, for example, accept an object which can be configured in the same style as Isotope allows.

[Suggestion] React.js version?

Hi,

This is an awesome library. If there was a react.js version for this, I'm sure there'd be alot of users. There are existing libraries I've tried and the one of them is react-dnd which is what I use. Its setup is not straightforward but it is super flexible, it doesn't offer any transitions out of the box though. There's another called react-sortable-hoc which is easy to setup but does not support multiple lists/containers.

Add .getElement() and .getRect() methods

I thought it would be nice to have a public method for retrieving Muuri instance's element (might come in handy when connected Muuri instances feature is ready). Also, layout system is now changed a bit and Muuri keeps the container element's dimensions and offsets cached, which should be retrievable via muuri.getRect() method.

filter button help...again

I had some luck creating a filter button using the demo js as a guide, but I have run up against another challenge. My first version worked on the first filter but then just appended the grid on every other filter. I added a rather inelegant reset of the "itemsToShow" array at the beginning of my click function to solve that problem, but it doesn't animate as nicely as the initial filter add gets progressively worse. Do you have any advice for a better solution? I apologize in advance for my basic code...still learning. Here is the js:

$(document).ready(function() {
var filterButton = $(".filter-button");
var items = grid.get();
var itemsToShow = [];
var itemsToHide = [];

  $( filterButton ).click(function(e) {

    e.preventDefault();
    var filterButtonType = $(this).attr('id');
    itemsToShow = [];

    items.forEach(function (item) {
      var $elem = $(item._element);
      var isFilterMatch = filterButtonType ? $elem.attr('data-filter-type') === filterButtonType: true;
      (isFilterMatch ? itemsToShow : itemsToHide).push(item);
      grid.hide(itemsToHide);
      grid.show(itemsToShow);

    });
  });

});

Random items

Hello!
How can i make a gellery with random order of items on every loading?

Thank you!

drag images

I love muuri,but not clear on how to applay to a real project. And I got a question when try it. Why the images concluded in the item-content can not be dragged? Is that OK to insert different size pictures? How can I fix my code. Thanks.
http://codepen.io/diyifang/pen/NdVgNX

Allow dropping an item over an empty space

Problem

A dragged item needs to overlap another item in order for moving to happen. A dragged item can not be dropped on empty gaps within the grid, which feels like bug.

Solution

When calculating the layout, don't lose the empty slots data, but instead use it for the drag overlap calculations. For example, connect each empty slot to an actual item and when the dragged item overlaps an empty slot the item is moved in place of the slot's connected item. The current layout data should be stored in the Muuri instance.

Problem Using Percentage Width Items

Is it possible to use percentages instead of hard coded dimensions for items? I developed my project using them which worked fine on my local, but when I pushed them to my dev site the images weren't loading in time for muuri so leaving my heights at auto borked my grid. Can I use the refresh items function to resize after load? I tried preloading the images, but that hasn't solved the problem. Maybe delay the layout function? If I do delay or refresh...would I put that in the init code or run a separate script? Any help would be greatly appreciated. See my page here... http://www.tomwattsart.com/work.html

Thanks,
Tom

Refactor the animation system to be overwritable

It would be nice if the user would not be limited to using Velocity as the only way to animate the items. Figure out a way to make it possible for the user to use another animation engine to do all the animations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.