enmi12/glossaire/_posts/docs/2011-05-25-extending-isotope.mdown
changeset 0 d970ebf37754
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 ---
       
     2 
       
     3 title: Extending Isotope
       
     4 category: docs
       
     5 layout: default
       
     6 toc:
       
     7   - { title: Custom layout modes, anchor: custom_layout_modes }
       
     8 
       
     9 ---
       
    10 
       
    11 Isotope uses a constructor pattern, `$.Isotope`. To extend Isotope, you need only to add a method to `$.Isotope.prototype`.
       
    12 
       
    13 {% highlight javascript %}
       
    14 
       
    15 $.Isotope.prototype.myMethod = function() { ... };
       
    16 
       
    17 // or, using jQuery extend utility
       
    18 $.extend( $.Isotope.prototype, {
       
    19   myMethod : function() { ... }
       
    20 });
       
    21 
       
    22 {% endhighlight %}
       
    23 
       
    24 Before diving in, try [looking over the source](../jquery.isotope.js) to get a better understand of the internal logic behind Isotope.
       
    25 
       
    26 ## Custom layout modes
       
    27 
       
    28 Isotope's layout modes are built around four methods: `Reset`, `Layout`, `GetContainerSize`, and `ResizeChanged`. These methods are the hooks that allow you to develop your own custom layout mode, without getting your hands dirty dealing with sorting, filtering, or other functionality. These layout mode methods need to be prefixed with an underscore and the name of the layout mode.
       
    29 
       
    30 {% highlight javascript %}
       
    31 
       
    32 // adding layout mode methods for 'customMode'
       
    33 $.extend( $.Isotope.prototype, {
       
    34   _customModeReset : function() { ... },
       
    35   _customModeLayout : function( $elems ) { ... },
       
    36   _customModeGetContainerSize : function() { ... },
       
    37   _customModeResizeChanged : function() { ... }
       
    38 });
       
    39 
       
    40 {% endhighlight %}
       
    41 
       
    42 [**See Custom layout mode: Category Rows**](../custom-layout-modes/category-rows.html)
       
    43 [**See Custom layout mode: Spine align**](../custom-layout-modes/spine-align.html)
       
    44 
       
    45 All of the [default layout modes](../docs/layout-modes.html) follow this pattern. We'll look at the code behind the _fitRows_ layout mode.
       
    46 
       
    47 ### Reset
       
    48 
       
    49 Each layout mode should have its own set of properties that only it can use and not be affected by other layout modes. These properties can be accessed in the instance as an object whose value matches the layout mode name (i.e. `this.fitRows` for _fitRows_).
       
    50 
       
    51 The `Reset` layout mode method is called with every `reLayout`, where Isotope will go through each item element and position it. This method resets layout mode properties.
       
    52 
       
    53 The _fitRows_ layout mode keeps track of x and y position, as well as the height of the container. These properties are set back to zero in `Reset`.
       
    54 
       
    55 {% highlight javascript %}
       
    56 
       
    57 _fitRowsReset : function() {
       
    58   this.fitRows = {
       
    59     x : 0,
       
    60     y : 0,
       
    61     height : 0
       
    62   };
       
    63 },
       
    64 
       
    65 {% endhighlight %}
       
    66 
       
    67 ### Layout
       
    68 
       
    69 The `Layout` layout mode method is where items are positioned. Most of your layout logic happens here. This method provides one argument `$elems` -- a jQuery object with the item elements that need to be positioned.
       
    70 
       
    71 `$elems.each` is the principle loop, iterating over each item element and positioning it. Items are positioned with the `_pushPosition` method (see below). The layout modes properties are 
       
    72 
       
    73 For _fitRows_, items are placed with the `this.fitRows.x` and `this.fitRows.y` values. This position is determined by if the item can fit in the current row, or if a new row needs to be started.
       
    74 
       
    75 {% highlight javascript %}
       
    76 
       
    77 _fitRowsLayout : function( $elems ) {
       
    78   var instance = this,
       
    79       containerWidth = this.element.width(),
       
    80       props = this.fitRows;
       
    81   
       
    82   $elems.each( function() {
       
    83     var $this = $(this),
       
    84         atomW = $this.outerWidth(true),
       
    85         atomH = $this.outerHeight(true);
       
    86   
       
    87     if ( props.x !== 0 && atomW + props.x > containerWidth ) {
       
    88       // if this element cannot fit in the current row
       
    89       props.x = 0;
       
    90       props.y = props.height;
       
    91     } 
       
    92   
       
    93     // position the atom
       
    94     instance._pushPosition( $this, props.x, props.y );
       
    95 
       
    96     props.height = Math.max( props.y + atomH, props.height );
       
    97     props.x += atomW;
       
    98 
       
    99   });
       
   100 },
       
   101 
       
   102 {% endhighlight %}
       
   103 
       
   104 ### GetContainerSize
       
   105 
       
   106 After the script goes through positioning each item, it needs to resize the container. `GetContainerSize` returns the style for the size of the container.
       
   107 
       
   108 In _fitRows_, the height property is returned as the value for height.
       
   109 
       
   110 {% highlight javascript %}
       
   111 
       
   112 _fitRowsGetContainerSize : function () {
       
   113   return { height : this.fitRows.height };
       
   114 },
       
   115 
       
   116 {% endhighlight %}
       
   117 
       
   118 ### ResizeChanged
       
   119 
       
   120 `ResizeChanged` is triggered whenever the browser window is resized. Before Isotope adjusts the layout, this method is triggered to determine if the layout has actually changed. The methods return a boolean.
       
   121 
       
   122 {% highlight javascript %}
       
   123 
       
   124 _fitRowsResizeChanged : function() {
       
   125   return true;
       
   126 },
       
   127 
       
   128 {% endhighlight %}
       
   129 
       
   130 ### Helper methods
       
   131 
       
   132 The `_pushPosition` method is used within a layout mode's `Layout` method. It takes 3 arguments: the item element currently being positioned, the x position, and the y position.
       
   133 
       
   134 {% highlight javascript %}
       
   135 
       
   136 _pushPosition( $item, x, y )
       
   137 
       
   138 {% endhighlight %}
       
   139 
       
   140 `_getSegments` is used within the layout mode's `Reset` method. It performs several utilities:
       
   141 
       
   142 + Determines the `columnWidth` for the layout mode (`rowHeight` for horizontal layout modes). This is either passed in as an option (i.e. `masonry { columnWidth: 90 }`), or the width of the first item element. This property is then set for the layout mode, i.e. `this.masonry.columnWidth`.
       
   143 + Calculates the number of number of columns (or rows, if horizontal) given the size of the container. This property is then set for the layout mode, i.e. `this.masonry.cols`.
       
   144 
       
   145 {% highlight javascript %}
       
   146 
       
   147 _getSegments( isHorizontal )
       
   148 
       
   149 // for example
       
   150 _cellsByRowReset : function() {
       
   151   this.cellsByRow = {
       
   152     index : 0
       
   153   };
       
   154   // get this.cellsByRow.columnWidth
       
   155   this._getSegments();
       
   156   // get this.cellsByRow.rowHeight
       
   157   this._getSegments(true);
       
   158 },
       
   159 
       
   160 {% endhighlight %}
       
   161 
       
   162 Similarly, `_checkIfSegmentsChanged` is used within `ResizeChanged`. It returns a boolean indicating whether or not the number of columns or rows has changed since the window has been resized.
       
   163 
       
   164 {% highlight javascript %}
       
   165 
       
   166 _checkIfSegmentsChanged( isHorizontal )
       
   167 
       
   168 // for example
       
   169 _masonryResizeChanged : function() {
       
   170   return this._checkIfSegmentsChanged();
       
   171 },
       
   172 
       
   173 {% endhighlight %}
       
   174