-
Notifications
You must be signed in to change notification settings - Fork 4
GridSwiper
GridSwiper is a dual axis infinite (or limited) swiper. This component re-uses its 5 grid cells rendered in a cross pattern and moves them around depending on the direction of the swipe for performance rendering in mind, just like a tile engine.
GridSwiper renders content in its virtual grid based on a map (and limited to that map's depth/size), or based on content added every time a swipe has completed.
Extends
Uxi, Touch
{"selector:GridSwiper":{CONFIG}}
let config = {
el:_SELECTOR_, //Required, the HTML element
core:_OGX_APP_, //OGX.App instance, required if used within app with views
map:_ARRAY_, //Optional, data map
start:_POINT_, //Optional, a 2D point coordinates of the grid cell to show at start, defaults to center of map
loop:_BOOL_, //Optional, infinite loop
axis:_OBJECT_, //Optional, object to enable/disable axis, defaults to {x:true, y:true}
chromeos:_BOOL_ //Optional, set to true if used on ChromeOS app
};
As an OML node
let swiper = OGX.OM.render(this, OML);
At runtime, from an object extending UXi
let swiper = this.create('GridSwiper', config);
Independently
let swiper = OGX.Object.create('GridSwiper', config);
In order to tell the component what to render at start and then what to render as the end user swipes the grid, you need to work with a 2D map. If you simply want to horizontally swipe between 2 panels or views, check out Carousel
As a 2D array is passed then the depth restriction is based on the length of the series around its starting point. In other words, the component will display content BB upon start, a swipe down would display content BA and disable further swiping down. Then swiping right would display content AA and disable further swiping right.
let config = {..., map:[
['content AA', 'content BA', 'content CA'],
['content AB', 'content BB', 'content CB'],
['content AC', 'content BC', 'content CC'],
]};
If you wish to prevent the end user to land on a particular cell, set the map data to false for that cell. For instance, if we change the map to the following, the end user will be restricted from reaching the top left cell
let config = {..., map:[
[false, 'content BA', 'content CA'],
['content AB', 'content BB', 'content CB'],
['content AC', 'content BC', 'content CC'],
]};
You can of course use OML instead of html content. In this case, the views will receive a call to their focus/blur method depending on their individual position. If a view, due to the result of a swipe, is not displayed anymore, it will receive a call to its blur method. If the view if outside of the surroundings of the displayed cell, that view will get destroyed.
If you are using OML, your map would look like this
{..., map:[[
{"default:Views.MyView":{template:'MyTemplate', data:SomeDataA}},
{"default:Views.OtherView":{template:'MyTemplate', data:SomeDataB}},
{"default:Views.ThirdView":{template:'MyTemplate', data:SomeDataC}},
]]};
You can also pass dynamic data based on the cell position by using a custom function. Consider this simple function that will return a different object based on the value of the passed relative cell point
function customData(relative_point, absolute_point, offset_point){
if(relative_point.x > 5){
return {whatever:'whatever'};
}
return {whatever:'breh'};
}
Now you can use this function to generate custom data for a view by settings it in the map, such as
{..., map:[[
{"default:Views.MyView":{template:'MyTemplate', data:customData}},
{"default:Views.OtherView":{template:'MyTemplate', data:customData}},
{"default:Views.ThirdView":{template:'MyTemplate', data:customData}},
]]};
In this case, the OML nodes will be passed the result of customData as it is instanced in a cell of the grid
You can also render cells content using custom functions. Custom functions receive the relative and absolute grid point coordinates and the HTML element representing the content of the cell. Consider the following custom function
function renderStuff(relative_point, absolute_point, offset_point, element){
var html = 'My custom content for grid cell at '+relative_point.x+','+relative_point.y;
return html;
}
This is a very simple function that will return a html string with the passed coordinates. Up to you to make your own calculations based on the given points, to return a html string that would vary on the coordinates of the points. Then to use it, simply add it to your map
let config = {..., map:[
[renderStuff, 'content BA', 'content CA'],
['content AB', 'content BB', 'content CB'],
['content AC', 'content BC', renderStuff],
]};
In this configuration, the custom function will be called when displaying the top left of the map or the bottom right.
relative_point is the point relative to your map. Loops are ignored here and the point will always be relative to your map length. This point will never pass the width/height of the map.
absolute_point is the overall offset based on the grid system. Depending on your map, that point might be the same as the relative_point at start, but in a loop situation, the absolute_point will keep increasing/decreasing passed the width/height of the map.
offset_point is used to indicate the position of a cell around the centered cell, such as
{x:-1, y:0}
to indicate that the cell is left of the centered cell,{x:0, y:1}
would indicate the cell is below the centered cell.
If you want to work in a true unlimited grid without passing all of the content in a map, you can add content on the fly. In this case, you would set your map to display the initial cells (start cell and the cells around it in a cross pattern), and then update the map after every swipe.
let config = {..., map:[
['', 'content BA', ''],
['content AB', 'content BB', 'content CB'],
['', 'content BC', ''],
]};
Then you would listen to a swipe event and then from that event, update the map content, such as
swiper.el.on(OGX.GridSwiper.SWIPE_RIGHT, function(__e, __data){
//__data.cell = the relative map cell
//__data.point = the absolute map point
//set some content on the fly for the cell on the left
swiper.setLeftCell('some html content');
});
The data object that is passed upon a swipe contains the relative and absolute coordinates. The cell property holds the relative map cell, meaning that no matter how many times you have looped, you will get coordinates within the map range.
The point property holds the absolute point, which can be negative. For instance, if the end user swipes right enough time to loop, the x coordinate might be negative.
Now, if you use this method, understand that you must be passing content that is not yet visible, around the visible cell, based on the direction of a swipe.
If you wish to have a the grid infinitely displaying your content in a loop, set the loop flag to true in the config. If set to false, the component will prevent from swiping in a direction outside of the map bounds.
If a start point is not passed, the component will calculate and use the center of the map as the starting point. If you wish to start to a specific location, pass a start point corresponding to the coordinates of the cell to display, such as
let config = {..., start:{x:0, y:0}, ...}
You can also force an axis to be disabled by using the axis flag. The following disables swipping vertically, no matter if the map has multiple rows. Note that using a map with only 1 row automatically disables the vertical axis
let config = {..., axis:{x:true, y:false}, ...}
swiper.swipeRight();
swiper.swipeLeft();
swiper.swipeUp();
swiper.swipeDown();
swiper.setMap(__map, __start_pt); //Set map (2DArray) and optional start point
swiper.setMapCell(__point, __data); //Set or update data in map
swiper.getCells(); //Return rendered cells as {abs:point, abs:point, offset:abs:point, element:HTMelement}
swiper.setTopCell(_content_); //Set the content for cell top to current cell
swiper.setBottomCell(_content_); //Set the content for cell bottom to current cell
swiper.setLeftCell(_content_); //Set the content for the cell left to current cell
swiper.setRightCell(_content_); //Set the content for the cell right to current cell
OGX.GridSwiper.SWIPE_RIGHT
OGX.GridSwiper.SWIPE_LEFT
OGX.GridSwiper.SWIPE_UP
OGX.GridSwiper.SWIPE_DOWN
OGX.GridSwiper.SWIPE_START
OGX.GridSwiper.SWIPE_END
swiper.enable();
swiper.disable();
swiper.destroy();
- Welcome
- Changelog
- Structure
- Configuration
- Getting started
- CLI
- Poly
- Core
- Templating
- Routing
- Controllers
- Components
- Extra Components
- Helpers
- Styling
- Debugging