├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── demo
├── app.js
└── index.html
├── dist
├── angular-bricklayer.js
└── angular-bricklayer.min.js
├── package.json
└── src
└── angular-bricklayer.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /bower_components
2 | /.idea
3 | /node_modules
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | var banner = '/**\n @name: <%= pkg.name %> \n @version: <%= pkg.version %> (<%= grunt.template.today("dd-mm-yyyy") %>) \n @author: <%= pkg.author %> \n @url: <%= pkg.homepage %> \n @license: <%= pkg.license %>\n*/\n';
4 |
5 | var sources = [
6 | 'node_modules/imagesloaded/imagesloaded.pkgd.js',
7 | 'src/angular-bricklayer.js'
8 | ];
9 |
10 | grunt.initConfig({
11 | pkg: grunt.file.readJSON('package.json'),
12 | uglify: {
13 | js: {
14 | files : {
15 | 'dist/angular-bricklayer.min.js' : sources
16 | }
17 | },
18 | options: {
19 | banner: banner
20 | }
21 | },
22 | concat: {
23 | options: {
24 | separator: ';',
25 | banner: banner
26 | },
27 | dist: {
28 | src: sources,
29 | dest: 'dist/angular-bricklayer.js'
30 | }
31 | },
32 | watch: {
33 | minifiyJs: {
34 | files: sources,
35 | tasks: ['uglify', 'concat'],
36 | options: {
37 | spawn: true
38 | }
39 | }
40 | }
41 | });
42 |
43 | grunt.loadNpmTasks('grunt-contrib-concat');
44 | grunt.loadNpmTasks('grunt-contrib-uglify');
45 | grunt.loadNpmTasks('grunt-contrib-watch');
46 |
47 | grunt.registerTask('default', ['watch']);
48 |
49 | };
50 |
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jonathan Hornung
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-bricklayer
2 | AngularJS module for [ademilter's bricklayer](https://github.com/ademilter/bricklayer), a lightweight & independent cascading grid layout library
3 |
4 | [](https://badge.fury.io/js/angular-bricklayer)
5 | [](https://badge.fury.io/bo/angular-bricklayer)
6 |
7 | ## Demos
8 | - [Simple demo on GitHub](https://rawgit.com/JohnnyTheTank/angular-bricklayer/master/demo/index.html)
9 | - [Simple demo on Plnkr](http://plnkr.co/edit/mo3G36)
10 | - [Demo with images from flickr](https://rawgit.com/JohnnyTheTank/apiNG-design-bricklayer/master/demo/index.html) (made with [apiNG](https://github.com/JohnnyTheTank/apiNG))
11 |
12 | [](http://ademilter.github.io/bricklayer)
13 |
14 | ## Installation
15 |
16 | 1. Install via either [bower](http://bower.io/), [npm](https://www.npmjs.com/) or downloaded files:
17 | 1. via bower: `bower install --save angular-bricklayer`
18 | 2. via npm: `npm install --save angular-bricklayer`
19 | 3. via CDN (jsDelivr)
20 | 4. via [downloaded files](https://github.com/JohnnyTheTank/angular-bricklayer/zipball/master)
21 |
22 | 2. Include dependencies and angular-bricklayer in your HTML.
23 | 1. When using bower
24 | ```html
25 |
26 |
27 |
28 | ```
29 | 2. When using npm
30 | ```html
31 |
32 |
33 |
34 | ```
35 | 3. When using CDN
36 | ```html
37 |
38 |
39 |
40 | ```
41 | 4. When using downloaded files
42 | ```html
43 |
44 |
45 |
46 | ```
47 |
48 | 3. Add **`jtt_bricklayer`** to your application's module dependencies, like this:
49 | ```javascript
50 | angular.module('app', ['jtt_bricklayer']);
51 | ```
52 |
53 | ## Usage
54 | Create a simple list and set the css class **`bricklayer`** like this
55 |
56 | ```html
57 |
58 |
Your item
59 |
Your another item
60 |
Your another but long item
61 |
Your another but very short item
62 |
Your one more item
63 |
Your smallest item
64 |
65 | ```
66 |
67 | Define **bricklayer column size**:
68 |
69 | ```css
70 | @media screen and (min-width: 1200px) {
71 | .bricklayer-column-sizer {
72 | /* divide by 3. */
73 | width: 33.3%;
74 | }
75 | }
76 |
77 | @media screen and (min-width: 768px) {
78 | .bricklayer-column-sizer {
79 | /* divide by 2. */
80 | width: 50%;
81 | }
82 | }
83 | ```
84 |
85 | ## Add bricks dynamically
86 |
87 | Use `bricklayer-append` or `bricklayer-prepend` as attribute, class or element name inside of your `bricklayer` instance
88 |
89 | ```html
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | ```
98 |
99 | ## Images
100 | Since `v1.1.0` the grid gets redrawn when images have been loaded, by including and using [desandro's imagesloaded](https://github.com/desandro/imagesloaded)
101 |
102 | # License
103 | MIT
104 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-bricklayer",
3 | "homepage": "https://github.com/JohnnyTheTank/angular-bricklayer",
4 | "authors": [
5 | "Jonathan Hornung "
6 | ],
7 | "description": "AngularJS module for bricklayer, a lightweight & independent cascading grid layout library",
8 | "main": "dist/angular-bricklayer.js",
9 | "version": "1.1.0",
10 | "moduleType": [],
11 | "keywords": [
12 | "angular",
13 | "angularjs",
14 | "grid",
15 | "bricklayer",
16 | "masonry"
17 | ],
18 | "ignore": [
19 | "**/.*",
20 | "src",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "tests",
25 | "demo"
26 | ],
27 | "license": "MIT",
28 | "devDependencies": {
29 | "angular": "^1.5.5"
30 | },
31 | "dependencies": {
32 | "bricklayer": "^0.4.1",
33 | "imagesloaded": "^4.1.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/demo/app.js:
--------------------------------------------------------------------------------
1 | angular.module('app', ['jtt_bricklayer']);
2 |
3 | angular.module('app')
4 | .controller("appController", function ($scope) {
5 | $scope.createElement = function () {
6 | return {
7 | color: '#' + Math.random().toString(16).substr(-6),
8 | height: sizes[Math.floor(Math.random() * sizes.length)],
9 | width: sizes[Math.floor(Math.random() * sizes.length)],
10 | }
11 | };
12 |
13 | $scope.data = [];
14 |
15 | $scope.appendNew = function () {
16 | $scope.data.push($scope.createElement());
17 | };
18 |
19 | var sizes = [220, 250, 260, 270, 290, 300, 310, 330, 400, 430, 450, 480, 500];
20 |
21 | for (var i = 0; i < 10; i++) {
22 | $scope.appendNew();
23 | }
24 |
25 | });
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | angular-bricklayer
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
![]()
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/dist/angular-bricklayer.js:
--------------------------------------------------------------------------------
1 | /**
2 | @name: angular-bricklayer
3 | @version: 1.1.0 (25-04-2016)
4 | @author:
5 | @url: https://github.com/JohnnyTheTank/angular-bricklayer
6 | @license: MIT
7 | */
8 | /*!
9 | * imagesLoaded PACKAGED v4.1.0
10 | * JavaScript is all like "You images are done yet or what?"
11 | * MIT License
12 | */
13 |
14 | /**
15 | * EvEmitter v1.0.1
16 | * Lil' event emitter
17 | * MIT License
18 | */
19 |
20 | /* jshint unused: true, undef: true, strict: true */
21 |
22 | ( function( global, factory ) {
23 | // universal module definition
24 | /* jshint strict: false */ /* globals define, module */
25 | if ( typeof define == 'function' && define.amd ) {
26 | // AMD - RequireJS
27 | define( 'ev-emitter/ev-emitter',factory );
28 | } else if ( typeof module == 'object' && module.exports ) {
29 | // CommonJS - Browserify, Webpack
30 | module.exports = factory();
31 | } else {
32 | // Browser globals
33 | global.EvEmitter = factory();
34 | }
35 |
36 | }( this, function() {
37 |
38 |
39 |
40 | function EvEmitter() {}
41 |
42 | var proto = EvEmitter.prototype;
43 |
44 | proto.on = function( eventName, listener ) {
45 | if ( !eventName || !listener ) {
46 | return;
47 | }
48 | // set events hash
49 | var events = this._events = this._events || {};
50 | // set listeners array
51 | var listeners = events[ eventName ] = events[ eventName ] || [];
52 | // only add once
53 | if ( listeners.indexOf( listener ) == -1 ) {
54 | listeners.push( listener );
55 | }
56 |
57 | return this;
58 | };
59 |
60 | proto.once = function( eventName, listener ) {
61 | if ( !eventName || !listener ) {
62 | return;
63 | }
64 | // add event
65 | this.on( eventName, listener );
66 | // set once flag
67 | // set onceEvents hash
68 | var onceEvents = this._onceEvents = this._onceEvents || {};
69 | // set onceListeners array
70 | var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || [];
71 | // set flag
72 | onceListeners[ listener ] = true;
73 |
74 | return this;
75 | };
76 |
77 | proto.off = function( eventName, listener ) {
78 | var listeners = this._events && this._events[ eventName ];
79 | if ( !listeners || !listeners.length ) {
80 | return;
81 | }
82 | var index = listeners.indexOf( listener );
83 | if ( index != -1 ) {
84 | listeners.splice( index, 1 );
85 | }
86 |
87 | return this;
88 | };
89 |
90 | proto.emitEvent = function( eventName, args ) {
91 | var listeners = this._events && this._events[ eventName ];
92 | if ( !listeners || !listeners.length ) {
93 | return;
94 | }
95 | var i = 0;
96 | var listener = listeners[i];
97 | args = args || [];
98 | // once stuff
99 | var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
100 |
101 | while ( listener ) {
102 | var isOnce = onceListeners && onceListeners[ listener ];
103 | if ( isOnce ) {
104 | // remove listener
105 | // remove before trigger to prevent recursion
106 | this.off( eventName, listener );
107 | // unset once flag
108 | delete onceListeners[ listener ];
109 | }
110 | // trigger listener
111 | listener.apply( this, args );
112 | // get next listener
113 | i += isOnce ? 0 : 1;
114 | listener = listeners[i];
115 | }
116 |
117 | return this;
118 | };
119 |
120 | return EvEmitter;
121 |
122 | }));
123 |
124 | /*!
125 | * imagesLoaded v4.1.0
126 | * JavaScript is all like "You images are done yet or what?"
127 | * MIT License
128 | */
129 |
130 | ( function( window, factory ) { 'use strict';
131 | // universal module definition
132 |
133 | /*global define: false, module: false, require: false */
134 |
135 | if ( typeof define == 'function' && define.amd ) {
136 | // AMD
137 | define( [
138 | 'ev-emitter/ev-emitter'
139 | ], function( EvEmitter ) {
140 | return factory( window, EvEmitter );
141 | });
142 | } else if ( typeof module == 'object' && module.exports ) {
143 | // CommonJS
144 | module.exports = factory(
145 | window,
146 | require('ev-emitter')
147 | );
148 | } else {
149 | // browser global
150 | window.imagesLoaded = factory(
151 | window,
152 | window.EvEmitter
153 | );
154 | }
155 |
156 | })( window,
157 |
158 | // -------------------------- factory -------------------------- //
159 |
160 | function factory( window, EvEmitter ) {
161 |
162 |
163 |
164 | var $ = window.jQuery;
165 | var console = window.console;
166 |
167 | // -------------------------- helpers -------------------------- //
168 |
169 | // extend objects
170 | function extend( a, b ) {
171 | for ( var prop in b ) {
172 | a[ prop ] = b[ prop ];
173 | }
174 | return a;
175 | }
176 |
177 | // turn element or nodeList into an array
178 | function makeArray( obj ) {
179 | var ary = [];
180 | if ( Array.isArray( obj ) ) {
181 | // use object if already an array
182 | ary = obj;
183 | } else if ( typeof obj.length == 'number' ) {
184 | // convert nodeList to array
185 | for ( var i=0; i < obj.length; i++ ) {
186 | ary.push( obj[i] );
187 | }
188 | } else {
189 | // array of single index
190 | ary.push( obj );
191 | }
192 | return ary;
193 | }
194 |
195 | // -------------------------- imagesLoaded -------------------------- //
196 |
197 | /**
198 | * @param {Array, Element, NodeList, String} elem
199 | * @param {Object or Function} options - if function, use as callback
200 | * @param {Function} onAlways - callback function
201 | */
202 | function ImagesLoaded( elem, options, onAlways ) {
203 | // coerce ImagesLoaded() without new, to be new ImagesLoaded()
204 | if ( !( this instanceof ImagesLoaded ) ) {
205 | return new ImagesLoaded( elem, options, onAlways );
206 | }
207 | // use elem as selector string
208 | if ( typeof elem == 'string' ) {
209 | elem = document.querySelectorAll( elem );
210 | }
211 |
212 | this.elements = makeArray( elem );
213 | this.options = extend( {}, this.options );
214 |
215 | if ( typeof options == 'function' ) {
216 | onAlways = options;
217 | } else {
218 | extend( this.options, options );
219 | }
220 |
221 | if ( onAlways ) {
222 | this.on( 'always', onAlways );
223 | }
224 |
225 | this.getImages();
226 |
227 | if ( $ ) {
228 | // add jQuery Deferred object
229 | this.jqDeferred = new $.Deferred();
230 | }
231 |
232 | // HACK check async to allow time to bind listeners
233 | setTimeout( function() {
234 | this.check();
235 | }.bind( this ));
236 | }
237 |
238 | ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
239 |
240 | ImagesLoaded.prototype.options = {};
241 |
242 | ImagesLoaded.prototype.getImages = function() {
243 | this.images = [];
244 |
245 | // filter & find items if we have an item selector
246 | this.elements.forEach( this.addElementImages, this );
247 | };
248 |
249 | /**
250 | * @param {Node} element
251 | */
252 | ImagesLoaded.prototype.addElementImages = function( elem ) {
253 | // filter siblings
254 | if ( elem.nodeName == 'IMG' ) {
255 | this.addImage( elem );
256 | }
257 | // get background image on element
258 | if ( this.options.background === true ) {
259 | this.addElementBackgroundImages( elem );
260 | }
261 |
262 | // find children
263 | // no non-element nodes, #143
264 | var nodeType = elem.nodeType;
265 | if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
266 | return;
267 | }
268 | var childImgs = elem.querySelectorAll('img');
269 | // concat childElems to filterFound array
270 | for ( var i=0; i < childImgs.length; i++ ) {
271 | var img = childImgs[i];
272 | this.addImage( img );
273 | }
274 |
275 | // get child background images
276 | if ( typeof this.options.background == 'string' ) {
277 | var children = elem.querySelectorAll( this.options.background );
278 | for ( i=0; i < children.length; i++ ) {
279 | var child = children[i];
280 | this.addElementBackgroundImages( child );
281 | }
282 | }
283 | };
284 |
285 | var elementNodeTypes = {
286 | 1: true,
287 | 9: true,
288 | 11: true
289 | };
290 |
291 | ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
292 | var style = getComputedStyle( elem );
293 | if ( !style ) {
294 | // Firefox returns null if in a hidden iframe https://bugzil.la/548397
295 | return;
296 | }
297 | // get url inside url("...")
298 | var reURL = /url\((['"])?(.*?)\1\)/gi;
299 | var matches = reURL.exec( style.backgroundImage );
300 | while ( matches !== null ) {
301 | var url = matches && matches[2];
302 | if ( url ) {
303 | this.addBackground( url, elem );
304 | }
305 | matches = reURL.exec( style.backgroundImage );
306 | }
307 | };
308 |
309 | /**
310 | * @param {Image} img
311 | */
312 | ImagesLoaded.prototype.addImage = function( img ) {
313 | var loadingImage = new LoadingImage( img );
314 | this.images.push( loadingImage );
315 | };
316 |
317 | ImagesLoaded.prototype.addBackground = function( url, elem ) {
318 | var background = new Background( url, elem );
319 | this.images.push( background );
320 | };
321 |
322 | ImagesLoaded.prototype.check = function() {
323 | var _this = this;
324 | this.progressedCount = 0;
325 | this.hasAnyBroken = false;
326 | // complete if no images
327 | if ( !this.images.length ) {
328 | this.complete();
329 | return;
330 | }
331 |
332 | function onProgress( image, elem, message ) {
333 | // HACK - Chrome triggers event before object properties have changed. #83
334 | setTimeout( function() {
335 | _this.progress( image, elem, message );
336 | });
337 | }
338 |
339 | this.images.forEach( function( loadingImage ) {
340 | loadingImage.once( 'progress', onProgress );
341 | loadingImage.check();
342 | });
343 | };
344 |
345 | ImagesLoaded.prototype.progress = function( image, elem, message ) {
346 | this.progressedCount++;
347 | this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
348 | // progress event
349 | this.emitEvent( 'progress', [ this, image, elem ] );
350 | if ( this.jqDeferred && this.jqDeferred.notify ) {
351 | this.jqDeferred.notify( this, image );
352 | }
353 | // check if completed
354 | if ( this.progressedCount == this.images.length ) {
355 | this.complete();
356 | }
357 |
358 | if ( this.options.debug && console ) {
359 | console.log( 'progress: ' + message, image, elem );
360 | }
361 | };
362 |
363 | ImagesLoaded.prototype.complete = function() {
364 | var eventName = this.hasAnyBroken ? 'fail' : 'done';
365 | this.isComplete = true;
366 | this.emitEvent( eventName, [ this ] );
367 | this.emitEvent( 'always', [ this ] );
368 | if ( this.jqDeferred ) {
369 | var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
370 | this.jqDeferred[ jqMethod ]( this );
371 | }
372 | };
373 |
374 | // -------------------------- -------------------------- //
375 |
376 | function LoadingImage( img ) {
377 | this.img = img;
378 | }
379 |
380 | LoadingImage.prototype = Object.create( EvEmitter.prototype );
381 |
382 | LoadingImage.prototype.check = function() {
383 | // If complete is true and browser supports natural sizes,
384 | // try to check for image status manually.
385 | var isComplete = this.getIsImageComplete();
386 | if ( isComplete ) {
387 | // report based on naturalWidth
388 | this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
389 | return;
390 | }
391 |
392 | // If none of the checks above matched, simulate loading on detached element.
393 | this.proxyImage = new Image();
394 | this.proxyImage.addEventListener( 'load', this );
395 | this.proxyImage.addEventListener( 'error', this );
396 | // bind to image as well for Firefox. #191
397 | this.img.addEventListener( 'load', this );
398 | this.img.addEventListener( 'error', this );
399 | this.proxyImage.src = this.img.src;
400 | };
401 |
402 | LoadingImage.prototype.getIsImageComplete = function() {
403 | return this.img.complete && this.img.naturalWidth !== undefined;
404 | };
405 |
406 | LoadingImage.prototype.confirm = function( isLoaded, message ) {
407 | this.isLoaded = isLoaded;
408 | this.emitEvent( 'progress', [ this, this.img, message ] );
409 | };
410 |
411 | // ----- events ----- //
412 |
413 | // trigger specified handler for event type
414 | LoadingImage.prototype.handleEvent = function( event ) {
415 | var method = 'on' + event.type;
416 | if ( this[ method ] ) {
417 | this[ method ]( event );
418 | }
419 | };
420 |
421 | LoadingImage.prototype.onload = function() {
422 | this.confirm( true, 'onload' );
423 | this.unbindEvents();
424 | };
425 |
426 | LoadingImage.prototype.onerror = function() {
427 | this.confirm( false, 'onerror' );
428 | this.unbindEvents();
429 | };
430 |
431 | LoadingImage.prototype.unbindEvents = function() {
432 | this.proxyImage.removeEventListener( 'load', this );
433 | this.proxyImage.removeEventListener( 'error', this );
434 | this.img.removeEventListener( 'load', this );
435 | this.img.removeEventListener( 'error', this );
436 | };
437 |
438 | // -------------------------- Background -------------------------- //
439 |
440 | function Background( url, element ) {
441 | this.url = url;
442 | this.element = element;
443 | this.img = new Image();
444 | }
445 |
446 | // inherit LoadingImage prototype
447 | Background.prototype = Object.create( LoadingImage.prototype );
448 |
449 | Background.prototype.check = function() {
450 | this.img.addEventListener( 'load', this );
451 | this.img.addEventListener( 'error', this );
452 | this.img.src = this.url;
453 | // check if image is already complete
454 | var isComplete = this.getIsImageComplete();
455 | if ( isComplete ) {
456 | this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
457 | this.unbindEvents();
458 | }
459 | };
460 |
461 | Background.prototype.unbindEvents = function() {
462 | this.img.removeEventListener( 'load', this );
463 | this.img.removeEventListener( 'error', this );
464 | };
465 |
466 | Background.prototype.confirm = function( isLoaded, message ) {
467 | this.isLoaded = isLoaded;
468 | this.emitEvent( 'progress', [ this, this.element, message ] );
469 | };
470 |
471 | // -------------------------- jQuery -------------------------- //
472 |
473 | ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
474 | jQuery = jQuery || window.jQuery;
475 | if ( !jQuery ) {
476 | return;
477 | }
478 | // set local variable
479 | $ = jQuery;
480 | // $().imagesLoaded()
481 | $.fn.imagesLoaded = function( options, callback ) {
482 | var instance = new ImagesLoaded( this, options, callback );
483 | return instance.jqDeferred.promise( $(this) );
484 | };
485 | };
486 | // try making plugin
487 | ImagesLoaded.makeJQueryPlugin();
488 |
489 | // -------------------------- -------------------------- //
490 |
491 | return ImagesLoaded;
492 |
493 | });
494 |
495 | ;angular.module('jtt_bricklayer', [])
496 | .directive('bricklayer', ['$timeout', function ($timeout) {
497 | return {
498 | restrict: 'C',
499 | link: function (scope, element, attrs) {
500 | var bricklayer = new Bricklayer(element[0]);
501 |
502 | imagesLoaded(element[0], function () {
503 | bricklayer.redraw();
504 | });
505 |
506 | $timeout(function () {
507 | bricklayer.redraw();
508 | });
509 |
510 | scope.$on('bricklayer.append', function (event, selectedElement) {
511 | bricklayer.append(selectedElement[0]);
512 | bricklayer.redraw();
513 | imagesLoaded(selectedElement, function () {
514 | bricklayer.redraw();
515 | });
516 | });
517 |
518 | scope.$on('bricklayer.prepend', function (event, selectedElement) {
519 | bricklayer.prepend(selectedElement[0]);
520 | bricklayer.redraw();
521 | imagesLoaded(selectedElement, function () {
522 | bricklayer.redraw();
523 | });
524 | });
525 |
526 | scope.$on('bricklayer.redraw', function () {
527 | bricklayer.redraw();
528 | });
529 | },
530 | controller: function () {
531 | }
532 | }
533 | }])
534 | .directive('bricklayerAppend', function () {
535 | return {
536 | require: '^^bricklayer',
537 | restrict: 'ACE',
538 | link: function (scope, element, attrs) {
539 | scope.$emit('bricklayer.append', element);
540 | }
541 | }
542 | })
543 | .directive('bricklayerPrepend', function () {
544 | return {
545 | require: '^^bricklayer',
546 | restrict: 'ACE',
547 | link: function (scope, element, attrs) {
548 | scope.$emit('bricklayer.prepend', element);
549 | }
550 | }
551 | });
--------------------------------------------------------------------------------
/dist/angular-bricklayer.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | @name: angular-bricklayer
3 | @version: 1.1.0 (25-04-2016)
4 | @author:
5 | @url: https://github.com/JohnnyTheTank/angular-bricklayer
6 | @license: MIT
7 | */
8 | !function(a,b){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",b):"object"==typeof module&&module.exports?module.exports=b():a.EvEmitter=b()}(this,function(){function a(){}var b=a.prototype;return b.on=function(a,b){if(a&&b){var c=this._events=this._events||{},d=c[a]=c[a]||[];return-1==d.indexOf(b)&&d.push(b),this}},b.once=function(a,b){if(a&&b){this.on(a,b);var c=this._onceEvents=this._onceEvents||{},d=c[a]=c[a]||[];return d[b]=!0,this}},b.off=function(a,b){var c=this._events&&this._events[a];if(c&&c.length){var d=c.indexOf(b);return-1!=d&&c.splice(d,1),this}},b.emitEvent=function(a,b){var c=this._events&&this._events[a];if(c&&c.length){var d=0,e=c[d];b=b||[];for(var f=this._onceEvents&&this._onceEvents[a];e;){var g=f&&f[e];g&&(this.off(a,e),delete f[e]),e.apply(this,b),d+=g?0:1,e=c[d]}return this}},a}),function(a,b){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(c){return b(a,c)}):"object"==typeof module&&module.exports?module.exports=b(a,require("ev-emitter")):a.imagesLoaded=b(a,a.EvEmitter)}(window,function(a,b){function c(a,b){for(var c in b)a[c]=b[c];return a}function d(a){var b=[];if(Array.isArray(a))b=a;else if("number"==typeof a.length)for(var c=0;c"
6 | ],
7 | "description": "AngularJS module for bricklayer, a lightweight & independent cascading grid layout library",
8 | "main": "dist/angular-bricklayer.js",
9 | "keywords": [
10 | "angular",
11 | "angularjs",
12 | "grid",
13 | "bricklayer",
14 | "masonry"
15 | ],
16 | "scripts": {
17 | "test": "echo \"Error: no test specified\" && exit 1"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/JohnnyTheTank/angular-bricklayer.git"
22 | },
23 | "author": "",
24 | "license": "MIT",
25 | "bugs": {
26 | "url": "https://github.com/JohnnyTheTank/angular-bricklayer/issues"
27 | },
28 | "homepage": "https://github.com/JohnnyTheTank/angular-bricklayer",
29 | "devDependencies": {
30 | "angular": "^1.5.5",
31 | "grunt": "^0.4.5",
32 | "grunt-contrib-concat": "^0.5.1",
33 | "grunt-contrib-uglify": "^0.11.0",
34 | "grunt-contrib-watch": "^0.6.1"
35 | },
36 | "dependencies": {
37 | "bricklayer": "^0.4.1",
38 | "imagesloaded": "^4.1.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/angular-bricklayer.js:
--------------------------------------------------------------------------------
1 | angular.module('jtt_bricklayer', [])
2 | .directive('bricklayer', ['$timeout', function ($timeout) {
3 | return {
4 | restrict: 'C',
5 | link: function (scope, element, attrs) {
6 | var bricklayer = new Bricklayer(element[0]);
7 |
8 | imagesLoaded(element[0], function () {
9 | bricklayer.redraw();
10 | });
11 |
12 | $timeout(function () {
13 | bricklayer.redraw();
14 | });
15 |
16 | scope.$on('bricklayer.append', function (event, selectedElement) {
17 | bricklayer.append(selectedElement[0]);
18 | bricklayer.redraw();
19 | imagesLoaded(selectedElement, function () {
20 | bricklayer.redraw();
21 | });
22 | });
23 |
24 | scope.$on('bricklayer.prepend', function (event, selectedElement) {
25 | bricklayer.prepend(selectedElement[0]);
26 | bricklayer.redraw();
27 | imagesLoaded(selectedElement, function () {
28 | bricklayer.redraw();
29 | });
30 | });
31 |
32 | scope.$on('bricklayer.redraw', function () {
33 | bricklayer.redraw();
34 | });
35 | },
36 | controller: function () {
37 | }
38 | }
39 | }])
40 | .directive('bricklayerAppend', function () {
41 | return {
42 | require: '^^bricklayer',
43 | restrict: 'ACE',
44 | link: function (scope, element, attrs) {
45 | scope.$emit('bricklayer.append', element);
46 | }
47 | }
48 | })
49 | .directive('bricklayerPrepend', function () {
50 | return {
51 | require: '^^bricklayer',
52 | restrict: 'ACE',
53 | link: function (scope, element, attrs) {
54 | scope.$emit('bricklayer.prepend', element);
55 | }
56 | }
57 | });
--------------------------------------------------------------------------------