added missing vimeo urls to existing talks

This commit is contained in:
Alex Corbi 2017-01-22 18:36:33 +01:00
parent 542d9e753a
commit 66c59cc269
118 changed files with 44678 additions and 20411 deletions

130
_layouts/event-special.html Normal file
View file

@ -0,0 +1,130 @@
---
layout: default
---
<div class="content container-fluid">
<article>
<div class="row">
<div class="transp-bg padded event-info col-md-2 col-md-offset-1">
<div class="event-date">
<h3>#{{page.number}}</h3>
<h4>{{page.date_text}}</h4>
</div>
<div class="padded_vert">
<ul>
{% for talk in page.talks %}
{% if talk.topics %}
{% assign tags = (talk.topics | split:",") %}
{% for tag in tags | uniq %}
<li>{{tag}}</li>
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</div>
<div class="padded_vert">
{% if page.location %}
<ul>
<li><a class="highlight button hvr-sweep-to-top" href={{post.location_website}} target="_blank">{{page.location}}</a></li>
{% if page.fb_event_url %}
<li><a class="highlight button hvr-sweep-to-top" target="_blank" href={{post.fb_event_url}}><i class="fa fa-facebook-square"></i></a></li>
{% endif %}
</ul>
{% endif %}
</div>
</div>
<div class="event event-{{page.number}} dark_bg col-md-7">
{% capture talks_number %}{{ page.talks | size }}{% endcapture %} {% capture col_width %}{{ 12 | divided_by:talks_number }}{% endcapture %} {% for talk in page.talks %}
<div class="talk col-md-{{col_width}}">
<div class="artist-media">
{% if {{talk.media_artist_url}} %}
<img src={{talk.media_artist_url}}></img>
{% else %}
<img src="/assets/no_artist_media.png"></img>
{% endif %}
</div>
<div class="talk-detail">
<h4>{{talk.artist}} / {{talk.title}}</h4>
{% if talk.description %}
<p>{{talk.description}}</p>
{% endif %} {% if talk.artist_bio %}
<h5>About {{talk.artist}}</h5>
<p>{{talk.artist_bio}}</p>
{% endif %}
{% if talk.artist_website || talk.video_artist_url || talk.video_url %}
{% if talk.artist_website %}
<a class="button hvr-sweep-to-top" href={{talk.artist_website}} target="_blank"><i class="fa fa-link"></i> Website</a>
{% endif %}
{% if talk.video_artist_url %}
<div class="transp-bg padded">
<p>Artist's Video</p>
<iframe src="//player.vimeo.com/video/{{(talk.video_artist_url | split:"/") | last}}" width="100%" height="140" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
{% endif %}
{% if talk.talk_video_url %}
<div class="transp-bg padded">
<p>Talk's Video</p>
<iframe src="//player.vimeo.com/video/{{(talk.talk_video_url | split:"/") | last}}" width="100%" height="140" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
{% if page.fb_gallery_id %}
<div class="row">
<div class="gallery dark_bg col-md-7 col-md-offset-3">
<h4>Photo gallery of the event</h4>
<div class="picbook"></div>
<script type="text/javascript">
var picbook = new picbookJs({
limit: 100,
albumId: '{{page.fb_gallery_id}}'
});
</script>
</div>
</div>
{% endif %}
</div>
<div class="row">
<div class="nav_bottom dark_bg col-md-7 col-md-offset-3">
<h4>Discover more</h4>
{% if page.previous %}
<a class="button hvr-sweep-to-top left" href={{page.previous.url | prepend: site.baseurl }}>#{{page.previous.number}}: {{page.previous.date_text}} {{page.previous.title}}</a> {% endif %} {% if page.next %}
<a class="button hvr-sweep-to-top right" href={{page.next.url | prepend: site.baseurl }}>#{{page.next.number}}: {{page.next.date_text}} {{page.next.title}}</a> {% endif %}
</div>
</div>
</article>
</div>

View file

@ -19,7 +19,7 @@ talks:
artist_website: "http://www.mfoptik.de/"
media_artist_url: "/images/ctm-trailer1-416x226.jpg_resized.png"
video_artist_url: "https://vimeo.com/39914745"
talk_video_url: https://vimeo.com/39914745
talk_video_url: "https://vimeo.com/39914745"
- title:
topics: "Experimental,Film"
artist: "Thorsten Fleisch"

View file

@ -24,9 +24,7 @@ talks:
topics: "Performance,Humour"
artist: "A-LI-CE "
speakers: "Claire Fristot"
artist_bio: "A-li-ce, based in Paris, works as video designer, live performer and VJ since 2004 around Europe. She uses a bunch of techniques from paper, animation and video, bridging the gap from hyperrealities “wonderland” to sophisticated, dark visual worlds.
Her work deals with identity, humor, and acidity. She presented her work at audiovisual festivals like Mapping (Ch), LPM (It), Visual Berlin Festival (De), and VisionR (Fr), including VJ solos and collective projects with Homemade Collective and the duo :NÄ:. Her music videos and short animation movies have been screened in festivals as the International Animation Film Festivals of Moscow ( 2011) and Stuttgart (official music video selection, 2011), Cinemabrut (2010) and many more."
artist_bio: "A-li-ce, based in Paris, works as video designer, live performer and VJ since 2004 around Europe. She uses a bunch of techniques from paper, animation and video, bridging the gap from hyperrealities “wonderland” to sophisticated, dark visual worlds. Her work deals with identity, humor, and acidity. She presented her work at audiovisual festivals like Mapping (Ch), LPM (It), Visual Berlin Festival (De), and VisionR (Fr), including VJ solos and collective projects with Homemade Collective and the duo :NÄ:. Her music videos and short animation movies have been screened in festivals as the International Animation Film Festivals of Moscow ( 2011) and Stuttgart (official music video selection, 2011), Cinemabrut (2010) and many more."
description: "For this years LPM edition, she will premiere the Piece «Parade: Ouverture», which is the first act of the “Parade A/V live performance project”, inspired freely on “The Atrocity Exhibition” of the writer J.G. Ballard. In collaboration with the sound artist Swub, it deals with spam messages, white lights, birds, electricity, schizophrenia, and Abba music."
artist_website: "http://www.a-li-ce.com"
media_artist_url: "/images/managua_still02_web.jpg_resized.png"

View file

@ -29,5 +29,5 @@ talks:
artist_website: "http://vvvv.org/"
media_artist_url: "/images/screenshot1420807005.png_resized.png"
video_artist_url:
talk_video_url:
talk_video_url: "https://vimeo.com/116418592"
---

View file

@ -14,9 +14,7 @@ talks:
topics: "Drawing, Sound"
artist: "Patrick K.-H., Andreas Karaoulanis"
speakers: "Patrick K.-H., Andreas Karaoulanis"
artist_bio: "Patrick K.-H. (Anton Iakhontov, b. 1980)
sound artist / video artist / composer, for the time works with sound installations, live and written acousmatic, graphical collage and animation. Researches interactive / cross-disciplinary forms, permutating the media, aiming on achieving unexpected mutants. Member of Theremin Center for Electroacoustic Music at Moscow Conservatory and Institut für Medienarchäologie (Austria). Author of music / video to drama / contemporary dance / post-dramatic theater plays and performances as well as his own works in Russia, Austria and Germany.
Art-director of Media Studio in Alexandrinsky Theater, St. Petersburg. Founder and co-curator of the Floating Sound Gallery for spatial sound (St.Petersburg). Currently lives and works in Vienna / St.Petersburg."
artist_bio: "Patrick K.-H. (Anton Iakhontov, b. 1980) sound artist / video artist / composer, for the time works with sound installations, live and written acousmatic, graphical collage and animation. Researches interactive / cross-disciplinary forms, permutating the media, aiming on achieving unexpected mutants. Member of Theremin Center for Electroacoustic Music at Moscow Conservatory and Institut für Medienarchäologie (Austria). Author of music / video to drama / contemporary dance / post-dramatic theater plays and performances as well as his own works in Russia, Austria and Germany. Art-director of Media Studio in Alexandrinsky Theater, St. Petersburg. Founder and co-curator of the Floating Sound Gallery for spatial sound (St.Petersburg). Currently lives and works in Vienna / St.Petersburg."
description: "(un)imation, unmusic, (un)struments"
artist_website: "http://drawnsound.org/"
media_artist_url: "/images/11391117_1153538288005410_1868394068597484897_n.jpg_resized.png"

View file

@ -19,7 +19,7 @@ talks:
artist_website:
media_artist_url: "/images/lauren-moffatt-540x320.jpg_resized.png"
video_artist_url: "https://vimeo.com/122552886"
talk_video_url:
talk_video_url: "https://vimeo.com/170467514"
- title:
topics: "Society"
artist: "MBJ Wetware"
@ -29,7 +29,7 @@ talks:
artist_website: "https://vimeo.com/user9345531"
media_artist_url: "/images/MARIJA-BOZINOVSKA-JONES-1-540x320.jpg_resized.png"
video_artist_url: "https://vimeo.com/104462080"
talk_video_url:
talk_video_url: "https://vimeo.com/170467518"
- title:
topics: "Electronic arts"
artist: "Carla Chan"
@ -39,5 +39,5 @@ talks:
artist_website: "https://vimeo.com/user4900276"
media_artist_url: "/images/carla-chan-black-moves_-540x320.jpg_resized.png"
video_artist_url: "https://vimeo.com/138680101"
talk_video_url:
talk_video_url: "https://vimeo.com/170482794"
---

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
"fontawesome": "~4.3.0",
"imagefill.js": "*",
"jquery": "~2.1.1",
"vegas": "~1.3.5"
"vegas": "~1.3.5",
"isotope": "^3.0.1"
}
}

View file

@ -0,0 +1,27 @@
# matchesSelector helper
[`matches`/`matchesSelector`](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) is pretty hot :fire:, but has [vendor-prefix baggage](http://caniuse.com/#feat=matchesselector) :handbag: :pouch:. This helper function takes care of that, without polyfilling or augmenting `Element.prototype`.
``` js
matchesSelector( elem, selector );
// for example
matchesSelector( myElem, 'div.my-hawt-selector' );
```
## Install
Download [matches-selector.js](https://github.com/desandro/matches-selector/raw/master/matches-selector.js)
Install with [Bower](http://bower.io): `bower install matches-selector`
[Install with npm](https://www.npmjs.org/package/desandro-matches-selector): `npm install desandro-matches-selector`
## Browser support
IE10+, all modern browsers
Use [matchesSelector v1](https://github.com/desandro/matches-selector/releases/tag/v1.0.3) for IE8 and IE9 support.
## MIT license
matchesSelector is released under the [MIT license](http://desandro.mit-license.org)

View file

@ -0,0 +1,32 @@
{
"name": "matches-selector",
"description": "matches/matchesSelector helper",
"main": "matches-selector.js",
"devDependencies": {
"qunit": "1.x"
},
"homepage": "https://github.com/desandro/matches-selector",
"authors": [
"David DeSandro"
],
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"DOM",
"matchesSelector",
"matches"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"tests.*",
"package.json"
]
}

View file

@ -0,0 +1,53 @@
/**
* matchesSelector v2.0.1
* matchesSelector( element, '.selector' )
* MIT license
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
( function( window, factory ) {
/*global define: false, module: false */
'use strict';
// universal module definition
if ( typeof define == 'function' && define.amd ) {
// AMD
define( factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory();
} else {
// browser global
window.matchesSelector = factory();
}
}( window, function factory() {
'use strict';
var matchesMethod = ( function() {
var ElemProto = Element.prototype;
// check for the standard method name first
if ( ElemProto.matches ) {
return 'matches';
}
// check un-prefixed
if ( ElemProto.matchesSelector ) {
return 'matchesSelector';
}
// check vendor prefixes
var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
for ( var i=0; i < prefixes.length; i++ ) {
var prefix = prefixes[i];
var method = prefix + 'MatchesSelector';
if ( ElemProto[ method ] ) {
return method;
}
}
})();
return function matchesSelector( elem, selector ) {
return elem[ matchesMethod ]( selector );
};
}));

View file

@ -0,0 +1,101 @@
# EvEmitter
_Lil' event emitter_ — add a little pub/sub
EvEmitter adds publish/subscribe pattern to a browser class. It's a smaller version of [Olical/EventEmitter](https://github.com/Olical/EventEmitter). That EventEmitter is full featured, widely used, and great. This EvEmitter has just the base event functionality to power the event API in libraries like [Isotope](http://isotope.metafizzy.co), [Flickity](http://flickity.metafizzy.co), [Masonry](http://masonry.desandro.com), and [imagesLoaded](http://imagesloaded.desandro.com).
## API
``` js
// Inherit prototype, IE8+
MyClass.prototype = new EvEmitter();
// Inherit prototype, IE9+
MyClass.prototype = Object.create( EvEmitter.prototype );
// Mixin prototype
_.extend( MyClass.prototype, EvEmitter.prototype );
// single instance
var emitter = new EventEmitter();
```
### on
Add an event listener.
``` js
emitter.on( eventName, listener )
```
+ `eventName` - _String_ - name of the event
+ `listener` - _Function_
### off
Remove an event listener.
``` js
emitter.off( eventName, listener )
```
### once
Add an event listener to be triggered only once.
``` js
emitter.once( eventName, listener )
```
### emitEvent
Trigger an event.
``` js
emitter.emitEvent( eventName, args )
```
+ `eventName` - _String_ - name of the event
+ `args` - _Array_ - arguments passed to listeners
## Code example
``` js
// create event emitter
var emitter = new EventEmitter();
// listeners
function hey( a, b, c ) {
console.log( 'Hey', a, b, c )
}
function ho( a, b, c ) {
console.log( 'Ho', a, b, c )
}
function letsGo( a, b, c ) {
console.log( 'Lets go', a, b, c )
}
// bind listeners
emitter.on( 'rock', hey )
emitter.once( 'rock', ho )
// trigger letsGo once
emitter.on( 'rock', letsGo )
// emit event
emitter.emitEvent( 'rock', [ 1, 2, 3 ] )
// => 'Hey', 1, 2, 3
// => 'Ho', 1, 2, 3
// => 'Lets go', 1, 2, 3
// unbind
emitter.off( 'rock', ho )
emitter.emitEvent( 'rock', [ 4, 5, 6 ] )
// => 'Hey' 4, 5, 6
```
## License
EvEmitter is released under the [MIT License](http://desandro.mit-license.org/). Have at it.

View file

@ -0,0 +1,28 @@
{
"name": "ev-emitter",
"main": "ev-emitter.js",
"homepage": "https://github.com/metafizzy/ev-emitter",
"authors": [
"David DeSandro <desandrocodes@gmail.com>"
],
"description": "lil' event emitter",
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"event",
"emitter",
"pubsub"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"sandbox"
]
}

View file

@ -0,0 +1,109 @@
/**
* EvEmitter v1.0.3
* Lil' event emitter
* MIT License
*/
/* jshint unused: true, undef: true, strict: true */
( function( global, factory ) {
// universal module definition
/* jshint strict: false */ /* globals define, module, window */
if ( typeof define == 'function' && define.amd ) {
// AMD - RequireJS
define( factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS - Browserify, Webpack
module.exports = factory();
} else {
// Browser globals
global.EvEmitter = factory();
}
}( typeof window != 'undefined' ? window : this, function() {
"use strict";
function EvEmitter() {}
var proto = EvEmitter.prototype;
proto.on = function( eventName, listener ) {
if ( !eventName || !listener ) {
return;
}
// set events hash
var events = this._events = this._events || {};
// set listeners array
var listeners = events[ eventName ] = events[ eventName ] || [];
// only add once
if ( listeners.indexOf( listener ) == -1 ) {
listeners.push( listener );
}
return this;
};
proto.once = function( eventName, listener ) {
if ( !eventName || !listener ) {
return;
}
// add event
this.on( eventName, listener );
// set once flag
// set onceEvents hash
var onceEvents = this._onceEvents = this._onceEvents || {};
// set onceListeners object
var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
// set flag
onceListeners[ listener ] = true;
return this;
};
proto.off = function( eventName, listener ) {
var listeners = this._events && this._events[ eventName ];
if ( !listeners || !listeners.length ) {
return;
}
var index = listeners.indexOf( listener );
if ( index != -1 ) {
listeners.splice( index, 1 );
}
return this;
};
proto.emitEvent = function( eventName, args ) {
var listeners = this._events && this._events[ eventName ];
if ( !listeners || !listeners.length ) {
return;
}
var i = 0;
var listener = listeners[i];
args = args || [];
// once stuff
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
while ( listener ) {
var isOnce = onceListeners && onceListeners[ listener ];
if ( isOnce ) {
// remove listener
// remove before trigger to prevent recursion
this.off( eventName, listener );
// unset once flag
delete onceListeners[ listener ];
}
// trigger listener
listener.apply( this, args );
// get next listener
i += isOnce ? 0 : 1;
listener = listeners[i];
}
return this;
};
return EvEmitter;
}));

View file

@ -0,0 +1,27 @@
{
"name": "ev-emitter",
"version": "1.0.3",
"description": "lil' event emitter",
"main": "ev-emitter.js",
"scripts": {
"test": "mocha test/test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/metafizzy/ev-emitter.git"
},
"keywords": [
"event",
"emitter",
"pubsub"
],
"author": "David DeSandro",
"license": "MIT",
"bugs": {
"url": "https://github.com/metafizzy/ev-emitter/issues"
},
"homepage": "https://github.com/metafizzy/ev-emitter#readme",
"directories": {
"test": "test"
}
}

View file

@ -0,0 +1,64 @@
# Fizzy UI utils
UI utility & helper functions
Used in [Flickity](http://flickity.metafizzy.co), [Isotope](http://isotope.metafizzy.co), [Masonry](http://masonry.desandro.com), [Draggabilly](http://draggabilly.desandro.com)
## Install
Bower: `bower install fizzy-ui-utils --save`
npm: `npm install fizzy-ui-utils --save`
## API
``` js
// fizzyUIUtils is the browser global
var utils = fizzyUIUtils;
// ---- ---- //
utils.extend( a, b )
// extend object
utils.modulo( num, div )
// num [modulo] div
utils.makeArray( obj )
// make array from object
utils.removeFrom( ary, obj )
// remove object from array
utils.getParent( elem, selector )
// get parent element of an element, given a selector string
utils.getQueryElement( elem )
// if elem is a string, use it as a selector and return element
Class.prototype.handleEvent = utils.handleEvent;
// enable Class.onclick when element.addEventListener( 'click', this, false )
utils.filterFindElements( elems, selector )
// iterate through elems, filter and find all elements that match selector
utils.debounceMethod( Class, methodName, threhold )
// debounce a class method
utils.docReady( callback )
// trigger callback on document ready
utils.toDashed( str )
// 'camelCaseString' -> 'camel-case-string'
utils.htmlInit( Class, namespace )
// on document ready, initialize Class on every element
// that matches js-namespace
// pass in JSON options from element's data-options-namespace attribute
```
---
[MIT license](http://desandro.mit-license.org/). Have at it.
By [Metafizzy](http://metafizzy.co)

View file

@ -0,0 +1,32 @@
{
"name": "fizzy-ui-utils",
"authors": [
"David DeSandro"
],
"description": "UI utilities",
"main": "utils.js",
"dependencies": {
"desandro-matches-selector": "~2.0.0"
},
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"utility",
"ui"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"package.json"
],
"devDependencies": {
"qunit": "~1.20.0"
}
}

View file

@ -0,0 +1,237 @@
/**
* Fizzy UI utils v2.0.3
* MIT license
*/
/*jshint browser: true, undef: true, unused: true, strict: true */
( function( window, factory ) {
// universal module definition
/*jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'desandro-matches-selector/matches-selector'
], function( matchesSelector ) {
return factory( window, matchesSelector );
});
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('desandro-matches-selector')
);
} else {
// browser global
window.fizzyUIUtils = factory(
window,
window.matchesSelector
);
}
}( window, function factory( window, matchesSelector ) {
'use strict';
var utils = {};
// ----- extend ----- //
// extends objects
utils.extend = function( a, b ) {
for ( var prop in b ) {
a[ prop ] = b[ prop ];
}
return a;
};
// ----- modulo ----- //
utils.modulo = function( num, div ) {
return ( ( num % div ) + div ) % div;
};
// ----- makeArray ----- //
// turn element or nodeList into an array
utils.makeArray = function( obj ) {
var ary = [];
if ( Array.isArray( obj ) ) {
// use object if already an array
ary = obj;
} else if ( obj && typeof obj.length == 'number' ) {
// convert nodeList to array
for ( var i=0; i < obj.length; i++ ) {
ary.push( obj[i] );
}
} else {
// array of single index
ary.push( obj );
}
return ary;
};
// ----- removeFrom ----- //
utils.removeFrom = function( ary, obj ) {
var index = ary.indexOf( obj );
if ( index != -1 ) {
ary.splice( index, 1 );
}
};
// ----- getParent ----- //
utils.getParent = function( elem, selector ) {
while ( elem != document.body ) {
elem = elem.parentNode;
if ( matchesSelector( elem, selector ) ) {
return elem;
}
}
};
// ----- getQueryElement ----- //
// use element as selector string
utils.getQueryElement = function( elem ) {
if ( typeof elem == 'string' ) {
return document.querySelector( elem );
}
return elem;
};
// ----- handleEvent ----- //
// enable .ontype to trigger from .addEventListener( elem, 'type' )
utils.handleEvent = function( event ) {
var method = 'on' + event.type;
if ( this[ method ] ) {
this[ method ]( event );
}
};
// ----- filterFindElements ----- //
utils.filterFindElements = function( elems, selector ) {
// make array of elems
elems = utils.makeArray( elems );
var ffElems = [];
elems.forEach( function( elem ) {
// check that elem is an actual element
if ( !( elem instanceof HTMLElement ) ) {
return;
}
// add elem if no selector
if ( !selector ) {
ffElems.push( elem );
return;
}
// filter & find items if we have a selector
// filter
if ( matchesSelector( elem, selector ) ) {
ffElems.push( elem );
}
// find children
var childElems = elem.querySelectorAll( selector );
// concat childElems to filterFound array
for ( var i=0; i < childElems.length; i++ ) {
ffElems.push( childElems[i] );
}
});
return ffElems;
};
// ----- debounceMethod ----- //
utils.debounceMethod = function( _class, methodName, threshold ) {
// original method
var method = _class.prototype[ methodName ];
var timeoutName = methodName + 'Timeout';
_class.prototype[ methodName ] = function() {
var timeout = this[ timeoutName ];
if ( timeout ) {
clearTimeout( timeout );
}
var args = arguments;
var _this = this;
this[ timeoutName ] = setTimeout( function() {
method.apply( _this, args );
delete _this[ timeoutName ];
}, threshold || 100 );
};
};
// ----- docReady ----- //
utils.docReady = function( callback ) {
var readyState = document.readyState;
if ( readyState == 'complete' || readyState == 'interactive' ) {
// do async to allow for other scripts to run. metafizzy/flickity#441
setTimeout( callback );
} else {
document.addEventListener( 'DOMContentLoaded', callback );
}
};
// ----- htmlInit ----- //
// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
utils.toDashed = function( str ) {
return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
return $1 + '-' + $2;
}).toLowerCase();
};
var console = window.console;
/**
* allow user to initialize classes via [data-namespace] or .js-namespace class
* htmlInit( Widget, 'widgetName' )
* options are parsed from data-namespace-options
*/
utils.htmlInit = function( WidgetClass, namespace ) {
utils.docReady( function() {
var dashedNamespace = utils.toDashed( namespace );
var dataAttr = 'data-' + dashedNamespace;
var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
var elems = utils.makeArray( dataAttrElems )
.concat( utils.makeArray( jsDashElems ) );
var dataOptionsAttr = dataAttr + '-options';
var jQuery = window.jQuery;
elems.forEach( function( elem ) {
var attr = elem.getAttribute( dataAttr ) ||
elem.getAttribute( dataOptionsAttr );
var options;
try {
options = attr && JSON.parse( attr );
} catch ( error ) {
// log error, do not initialize
if ( console ) {
console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
': ' + error );
}
return;
}
// initialize
var instance = new WidgetClass( elem, options );
// make available via $().data('namespace')
if ( jQuery ) {
jQuery.data( elem, namespace, instance );
}
});
});
};
// ----- ----- //
return utils;
}));

View file

@ -0,0 +1,37 @@
# getSize
Get the size of elements.
``` js
var size = getSize( elem );
// elem can be an element
var size = getSize( document.querySelector('#selector') )
// elem can be a string, used as a query selector
var size = getSize('#selector')
```
Returns an object with: `width`, `height`, `innerWidth/Height`, `outerWidth/Height`, `paddingLeft/Top/Right/Bottom`, `marginLeft/Top/Right/Bottom`, `borderLeft/Top/Right/BottomWidth` and `isBorderBox`.
Browser support: IE10+, Android 4.0+, iOS 5+, and modern browsers
## Install
Install with [Bower](http://bower.io): `bower install get-size`
Install with npm: `npm install get-size`
## Firefox hidden iframe bug
[Firefox has an old bug](https://bugzilla.mozilla.org/show_bug.cgi?id=548397) that occurs within iframes that are hidden with `display: none`. To resolve this, you can use alternate CSS to hide the iframe off-screen, with out `display: none`.
``` css
.hide-iframe {
visibility: hidden;
position: absolute;
left: -999em;
}
```
## MIT License
getSize is released under the [MIT License](http://desandro.mit-license.org/).

View file

@ -0,0 +1,37 @@
{
"name": "get-size",
"version": "2.0.2",
"main": "get-size.js",
"description": "measures element size",
"dependencies": {
},
"devDependencies": {
"qunit": "~1.10"
},
"ignore": [
"test/",
"**/.*",
"package.json",
"node_modules",
"bower_components",
"test",
"tests",
"sandbox.html"
],
"homepage": "https://github.com/desandro/get-size",
"authors": [
"David DeSandro <desandrocodes@gmail.com>"
],
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"size",
"dom",
"width",
"height"
],
"license": "MIT"
}

View file

@ -0,0 +1,209 @@
/*!
* getSize v2.0.2
* measure size of elements
* MIT license
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false, module: false, console: false */
( function( window, factory ) {
'use strict';
if ( typeof define == 'function' && define.amd ) {
// AMD
define( function() {
return factory();
});
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory();
} else {
// browser global
window.getSize = factory();
}
})( window, function factory() {
'use strict';
// -------------------------- helpers -------------------------- //
// get a number from a string, not a percentage
function getStyleSize( value ) {
var num = parseFloat( value );
// not a percent like '100%', and a number
var isValid = value.indexOf('%') == -1 && !isNaN( num );
return isValid && num;
}
function noop() {}
var logError = typeof console == 'undefined' ? noop :
function( message ) {
console.error( message );
};
// -------------------------- measurements -------------------------- //
var measurements = [
'paddingLeft',
'paddingRight',
'paddingTop',
'paddingBottom',
'marginLeft',
'marginRight',
'marginTop',
'marginBottom',
'borderLeftWidth',
'borderRightWidth',
'borderTopWidth',
'borderBottomWidth'
];
var measurementsLength = measurements.length;
function getZeroSize() {
var size = {
width: 0,
height: 0,
innerWidth: 0,
innerHeight: 0,
outerWidth: 0,
outerHeight: 0
};
for ( var i=0; i < measurementsLength; i++ ) {
var measurement = measurements[i];
size[ measurement ] = 0;
}
return size;
}
// -------------------------- getStyle -------------------------- //
/**
* getStyle, get style of element, check for Firefox bug
* https://bugzilla.mozilla.org/show_bug.cgi?id=548397
*/
function getStyle( elem ) {
var style = getComputedStyle( elem );
if ( !style ) {
logError( 'Style returned ' + style +
'. Are you running this code in a hidden iframe on Firefox? ' +
'See http://bit.ly/getsizebug1' );
}
return style;
}
// -------------------------- setup -------------------------- //
var isSetup = false;
var isBoxSizeOuter;
/**
* setup
* check isBoxSizerOuter
* do on first getSize() rather than on page load for Firefox bug
*/
function setup() {
// setup once
if ( isSetup ) {
return;
}
isSetup = true;
// -------------------------- box sizing -------------------------- //
/**
* WebKit measures the outer-width on style.width on border-box elems
* IE & Firefox<29 measures the inner-width
*/
var div = document.createElement('div');
div.style.width = '200px';
div.style.padding = '1px 2px 3px 4px';
div.style.borderStyle = 'solid';
div.style.borderWidth = '1px 2px 3px 4px';
div.style.boxSizing = 'border-box';
var body = document.body || document.documentElement;
body.appendChild( div );
var style = getStyle( div );
getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
body.removeChild( div );
}
// -------------------------- getSize -------------------------- //
function getSize( elem ) {
setup();
// use querySeletor if elem is string
if ( typeof elem == 'string' ) {
elem = document.querySelector( elem );
}
// do not proceed on non-objects
if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
return;
}
var style = getStyle( elem );
// if hidden, everything is 0
if ( style.display == 'none' ) {
return getZeroSize();
}
var size = {};
size.width = elem.offsetWidth;
size.height = elem.offsetHeight;
var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
// get all measurements
for ( var i=0; i < measurementsLength; i++ ) {
var measurement = measurements[i];
var value = style[ measurement ];
var num = parseFloat( value );
// any 'auto', 'medium' value will be 0
size[ measurement ] = !isNaN( num ) ? num : 0;
}
var paddingWidth = size.paddingLeft + size.paddingRight;
var paddingHeight = size.paddingTop + size.paddingBottom;
var marginWidth = size.marginLeft + size.marginRight;
var marginHeight = size.marginTop + size.marginBottom;
var borderWidth = size.borderLeftWidth + size.borderRightWidth;
var borderHeight = size.borderTopWidth + size.borderBottomWidth;
var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
// overwrite width and height if we can get it from style
var styleWidth = getStyleSize( style.width );
if ( styleWidth !== false ) {
size.width = styleWidth +
// add padding and border unless it's already including it
( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
}
var styleHeight = getStyleSize( style.height );
if ( styleHeight !== false ) {
size.height = styleHeight +
// add padding and border unless it's already including it
( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
}
size.innerWidth = size.width - ( paddingWidth + borderWidth );
size.innerHeight = size.height - ( paddingHeight + borderHeight );
size.outerWidth = size.width + marginWidth;
size.outerHeight = size.height + marginHeight;
return size;
}
return getSize;
});

View file

@ -0,0 +1,85 @@
# Isotope
_Filter & sort magical layouts_
See [isotope.metafizzy.co](http://isotope.metafizzy.co) for complete docs and demos.
## Install
### Download
+ [isotope.pkgd.js](https://npmcdn.com/isotope-layout@3/dist/isotope.pkgd.js) un-minified, or
+ [isotope.pkgd.min.js](https://npmcdn.com/isotope-layout@3/dist/isotope.pkgd.min.js) minified
### CDN
Link directly to Isotope files on [npmcdn](https://npmcdn.com).
``` html
<script src="https://npmcdn.com/isotope-layout@3.0/dist/isotope.pkgd.min.js"></script>
<!-- or -->
<script src="https://npmcdn.com/isotope-layout@3.0/dist/isotope.pkgd.js"></script>
```
### Package managers
npm: `npm install isotope-layout --save`
Bower: `bower install isotope --save`
## License
### Commercial license
If you want to use Isotope to develop commercial sites, themes, projects, and applications, the Commercial license is the appropriate license. With this option, your source code is kept proprietary. Purchase an Isotope Commercial License at [isotope.metafizzy.co](http://isotope.metafizzy.co/#commercial-license)
### Open source license
If you are creating an open source application under a license compatible with the [GNU GPL license v3](https://www.gnu.org/licenses/gpl-3.0.html), you may use Isotope under the terms of the GPLv3.
[Read more about Isotope's license](http://isotope.metafizzy.co/license.html).
## Initialize
With jQuery
``` js
$('.grid').isotope({
// options...
itemSelector: '.grid-item',
masonry: {
columnWidth: 200
}
});
```
With vanilla JavaScript
``` js
// vanilla JS
var grid = document.querySelector('.grid');
var iso = new Isotope( grid, {
// options...
itemSelector: '.grid-item',
masonry: {
columnWidth: 200
}
});
```
With HTML
Add a `data-isotope` attribute to your element. Options can be set in JSON in the value.
``` html
<div class="grid"
data-isotope='{ "itemSelector": ".grid-item", "masonry": { "columnWidth": 200 } }'>
<div class="grid-item"></div>
<div class="grid-item"></div>
...
</div>
```
* * *
By [Metafizzy](http://metafizzy.co), 20102016

View file

@ -0,0 +1,44 @@
{
"name": "isotope",
"description": "Filter and sort magical layouts",
"main": "js/isotope.js",
"dependencies": {
"desandro-matches-selector": "^2.0.0",
"fizzy-ui-utils": "^2.0.0",
"get-size": "^2.0.0",
"masonry": "^4.1.0",
"outlayer": "^2.1.0"
},
"devDependencies": {
"jquery": "2 < 4",
"jquery-bridget": "^2",
"qunit": "^1.15"
},
"ignore": [
"test/",
"sandbox/",
"**/.*",
"package.json",
"notes.md",
"node_modules",
"bower_components",
"test",
"tests"
],
"homepage": "http://isotope.metafizzy.co",
"authors": [
"David DeSandro"
],
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"filter",
"sort",
"masonry",
"jquery-plugin"
],
"license": "GPL-3.0"
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,142 @@
/*jshint node: true, strict: false */
var fs = require('fs');
var gulp = require('gulp');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
// ----- hint ----- //
var jshint = require('gulp-jshint');
gulp.task( 'hint-js', function() {
return gulp.src('js/*.js')
.pipe( jshint() )
.pipe( jshint.reporter('default') );
});
gulp.task( 'hint-test', function() {
return gulp.src('test/unit/*.js')
.pipe( jshint() )
.pipe( jshint.reporter('default') );
});
gulp.task( 'hint-task', function() {
return gulp.src('gulpfile.js')
.pipe( jshint() )
.pipe( jshint.reporter('default') );
});
var jsonlint = require('gulp-json-lint');
gulp.task( 'jsonlint', function() {
return gulp.src( '*.json' )
.pipe( jsonlint() )
.pipe( jsonlint.report('verbose') );
});
gulp.task( 'hint', [ 'hint-js', 'hint-test', 'hint-task', 'jsonlint' ]);
// -------------------------- make pkgd -------------------------- //
// regex for banner comment
var reBannerComment = new RegExp('^\\s*(?:\\/\\*[\\s\\S]*?\\*\\/)\\s*');
function getBanner() {
var src = fs.readFileSync( 'js/isotope.js', 'utf8' );
var matches = src.match( reBannerComment );
var banner = matches[0].replace( 'Isotope', 'Isotope PACKAGED' );
return banner;
}
function addBanner( str ) {
return replace( /^/, str );
}
var rjsOptimize = require('gulp-requirejs-optimize');
gulp.task( 'requirejs', function() {
var definitionRE = /define\(\s*'isotope\/isotope'(.|\n)+\],/;
var banner = getBanner();
// HACK src is not needed
// should refactor rjsOptimize to produce src
return gulp.src('js/isotope.js')
.pipe( rjsOptimize({
baseUrl: 'bower_components',
optimize: 'none',
include: [
'jquery-bridget/jquery-bridget',
'isotope/isotope'
],
paths: {
isotope: '../js/',
jquery: 'empty:'
}
}) )
// munge AMD definition
.pipe( replace( definitionRE, function( definition ) {
// remove named module
return definition.replace( "'isotope/isotope',", '' )
// use explicit file paths, './item' -> 'isotope/js/item'
.replace( /'.\//g, "'isotope/js/" );
}) )
.pipe( replace( "define( 'isotope/", "define( 'isotope/js/" ) )
// add banner
.pipe( addBanner( banner ) )
.pipe( rename('isotope.pkgd.js') )
.pipe( gulp.dest('dist') );
});
// ----- uglify ----- //
var uglify = require('gulp-uglify');
gulp.task( 'uglify', [ 'requirejs' ], function() {
var banner = getBanner();
gulp.src('dist/isotope.pkgd.js')
.pipe( uglify() )
// add banner
.pipe( addBanner( banner ) )
.pipe( rename('isotope.pkgd.min.js') )
.pipe( gulp.dest('dist') );
});
// ----- version ----- //
// set version in source files
var minimist = require('minimist');
var gutil = require('gulp-util');
var chalk = require('chalk');
// use gulp version -t 1.2.3
gulp.task( 'version', function() {
var args = minimist( process.argv.slice(3) );
var version = args.t;
if ( !version || !/^\d\.\d+\.\d+/.test( version ) ) {
gutil.log( 'invalid version: ' + chalk.red( version ) );
return;
}
gutil.log( 'ticking version to ' + chalk.green( version ) );
gulp.src('js/isotope.js')
.pipe( replace( /Packery v\d\.\d+\.\d+/, 'Isotope v' + version ) )
.pipe( gulp.dest('js') );
gulp.src( [ 'package.json' ] )
.pipe( replace( /"version": "\d\.\d+\.\d+"/, '"version": "' + version + '"' ) )
.pipe( gulp.dest('.') );
// replace CDN links in README
var minorVersion = version.match( /^\d\.\d+/ )[0];
gulp.src('README.md')
.pipe( replace( /isotope-layout@\d\.\d+/g, 'isotope-layout@' + minorVersion ))
.pipe( gulp.dest('.') );
});
// ----- default ----- //
gulp.task( 'default', [
'hint',
'uglify'
]);

View file

@ -0,0 +1,613 @@
/*!
* Isotope v3.0.1
*
* Licensed GPLv3 for open source use
* or Isotope Commercial License for commercial use
*
* http://isotope.metafizzy.co
* Copyright 2016 Metafizzy
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'outlayer/outlayer',
'get-size/get-size',
'desandro-matches-selector/matches-selector',
'fizzy-ui-utils/utils',
'./item',
'./layout-mode',
// include default layout modes
'./layout-modes/masonry',
'./layout-modes/fit-rows',
'./layout-modes/vertical'
],
function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
});
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('outlayer'),
require('get-size'),
require('desandro-matches-selector'),
require('fizzy-ui-utils'),
require('./item'),
require('./layout-mode'),
// include default layout modes
require('./layout-modes/masonry'),
require('./layout-modes/fit-rows'),
require('./layout-modes/vertical')
);
} else {
// browser global
window.Isotope = factory(
window,
window.Outlayer,
window.getSize,
window.matchesSelector,
window.fizzyUIUtils,
window.Isotope.Item,
window.Isotope.LayoutMode
);
}
}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
Item, LayoutMode ) {
'use strict';
// -------------------------- vars -------------------------- //
var jQuery = window.jQuery;
// -------------------------- helpers -------------------------- //
var trim = String.prototype.trim ?
function( str ) {
return str.trim();
} :
function( str ) {
return str.replace( /^\s+|\s+$/g, '' );
};
// -------------------------- isotopeDefinition -------------------------- //
// create an Outlayer layout class
var Isotope = Outlayer.create( 'isotope', {
layoutMode: 'masonry',
isJQueryFiltering: true,
sortAscending: true
});
Isotope.Item = Item;
Isotope.LayoutMode = LayoutMode;
var proto = Isotope.prototype;
proto._create = function() {
this.itemGUID = 0;
// functions that sort items
this._sorters = {};
this._getSorters();
// call super
Outlayer.prototype._create.call( this );
// create layout modes
this.modes = {};
// start filteredItems with all items
this.filteredItems = this.items;
// keep of track of sortBys
this.sortHistory = [ 'original-order' ];
// create from registered layout modes
for ( var name in LayoutMode.modes ) {
this._initLayoutMode( name );
}
};
proto.reloadItems = function() {
// reset item ID counter
this.itemGUID = 0;
// call super
Outlayer.prototype.reloadItems.call( this );
};
proto._itemize = function() {
var items = Outlayer.prototype._itemize.apply( this, arguments );
// assign ID for original-order
for ( var i=0; i < items.length; i++ ) {
var item = items[i];
item.id = this.itemGUID++;
}
this._updateItemsSortData( items );
return items;
};
// -------------------------- layout -------------------------- //
proto._initLayoutMode = function( name ) {
var Mode = LayoutMode.modes[ name ];
// set mode options
// HACK extend initial options, back-fill in default options
var initialOpts = this.options[ name ] || {};
this.options[ name ] = Mode.options ?
utils.extend( Mode.options, initialOpts ) : initialOpts;
// init layout mode instance
this.modes[ name ] = new Mode( this );
};
proto.layout = function() {
// if first time doing layout, do all magic
if ( !this._isLayoutInited && this._getOption('initLayout') ) {
this.arrange();
return;
}
this._layout();
};
// private method to be used in layout() & magic()
proto._layout = function() {
// don't animate first layout
var isInstant = this._getIsInstant();
// layout flow
this._resetLayout();
this._manageStamps();
this.layoutItems( this.filteredItems, isInstant );
// flag for initalized
this._isLayoutInited = true;
};
// filter + sort + layout
proto.arrange = function( opts ) {
// set any options pass
this.option( opts );
this._getIsInstant();
// filter, sort, and layout
// filter
var filtered = this._filter( this.items );
this.filteredItems = filtered.matches;
this._bindArrangeComplete();
if ( this._isInstant ) {
this._noTransition( this._hideReveal, [ filtered ] );
} else {
this._hideReveal( filtered );
}
this._sort();
this._layout();
};
// alias to _init for main plugin method
proto._init = proto.arrange;
proto._hideReveal = function( filtered ) {
this.reveal( filtered.needReveal );
this.hide( filtered.needHide );
};
// HACK
// Don't animate/transition first layout
// Or don't animate/transition other layouts
proto._getIsInstant = function() {
var isLayoutInstant = this._getOption('layoutInstant');
var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
!this._isLayoutInited;
this._isInstant = isInstant;
return isInstant;
};
// listen for layoutComplete, hideComplete and revealComplete
// to trigger arrangeComplete
proto._bindArrangeComplete = function() {
// listen for 3 events to trigger arrangeComplete
var isLayoutComplete, isHideComplete, isRevealComplete;
var _this = this;
function arrangeParallelCallback() {
if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
_this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
}
}
this.once( 'layoutComplete', function() {
isLayoutComplete = true;
arrangeParallelCallback();
});
this.once( 'hideComplete', function() {
isHideComplete = true;
arrangeParallelCallback();
});
this.once( 'revealComplete', function() {
isRevealComplete = true;
arrangeParallelCallback();
});
};
// -------------------------- filter -------------------------- //
proto._filter = function( items ) {
var filter = this.options.filter;
filter = filter || '*';
var matches = [];
var hiddenMatched = [];
var visibleUnmatched = [];
var test = this._getFilterTest( filter );
// test each item
for ( var i=0; i < items.length; i++ ) {
var item = items[i];
if ( item.isIgnored ) {
continue;
}
// add item to either matched or unmatched group
var isMatched = test( item );
// item.isFilterMatched = isMatched;
// add to matches if its a match
if ( isMatched ) {
matches.push( item );
}
// add to additional group if item needs to be hidden or revealed
if ( isMatched && item.isHidden ) {
hiddenMatched.push( item );
} else if ( !isMatched && !item.isHidden ) {
visibleUnmatched.push( item );
}
}
// return collections of items to be manipulated
return {
matches: matches,
needReveal: hiddenMatched,
needHide: visibleUnmatched
};
};
// get a jQuery, function, or a matchesSelector test given the filter
proto._getFilterTest = function( filter ) {
if ( jQuery && this.options.isJQueryFiltering ) {
// use jQuery
return function( item ) {
return jQuery( item.element ).is( filter );
};
}
if ( typeof filter == 'function' ) {
// use filter as function
return function( item ) {
return filter( item.element );
};
}
// default, use filter as selector string
return function( item ) {
return matchesSelector( item.element, filter );
};
};
// -------------------------- sorting -------------------------- //
/**
* @params {Array} elems
* @public
*/
proto.updateSortData = function( elems ) {
// get items
var items;
if ( elems ) {
elems = utils.makeArray( elems );
items = this.getItems( elems );
} else {
// update all items if no elems provided
items = this.items;
}
this._getSorters();
this._updateItemsSortData( items );
};
proto._getSorters = function() {
var getSortData = this.options.getSortData;
for ( var key in getSortData ) {
var sorter = getSortData[ key ];
this._sorters[ key ] = mungeSorter( sorter );
}
};
/**
* @params {Array} items - of Isotope.Items
* @private
*/
proto._updateItemsSortData = function( items ) {
// do not update if no items
var len = items && items.length;
for ( var i=0; len && i < len; i++ ) {
var item = items[i];
item.updateSortData();
}
};
// ----- munge sorter ----- //
// encapsulate this, as we just need mungeSorter
// other functions in here are just for munging
var mungeSorter = ( function() {
// add a magic layer to sorters for convienent shorthands
// `.foo-bar` will use the text of .foo-bar querySelector
// `[foo-bar]` will use attribute
// you can also add parser
// `.foo-bar parseInt` will parse that as a number
function mungeSorter( sorter ) {
// if not a string, return function or whatever it is
if ( typeof sorter != 'string' ) {
return sorter;
}
// parse the sorter string
var args = trim( sorter ).split(' ');
var query = args[0];
// check if query looks like [an-attribute]
var attrMatch = query.match( /^\[(.+)\]$/ );
var attr = attrMatch && attrMatch[1];
var getValue = getValueGetter( attr, query );
// use second argument as a parser
var parser = Isotope.sortDataParsers[ args[1] ];
// parse the value, if there was a parser
sorter = parser ? function( elem ) {
return elem && parser( getValue( elem ) );
} :
// otherwise just return value
function( elem ) {
return elem && getValue( elem );
};
return sorter;
}
// get an attribute getter, or get text of the querySelector
function getValueGetter( attr, query ) {
// if query looks like [foo-bar], get attribute
if ( attr ) {
return function getAttribute( elem ) {
return elem.getAttribute( attr );
};
}
// otherwise, assume its a querySelector, and get its text
return function getChildText( elem ) {
var child = elem.querySelector( query );
return child && child.textContent;
};
}
return mungeSorter;
})();
// parsers used in getSortData shortcut strings
Isotope.sortDataParsers = {
'parseInt': function( val ) {
return parseInt( val, 10 );
},
'parseFloat': function( val ) {
return parseFloat( val );
}
};
// ----- sort method ----- //
// sort filteredItem order
proto._sort = function() {
var sortByOpt = this.options.sortBy;
if ( !sortByOpt ) {
return;
}
// concat all sortBy and sortHistory
var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
// sort magic
var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
this.filteredItems.sort( itemSorter );
// keep track of sortBy History
if ( sortByOpt != this.sortHistory[0] ) {
// add to front, oldest goes in last
this.sortHistory.unshift( sortByOpt );
}
};
// returns a function used for sorting
function getItemSorter( sortBys, sortAsc ) {
return function sorter( itemA, itemB ) {
// cycle through all sortKeys
for ( var i = 0; i < sortBys.length; i++ ) {
var sortBy = sortBys[i];
var a = itemA.sortData[ sortBy ];
var b = itemB.sortData[ sortBy ];
if ( a > b || a < b ) {
// if sortAsc is an object, use the value given the sortBy key
var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
var direction = isAscending ? 1 : -1;
return ( a > b ? 1 : -1 ) * direction;
}
}
return 0;
};
}
// -------------------------- methods -------------------------- //
// get layout mode
proto._mode = function() {
var layoutMode = this.options.layoutMode;
var mode = this.modes[ layoutMode ];
if ( !mode ) {
// TODO console.error
throw new Error( 'No layout mode: ' + layoutMode );
}
// HACK sync mode's options
// any options set after init for layout mode need to be synced
mode.options = this.options[ layoutMode ];
return mode;
};
proto._resetLayout = function() {
// trigger original reset layout
Outlayer.prototype._resetLayout.call( this );
this._mode()._resetLayout();
};
proto._getItemLayoutPosition = function( item ) {
return this._mode()._getItemLayoutPosition( item );
};
proto._manageStamp = function( stamp ) {
this._mode()._manageStamp( stamp );
};
proto._getContainerSize = function() {
return this._mode()._getContainerSize();
};
proto.needsResizeLayout = function() {
return this._mode().needsResizeLayout();
};
// -------------------------- adding & removing -------------------------- //
// HEADS UP overwrites default Outlayer appended
proto.appended = function( elems ) {
var items = this.addItems( elems );
if ( !items.length ) {
return;
}
// filter, layout, reveal new items
var filteredItems = this._filterRevealAdded( items );
// add to filteredItems
this.filteredItems = this.filteredItems.concat( filteredItems );
};
// HEADS UP overwrites default Outlayer prepended
proto.prepended = function( elems ) {
var items = this._itemize( elems );
if ( !items.length ) {
return;
}
// start new layout
this._resetLayout();
this._manageStamps();
// filter, layout, reveal new items
var filteredItems = this._filterRevealAdded( items );
// layout previous items
this.layoutItems( this.filteredItems );
// add to items and filteredItems
this.filteredItems = filteredItems.concat( this.filteredItems );
this.items = items.concat( this.items );
};
proto._filterRevealAdded = function( items ) {
var filtered = this._filter( items );
this.hide( filtered.needHide );
// reveal all new items
this.reveal( filtered.matches );
// layout new items, no transition
this.layoutItems( filtered.matches, true );
return filtered.matches;
};
/**
* Filter, sort, and layout newly-appended item elements
* @param {Array or NodeList or Element} elems
*/
proto.insert = function( elems ) {
var items = this.addItems( elems );
if ( !items.length ) {
return;
}
// append item elements
var i, item;
var len = items.length;
for ( i=0; i < len; i++ ) {
item = items[i];
this.element.appendChild( item.element );
}
// filter new stuff
var filteredInsertItems = this._filter( items ).matches;
// set flag
for ( i=0; i < len; i++ ) {
items[i].isLayoutInstant = true;
}
this.arrange();
// reset flag
for ( i=0; i < len; i++ ) {
delete items[i].isLayoutInstant;
}
this.reveal( filteredInsertItems );
};
var _remove = proto.remove;
proto.remove = function( elems ) {
elems = utils.makeArray( elems );
var removeItems = this.getItems( elems );
// do regular thing
_remove.call( this, elems );
// bail if no items to remove
var len = removeItems && removeItems.length;
// remove elems from filteredItems
for ( var i=0; len && i < len; i++ ) {
var item = removeItems[i];
// remove item from collection
utils.removeFrom( this.filteredItems, item );
}
};
proto.shuffle = function() {
// update random sortData
for ( var i=0; i < this.items.length; i++ ) {
var item = this.items[i];
item.sortData.random = Math.random();
}
this.options.sortBy = 'random';
this._sort();
this._layout();
};
/**
* trigger fn without transition
* kind of hacky to have this in the first place
* @param {Function} fn
* @param {Array} args
* @returns ret
* @private
*/
proto._noTransition = function( fn, args ) {
// save transitionDuration before disabling
var transitionDuration = this.options.transitionDuration;
// disable transition
this.options.transitionDuration = 0;
// do it
var returnValue = fn.apply( this, args );
// re-enable transition for reveal
this.options.transitionDuration = transitionDuration;
return returnValue;
};
// ----- helper methods ----- //
/**
* getter method for getting filtered item elements
* @returns {Array} elems - collection of item elements
*/
proto.getFilteredItemElements = function() {
return this.filteredItems.map( function( item ) {
return item.element;
});
};
// ----- ----- //
return Isotope;
}));

View file

@ -0,0 +1,77 @@
/**
* Isotope Item
**/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'outlayer/outlayer'
],
factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('outlayer')
);
} else {
// browser global
window.Isotope = window.Isotope || {};
window.Isotope.Item = factory(
window.Outlayer
);
}
}( window, function factory( Outlayer ) {
'use strict';
// -------------------------- Item -------------------------- //
// sub-class Outlayer Item
function Item() {
Outlayer.Item.apply( this, arguments );
}
var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
var _create = proto._create;
proto._create = function() {
// assign id, used for original-order sorting
this.id = this.layout.itemGUID++;
_create.call( this );
this.sortData = {};
};
proto.updateSortData = function() {
if ( this.isIgnored ) {
return;
}
// default sorters
this.sortData.id = this.id;
// for backward compatibility
this.sortData['original-order'] = this.id;
this.sortData.random = Math.random();
// go thru getSortData obj and apply the sorters
var getSortData = this.layout.options.getSortData;
var sorters = this.layout._sorters;
for ( var key in getSortData ) {
var sorter = sorters[ key ];
this.sortData[ key ] = sorter( this.element, this );
}
};
var _destroy = proto.destroy;
proto.destroy = function() {
// call super
_destroy.apply( this, arguments );
// reset display, #741
this.css({
display: ''
});
};
return Item;
}));

View file

@ -0,0 +1,157 @@
/**
* Isotope LayoutMode
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'get-size/get-size',
'outlayer/outlayer'
],
factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('get-size'),
require('outlayer')
);
} else {
// browser global
window.Isotope = window.Isotope || {};
window.Isotope.LayoutMode = factory(
window.getSize,
window.Outlayer
);
}
}( window, function factory( getSize, Outlayer ) {
'use strict';
// layout mode class
function LayoutMode( isotope ) {
this.isotope = isotope;
// link properties
if ( isotope ) {
this.options = isotope.options[ this.namespace ];
this.element = isotope.element;
this.items = isotope.filteredItems;
this.size = isotope.size;
}
}
var proto = LayoutMode.prototype;
/**
* some methods should just defer to default Outlayer method
* and reference the Isotope instance as `this`
**/
var facadeMethods = [
'_resetLayout',
'_getItemLayoutPosition',
'_manageStamp',
'_getContainerSize',
'_getElementOffset',
'needsResizeLayout',
'_getOption'
];
facadeMethods.forEach( function( methodName ) {
proto[ methodName ] = function() {
return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
};
});
// ----- ----- //
// for horizontal layout modes, check vertical size
proto.needsVerticalResizeLayout = function() {
// don't trigger if size did not change
var size = getSize( this.isotope.element );
// check that this.size and size are there
// IE8 triggers resize on body size change, so they might not be
var hasSizes = this.isotope.size && size;
return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
};
// ----- measurements ----- //
proto._getMeasurement = function() {
this.isotope._getMeasurement.apply( this, arguments );
};
proto.getColumnWidth = function() {
this.getSegmentSize( 'column', 'Width' );
};
proto.getRowHeight = function() {
this.getSegmentSize( 'row', 'Height' );
};
/**
* get columnWidth or rowHeight
* segment: 'column' or 'row'
* size 'Width' or 'Height'
**/
proto.getSegmentSize = function( segment, size ) {
var segmentName = segment + size;
var outerSize = 'outer' + size;
// columnWidth / outerWidth // rowHeight / outerHeight
this._getMeasurement( segmentName, outerSize );
// got rowHeight or columnWidth, we can chill
if ( this[ segmentName ] ) {
return;
}
// fall back to item of first element
var firstItemSize = this.getFirstItemSize();
this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
// or size of container
this.isotope.size[ 'inner' + size ];
};
proto.getFirstItemSize = function() {
var firstItem = this.isotope.filteredItems[0];
return firstItem && firstItem.element && getSize( firstItem.element );
};
// ----- methods that should reference isotope ----- //
proto.layout = function() {
this.isotope.layout.apply( this.isotope, arguments );
};
proto.getSize = function() {
this.isotope.getSize();
this.size = this.isotope.size;
};
// -------------------------- create -------------------------- //
LayoutMode.modes = {};
LayoutMode.create = function( namespace, options ) {
function Mode() {
LayoutMode.apply( this, arguments );
}
Mode.prototype = Object.create( proto );
Mode.prototype.constructor = Mode;
// default options
if ( options ) {
Mode.options = options;
}
Mode.prototype.namespace = namespace;
// register in Isotope
LayoutMode.modes[ namespace ] = Mode;
return Mode;
};
return LayoutMode;
}));

View file

@ -0,0 +1,68 @@
/**
* fitRows layout mode
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'../layout-mode'
],
factory );
} else if ( typeof exports == 'object' ) {
// CommonJS
module.exports = factory(
require('../layout-mode')
);
} else {
// browser global
factory(
window.Isotope.LayoutMode
);
}
}( window, function factory( LayoutMode ) {
'use strict';
var FitRows = LayoutMode.create('fitRows');
var proto = FitRows.prototype;
proto._resetLayout = function() {
this.x = 0;
this.y = 0;
this.maxY = 0;
this._getMeasurement( 'gutter', 'outerWidth' );
};
proto._getItemLayoutPosition = function( item ) {
item.getSize();
var itemWidth = item.size.outerWidth + this.gutter;
// if this element cannot fit in the current row
var containerWidth = this.isotope.size.innerWidth + this.gutter;
if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
this.x = 0;
this.y = this.maxY;
}
var position = {
x: this.x,
y: this.y
};
this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
this.x += itemWidth;
return position;
};
proto._getContainerSize = function() {
return { height: this.maxY };
};
return FitRows;
}));

View file

@ -0,0 +1,74 @@
/*!
* Masonry layout mode
* sub-classes Masonry
* http://masonry.desandro.com
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'../layout-mode',
'masonry/masonry'
],
factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('../layout-mode'),
require('masonry-layout')
);
} else {
// browser global
factory(
window.Isotope.LayoutMode,
window.Masonry
);
}
}( window, function factory( LayoutMode, Masonry ) {
'use strict';
// -------------------------- masonryDefinition -------------------------- //
// create an Outlayer layout class
var MasonryMode = LayoutMode.create('masonry');
var proto = MasonryMode.prototype;
var keepModeMethods = {
_getElementOffset: true,
layout: true,
_getMeasurement: true
};
// inherit Masonry prototype
for ( var method in Masonry.prototype ) {
// do not inherit mode methods
if ( !keepModeMethods[ method ] ) {
proto[ method ] = Masonry.prototype[ method ];
}
}
var measureColumns = proto.measureColumns;
proto.measureColumns = function() {
// set items, used if measuring first item
this.items = this.isotope.filteredItems;
measureColumns.call( this );
};
// point to mode options for fitWidth
var _getOption = proto._getOption;
proto._getOption = function( option ) {
if ( option == 'fitWidth' ) {
return this.options.isFitWidth !== undefined ?
this.options.isFitWidth : this.options.fitWidth;
}
return _getOption.apply( this.isotope, arguments );
};
return MasonryMode;
}));

View file

@ -0,0 +1,54 @@
/**
* vertical layout mode
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'../layout-mode'
],
factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('../layout-mode')
);
} else {
// browser global
factory(
window.Isotope.LayoutMode
);
}
}( window, function factory( LayoutMode ) {
'use strict';
var Vertical = LayoutMode.create( 'vertical', {
horizontalAlignment: 0
});
var proto = Vertical.prototype;
proto._resetLayout = function() {
this.y = 0;
};
proto._getItemLayoutPosition = function( item ) {
item.getSize();
var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
this.options.horizontalAlignment;
var y = this.y;
this.y += item.size.outerHeight;
return { x: x, y: y };
};
proto._getContainerSize = function() {
return { height: this.y };
};
return Vertical;
}));

View file

@ -0,0 +1,80 @@
# Masonry
_Cascading grid layout library_
Masonry works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. Youve probably seen it in use all over the Internet.
See [masonry.desandro.com](http://masonry.desandro.com) for complete docs and demos.
## Install
### Download
+ [masonry.pkgd.js](https://github.com/desandro/masonry/raw/master/dist/masonry.pkgd.js) un-minified, or
+ [masonry.pkgd.min.js](https://github.com/desandro/masonry/raw/master/dist/masonry.pkgd.min.js) minified
### CDN
Link directly to Masonry files on [npmcdn](https://npmcdn.com/).
``` html
<script src="https://npmcdn.com/masonry-layout@4.1/dist/masonry.pkgd.js"></script>
<!-- or -->
<script src="https://npmcdn.com/masonry-layout@4.1/dist/masonry.pkgd.min.js"></script>
```
### Package managers
Bower: `bower install masonry --save`
[npm](https://www.npmjs.com/package/masonry-layout): `npm install masonry-layout --save`
## Initialize
With jQuery
``` js
$('.grid').masonry({
// options...
itemSelector: '.grid-item',
columnWidth: 200
});
```
With vanilla JavaScript
``` js
// vanilla JS
// init with element
var grid = document.querySelector('.grid');
var msnry = new Masonry( grid, {
// options...
itemSelector: '.grid-item',
columnWidth: 200
});
// init with selector
var msnry = new Masonry( '.grid', {
// options...
});
```
With HTML
Add a `data-masonry` attribute to your element. Options can be set in JSON in the value.
``` html
<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>
<div class="grid-item"></div>
<div class="grid-item"></div>
...
</div>
```
## License
Masonry is released under the [MIT license](http://desandro.mit-license.org). Have at it.
* * *
Made by David DeSandro

View file

@ -0,0 +1,40 @@
{
"name": "masonry",
"description": "Cascading grid layout library",
"main": "masonry.js",
"dependencies": {
"get-size": "^2.0.2",
"outlayer": "^2.1.0"
},
"devDependencies": {
"jquery-bridget": "~2.0.0",
"qunit": "^1.12",
"jquery": ">=1.4.3 <4"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"sandbox/",
"gulpfile.js",
"package.json",
"composer.json"
],
"homepage": "http://masonry.desandro.com",
"authors": [
"David DeSandro"
],
"keywords": [
"masonry",
"layout",
"outlayer"
],
"license": "MIT",
"moduleType": [
"amd",
"globals",
"node"
]
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,205 @@
/*!
* Masonry v4.1.1
* Cascading grid layout library
* http://masonry.desandro.com
* MIT License
* by David DeSandro
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'outlayer/outlayer',
'get-size/get-size'
],
factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('outlayer'),
require('get-size')
);
} else {
// browser global
window.Masonry = factory(
window.Outlayer,
window.getSize
);
}
}( window, function factory( Outlayer, getSize ) {
'use strict';
// -------------------------- masonryDefinition -------------------------- //
// create an Outlayer layout class
var Masonry = Outlayer.create('masonry');
// isFitWidth -> fitWidth
Masonry.compatOptions.fitWidth = 'isFitWidth';
Masonry.prototype._resetLayout = function() {
this.getSize();
this._getMeasurement( 'columnWidth', 'outerWidth' );
this._getMeasurement( 'gutter', 'outerWidth' );
this.measureColumns();
// reset column Y
this.colYs = [];
for ( var i=0; i < this.cols; i++ ) {
this.colYs.push( 0 );
}
this.maxY = 0;
};
Masonry.prototype.measureColumns = function() {
this.getContainerWidth();
// if columnWidth is 0, default to outerWidth of first item
if ( !this.columnWidth ) {
var firstItem = this.items[0];
var firstItemElem = firstItem && firstItem.element;
// columnWidth fall back to item of first element
this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
// if first elem has no width, default to size of container
this.containerWidth;
}
var columnWidth = this.columnWidth += this.gutter;
// calculate columns
var containerWidth = this.containerWidth + this.gutter;
var cols = containerWidth / columnWidth;
// fix rounding errors, typically with gutters
var excess = columnWidth - containerWidth % columnWidth;
// if overshoot is less than a pixel, round up, otherwise floor it
var mathMethod = excess && excess < 1 ? 'round' : 'floor';
cols = Math[ mathMethod ]( cols );
this.cols = Math.max( cols, 1 );
};
Masonry.prototype.getContainerWidth = function() {
// container is parent if fit width
var isFitWidth = this._getOption('fitWidth');
var container = isFitWidth ? this.element.parentNode : this.element;
// check that this.size and size are there
// IE8 triggers resize on body size change, so they might not be
var size = getSize( container );
this.containerWidth = size && size.innerWidth;
};
Masonry.prototype._getItemLayoutPosition = function( item ) {
item.getSize();
// how many columns does this brick span
var remainder = item.size.outerWidth % this.columnWidth;
var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
// round if off by 1 pixel, otherwise use ceil
var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
colSpan = Math.min( colSpan, this.cols );
var colGroup = this._getColGroup( colSpan );
// get the minimum Y value from the columns
var minimumY = Math.min.apply( Math, colGroup );
var shortColIndex = colGroup.indexOf( minimumY );
// position the brick
var position = {
x: this.columnWidth * shortColIndex,
y: minimumY
};
// apply setHeight to necessary columns
var setHeight = minimumY + item.size.outerHeight;
var setSpan = this.cols + 1 - colGroup.length;
for ( var i = 0; i < setSpan; i++ ) {
this.colYs[ shortColIndex + i ] = setHeight;
}
return position;
};
/**
* @param {Number} colSpan - number of columns the element spans
* @returns {Array} colGroup
*/
Masonry.prototype._getColGroup = function( colSpan ) {
if ( colSpan < 2 ) {
// if brick spans only one column, use all the column Ys
return this.colYs;
}
var colGroup = [];
// how many different places could this brick fit horizontally
var groupCount = this.cols + 1 - colSpan;
// for each group potential horizontal position
for ( var i = 0; i < groupCount; i++ ) {
// make an array of colY values for that one group
var groupColYs = this.colYs.slice( i, i + colSpan );
// and get the max value of the array
colGroup[i] = Math.max.apply( Math, groupColYs );
}
return colGroup;
};
Masonry.prototype._manageStamp = function( stamp ) {
var stampSize = getSize( stamp );
var offset = this._getElementOffset( stamp );
// get the columns that this stamp affects
var isOriginLeft = this._getOption('originLeft');
var firstX = isOriginLeft ? offset.left : offset.right;
var lastX = firstX + stampSize.outerWidth;
var firstCol = Math.floor( firstX / this.columnWidth );
firstCol = Math.max( 0, firstCol );
var lastCol = Math.floor( lastX / this.columnWidth );
// lastCol should not go over if multiple of columnWidth #425
lastCol -= lastX % this.columnWidth ? 0 : 1;
lastCol = Math.min( this.cols - 1, lastCol );
// set colYs to bottom of the stamp
var isOriginTop = this._getOption('originTop');
var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
stampSize.outerHeight;
for ( var i = firstCol; i <= lastCol; i++ ) {
this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
}
};
Masonry.prototype._getContainerSize = function() {
this.maxY = Math.max.apply( Math, this.colYs );
var size = {
height: this.maxY
};
if ( this._getOption('fitWidth') ) {
size.width = this._getContainerFitWidth();
}
return size;
};
Masonry.prototype._getContainerFitWidth = function() {
var unusedCols = 0;
// count unused columns
var i = this.cols;
while ( --i ) {
if ( this.colYs[i] !== 0 ) {
break;
}
unusedCols++;
}
// fit container to columns that have been used
return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
};
Masonry.prototype.needsResizeLayout = function() {
var previousWidth = this.containerWidth;
this.getContainerWidth();
return previousWidth != this.containerWidth;
};
return Masonry;
}));

View file

@ -0,0 +1,125 @@
# Outlayer
_Brains and guts of a layout library_
Outlayer is a base layout class for layout libraries like [Isotope](http://isotope.metafizzy.co), [Packery](http://packery.metafizzy.co), and [Masonry](http://masonry.desandro.com)
Outlayer layouts work with a container element and children item elements.
``` html
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
...
</div>
```
## Install
Install with [Bower](http://bower.io): `bower install outlayer`
[Install with npm](http://npmjs.org/package/outlayer): `npm install outlayer`
## Outlayer.create()
Create a layout class with `Outlayer.create()`
``` js
var Layout = Outlayer.create( namespace );
// for example
var Masonry = Outlayer.create('masonry');
```
+ `namespace` _{String}_ should be camelCased
+ returns `LayoutClass` _{Function}_
Create a new layout class. `namespace` is used for jQuery plugin, and for declarative initialization.
The `Layout` inherits from [`Outlayer.prototype`](docs/outlayer.md).
```
var elem = document.querySelector('.selector');
var msnry = new Masonry( elem, {
// set options...
columnWidth: 200
});
```
## Item
Layouts work with Items, accessible as `Layout.Item`. See [Item API](docs/item.md).
## Declarative
An Outlayer layout class can be initialized via HTML, by setting an attribute of `data-namespace` on the element. Options are set in JSON. For example:
``` html
<!-- var Masonry = Outlayer.create('masonry') -->
<div class="grid" data-masonry='{ "itemSelector": ".item", "columnWidth": 200 }'>
...
</div>
```
The declarative attributes and class will be dashed. i.e. `Outlayer.create('myNiceLayout')` will use `data-my-nice-layout` as the attribute.
## .data()
Get a layout instance from an element.
```
var myMasonry = Masonry.data( document.querySelector('.grid') );
```
## jQuery plugin
The layout class also works as jQuery plugin.
``` js
// create Masonry layout class, namespace will be the jQuery method
var Masonry = Outlayer.create('masonry');
// rock some jQuery
$( function() {
// .masonry() to initialize
var $grid = $('.grid').masonry({
// options...
});
// methods are available by passing a string as first parameter
$grid.masonry( 'reveal', elems );
});
```
## RequireJS
To use Outlayer with [RequireJS](http://requirejs.org/), you'll need to set some config.
Set [baseUrl](http://requirejs.org/docs/api.html#config-baseUrl) to bower_components and set a [path config](http://requirejs.org/docs/api.html#config-paths) for all your application code.
``` js
requirejs.config({
baseUrl: 'bower_components',
paths: {
app: '../'
}
});
requirejs( [ 'outlayer/outlayer', 'app/my-component.js' ], function( Outlayer, myComp ) {
new Outlayer( /*...*/ )
});
```
Or set a path config for all Outlayer dependencies.
``` js
requirejs.config({
paths: {
'ev-emitter': 'bower_components/ev-emitter',
'get-size': 'bower_components/get-size',
'matches-selector': 'bower_components/matches-selector'
}
});
```
## MIT license
Outlayer is released under the [MIT license](http://desandro.mit-license.org).

View file

@ -0,0 +1,43 @@
{
"name": "outlayer",
"description": "the brains and guts of a layout library",
"main": "outlayer.js",
"dependencies": {
"ev-emitter": "^1.0.0",
"get-size": "^2.0.2",
"fizzy-ui-utils": "^2.0.0"
},
"devDependencies": {
"jquery-bridget": "2.x",
"jquery": ">=1.4.3 <4",
"qunit": "^1.17.0"
},
"ignore": [
"test/",
"docs/",
"sandbox/",
".*",
"notes.md",
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"package.json"
],
"homepage": "https://github.com/metafizzy/outlayer",
"authors": [
"Metafizzy"
],
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"layout",
"masonry",
"isotope"
],
"license": "MIT"
}

553
_site/bower_components/outlayer/item.js vendored Normal file
View file

@ -0,0 +1,553 @@
/**
* Outlayer Item
*/
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /* globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD - RequireJS
define( [
'ev-emitter/ev-emitter',
'get-size/get-size'
],
factory
);
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS - Browserify, Webpack
module.exports = factory(
require('ev-emitter'),
require('get-size')
);
} else {
// browser global
window.Outlayer = {};
window.Outlayer.Item = factory(
window.EvEmitter,
window.getSize
);
}
}( window, function factory( EvEmitter, getSize ) {
'use strict';
// ----- helpers ----- //
function isEmptyObj( obj ) {
for ( var prop in obj ) {
return false;
}
prop = null;
return true;
}
// -------------------------- CSS3 support -------------------------- //
var docElemStyle = document.documentElement.style;
var transitionProperty = typeof docElemStyle.transition == 'string' ?
'transition' : 'WebkitTransition';
var transformProperty = typeof docElemStyle.transform == 'string' ?
'transform' : 'WebkitTransform';
var transitionEndEvent = {
WebkitTransition: 'webkitTransitionEnd',
transition: 'transitionend'
}[ transitionProperty ];
// cache all vendor properties that could have vendor prefix
var vendorProperties = {
transform: transformProperty,
transition: transitionProperty,
transitionDuration: transitionProperty + 'Duration',
transitionProperty: transitionProperty + 'Property',
transitionDelay: transitionProperty + 'Delay'
};
// -------------------------- Item -------------------------- //
function Item( element, layout ) {
if ( !element ) {
return;
}
this.element = element;
// parent layout class, i.e. Masonry, Isotope, or Packery
this.layout = layout;
this.position = {
x: 0,
y: 0
};
this._create();
}
// inherit EvEmitter
var proto = Item.prototype = Object.create( EvEmitter.prototype );
proto.constructor = Item;
proto._create = function() {
// transition objects
this._transn = {
ingProperties: {},
clean: {},
onEnd: {}
};
this.css({
position: 'absolute'
});
};
// trigger specified handler for event type
proto.handleEvent = function( event ) {
var method = 'on' + event.type;
if ( this[ method ] ) {
this[ method ]( event );
}
};
proto.getSize = function() {
this.size = getSize( this.element );
};
/**
* apply CSS styles to element
* @param {Object} style
*/
proto.css = function( style ) {
var elemStyle = this.element.style;
for ( var prop in style ) {
// use vendor property if available
var supportedProp = vendorProperties[ prop ] || prop;
elemStyle[ supportedProp ] = style[ prop ];
}
};
// measure position, and sets it
proto.getPosition = function() {
var style = getComputedStyle( this.element );
var isOriginLeft = this.layout._getOption('originLeft');
var isOriginTop = this.layout._getOption('originTop');
var xValue = style[ isOriginLeft ? 'left' : 'right' ];
var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
// convert percent to pixels
var layoutSize = this.layout.size;
var x = xValue.indexOf('%') != -1 ?
( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
var y = yValue.indexOf('%') != -1 ?
( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
// clean up 'auto' or other non-integer values
x = isNaN( x ) ? 0 : x;
y = isNaN( y ) ? 0 : y;
// remove padding from measurement
x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
this.position.x = x;
this.position.y = y;
};
// set settled position, apply padding
proto.layoutPosition = function() {
var layoutSize = this.layout.size;
var style = {};
var isOriginLeft = this.layout._getOption('originLeft');
var isOriginTop = this.layout._getOption('originTop');
// x
var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
var xProperty = isOriginLeft ? 'left' : 'right';
var xResetProperty = isOriginLeft ? 'right' : 'left';
var x = this.position.x + layoutSize[ xPadding ];
// set in percentage or pixels
style[ xProperty ] = this.getXValue( x );
// reset other property
style[ xResetProperty ] = '';
// y
var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
var yProperty = isOriginTop ? 'top' : 'bottom';
var yResetProperty = isOriginTop ? 'bottom' : 'top';
var y = this.position.y + layoutSize[ yPadding ];
// set in percentage or pixels
style[ yProperty ] = this.getYValue( y );
// reset other property
style[ yResetProperty ] = '';
this.css( style );
this.emitEvent( 'layout', [ this ] );
};
proto.getXValue = function( x ) {
var isHorizontal = this.layout._getOption('horizontal');
return this.layout.options.percentPosition && !isHorizontal ?
( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
};
proto.getYValue = function( y ) {
var isHorizontal = this.layout._getOption('horizontal');
return this.layout.options.percentPosition && isHorizontal ?
( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
};
proto._transitionTo = function( x, y ) {
this.getPosition();
// get current x & y from top/left
var curX = this.position.x;
var curY = this.position.y;
var compareX = parseInt( x, 10 );
var compareY = parseInt( y, 10 );
var didNotMove = compareX === this.position.x && compareY === this.position.y;
// save end position
this.setPosition( x, y );
// if did not move and not transitioning, just go to layout
if ( didNotMove && !this.isTransitioning ) {
this.layoutPosition();
return;
}
var transX = x - curX;
var transY = y - curY;
var transitionStyle = {};
transitionStyle.transform = this.getTranslate( transX, transY );
this.transition({
to: transitionStyle,
onTransitionEnd: {
transform: this.layoutPosition
},
isCleaning: true
});
};
proto.getTranslate = function( x, y ) {
// flip cooridinates if origin on right or bottom
var isOriginLeft = this.layout._getOption('originLeft');
var isOriginTop = this.layout._getOption('originTop');
x = isOriginLeft ? x : -x;
y = isOriginTop ? y : -y;
return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
};
// non transition + transform support
proto.goTo = function( x, y ) {
this.setPosition( x, y );
this.layoutPosition();
};
proto.moveTo = proto._transitionTo;
proto.setPosition = function( x, y ) {
this.position.x = parseInt( x, 10 );
this.position.y = parseInt( y, 10 );
};
// ----- transition ----- //
/**
* @param {Object} style - CSS
* @param {Function} onTransitionEnd
*/
// non transition, just trigger callback
proto._nonTransition = function( args ) {
this.css( args.to );
if ( args.isCleaning ) {
this._removeStyles( args.to );
}
for ( var prop in args.onTransitionEnd ) {
args.onTransitionEnd[ prop ].call( this );
}
};
/**
* proper transition
* @param {Object} args - arguments
* @param {Object} to - style to transition to
* @param {Object} from - style to start transition from
* @param {Boolean} isCleaning - removes transition styles after transition
* @param {Function} onTransitionEnd - callback
*/
proto.transition = function( args ) {
// redirect to nonTransition if no transition duration
if ( !parseFloat( this.layout.options.transitionDuration ) ) {
this._nonTransition( args );
return;
}
var _transition = this._transn;
// keep track of onTransitionEnd callback by css property
for ( var prop in args.onTransitionEnd ) {
_transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
}
// keep track of properties that are transitioning
for ( prop in args.to ) {
_transition.ingProperties[ prop ] = true;
// keep track of properties to clean up when transition is done
if ( args.isCleaning ) {
_transition.clean[ prop ] = true;
}
}
// set from styles
if ( args.from ) {
this.css( args.from );
// force redraw. http://blog.alexmaccaw.com/css-transitions
var h = this.element.offsetHeight;
// hack for JSHint to hush about unused var
h = null;
}
// enable transition
this.enableTransition( args.to );
// set styles that are transitioning
this.css( args.to );
this.isTransitioning = true;
};
// dash before all cap letters, including first for
// WebkitTransform => -webkit-transform
function toDashedAll( str ) {
return str.replace( /([A-Z])/g, function( $1 ) {
return '-' + $1.toLowerCase();
});
}
var transitionProps = 'opacity,' + toDashedAll( transformProperty );
proto.enableTransition = function(/* style */) {
// HACK changing transitionProperty during a transition
// will cause transition to jump
if ( this.isTransitioning ) {
return;
}
// make `transition: foo, bar, baz` from style object
// HACK un-comment this when enableTransition can work
// while a transition is happening
// var transitionValues = [];
// for ( var prop in style ) {
// // dash-ify camelCased properties like WebkitTransition
// prop = vendorProperties[ prop ] || prop;
// transitionValues.push( toDashedAll( prop ) );
// }
// munge number to millisecond, to match stagger
var duration = this.layout.options.transitionDuration;
duration = typeof duration == 'number' ? duration + 'ms' : duration;
// enable transition styles
this.css({
transitionProperty: transitionProps,
transitionDuration: duration,
transitionDelay: this.staggerDelay || 0
});
// listen for transition end event
this.element.addEventListener( transitionEndEvent, this, false );
};
// ----- events ----- //
proto.onwebkitTransitionEnd = function( event ) {
this.ontransitionend( event );
};
proto.onotransitionend = function( event ) {
this.ontransitionend( event );
};
// properties that I munge to make my life easier
var dashedVendorProperties = {
'-webkit-transform': 'transform'
};
proto.ontransitionend = function( event ) {
// disregard bubbled events from children
if ( event.target !== this.element ) {
return;
}
var _transition = this._transn;
// get property name of transitioned property, convert to prefix-free
var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
// remove property that has completed transitioning
delete _transition.ingProperties[ propertyName ];
// check if any properties are still transitioning
if ( isEmptyObj( _transition.ingProperties ) ) {
// all properties have completed transitioning
this.disableTransition();
}
// clean style
if ( propertyName in _transition.clean ) {
// clean up style
this.element.style[ event.propertyName ] = '';
delete _transition.clean[ propertyName ];
}
// trigger onTransitionEnd callback
if ( propertyName in _transition.onEnd ) {
var onTransitionEnd = _transition.onEnd[ propertyName ];
onTransitionEnd.call( this );
delete _transition.onEnd[ propertyName ];
}
this.emitEvent( 'transitionEnd', [ this ] );
};
proto.disableTransition = function() {
this.removeTransitionStyles();
this.element.removeEventListener( transitionEndEvent, this, false );
this.isTransitioning = false;
};
/**
* removes style property from element
* @param {Object} style
**/
proto._removeStyles = function( style ) {
// clean up transition styles
var cleanStyle = {};
for ( var prop in style ) {
cleanStyle[ prop ] = '';
}
this.css( cleanStyle );
};
var cleanTransitionStyle = {
transitionProperty: '',
transitionDuration: '',
transitionDelay: ''
};
proto.removeTransitionStyles = function() {
// remove transition
this.css( cleanTransitionStyle );
};
// ----- stagger ----- //
proto.stagger = function( delay ) {
delay = isNaN( delay ) ? 0 : delay;
this.staggerDelay = delay + 'ms';
};
// ----- show/hide/remove ----- //
// remove element from DOM
proto.removeElem = function() {
this.element.parentNode.removeChild( this.element );
// remove display: none
this.css({ display: '' });
this.emitEvent( 'remove', [ this ] );
};
proto.remove = function() {
// just remove element if no transition support or no transition
if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
this.removeElem();
return;
}
// start transition
this.once( 'transitionEnd', function() {
this.removeElem();
});
this.hide();
};
proto.reveal = function() {
delete this.isHidden;
// remove display: none
this.css({ display: '' });
var options = this.layout.options;
var onTransitionEnd = {};
var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
this.transition({
from: options.hiddenStyle,
to: options.visibleStyle,
isCleaning: true,
onTransitionEnd: onTransitionEnd
});
};
proto.onRevealTransitionEnd = function() {
// check if still visible
// during transition, item may have been hidden
if ( !this.isHidden ) {
this.emitEvent('reveal');
}
};
/**
* get style property use for hide/reveal transition end
* @param {String} styleProperty - hiddenStyle/visibleStyle
* @returns {String}
*/
proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
var optionStyle = this.layout.options[ styleProperty ];
// use opacity
if ( optionStyle.opacity ) {
return 'opacity';
}
// get first property
for ( var prop in optionStyle ) {
return prop;
}
};
proto.hide = function() {
// set flag
this.isHidden = true;
// remove display: none
this.css({ display: '' });
var options = this.layout.options;
var onTransitionEnd = {};
var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
this.transition({
from: options.visibleStyle,
to: options.hiddenStyle,
// keep hidden stuff hidden
isCleaning: true,
onTransitionEnd: onTransitionEnd
});
};
proto.onHideTransitionEnd = function() {
// check if still hidden
// during transition, item may have been un-hidden
if ( this.isHidden ) {
this.css({ display: 'none' });
this.emitEvent('hide');
}
};
proto.destroy = function() {
this.css({
position: '',
left: '',
right: '',
top: '',
bottom: '',
transition: '',
transform: ''
});
};
return Item;
}));

View file

@ -0,0 +1,939 @@
/*!
* Outlayer v2.1.0
* the brains and guts of a layout library
* MIT license
*/
( function( window, factory ) {
'use strict';
// universal module definition
/* jshint strict: false */ /* globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD - RequireJS
define( [
'ev-emitter/ev-emitter',
'get-size/get-size',
'fizzy-ui-utils/utils',
'./item'
],
function( EvEmitter, getSize, utils, Item ) {
return factory( window, EvEmitter, getSize, utils, Item);
}
);
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS - Browserify, Webpack
module.exports = factory(
window,
require('ev-emitter'),
require('get-size'),
require('fizzy-ui-utils'),
require('./item')
);
} else {
// browser global
window.Outlayer = factory(
window,
window.EvEmitter,
window.getSize,
window.fizzyUIUtils,
window.Outlayer.Item
);
}
}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
'use strict';
// ----- vars ----- //
var console = window.console;
var jQuery = window.jQuery;
var noop = function() {};
// -------------------------- Outlayer -------------------------- //
// globally unique identifiers
var GUID = 0;
// internal store of all Outlayer intances
var instances = {};
/**
* @param {Element, String} element
* @param {Object} options
* @constructor
*/
function Outlayer( element, options ) {
var queryElement = utils.getQueryElement( element );
if ( !queryElement ) {
if ( console ) {
console.error( 'Bad element for ' + this.constructor.namespace +
': ' + ( queryElement || element ) );
}
return;
}
this.element = queryElement;
// add jQuery
if ( jQuery ) {
this.$element = jQuery( this.element );
}
// options
this.options = utils.extend( {}, this.constructor.defaults );
this.option( options );
// add id for Outlayer.getFromElement
var id = ++GUID;
this.element.outlayerGUID = id; // expando
instances[ id ] = this; // associate via id
// kick it off
this._create();
var isInitLayout = this._getOption('initLayout');
if ( isInitLayout ) {
this.layout();
}
}
// settings are for internal use only
Outlayer.namespace = 'outlayer';
Outlayer.Item = Item;
// default options
Outlayer.defaults = {
containerStyle: {
position: 'relative'
},
initLayout: true,
originLeft: true,
originTop: true,
resize: true,
resizeContainer: true,
// item options
transitionDuration: '0.4s',
hiddenStyle: {
opacity: 0,
transform: 'scale(0.001)'
},
visibleStyle: {
opacity: 1,
transform: 'scale(1)'
}
};
var proto = Outlayer.prototype;
// inherit EvEmitter
utils.extend( proto, EvEmitter.prototype );
/**
* set options
* @param {Object} opts
*/
proto.option = function( opts ) {
utils.extend( this.options, opts );
};
/**
* get backwards compatible option value, check old name
*/
proto._getOption = function( option ) {
var oldOption = this.constructor.compatOptions[ option ];
return oldOption && this.options[ oldOption ] !== undefined ?
this.options[ oldOption ] : this.options[ option ];
};
Outlayer.compatOptions = {
// currentName: oldName
initLayout: 'isInitLayout',
horizontal: 'isHorizontal',
layoutInstant: 'isLayoutInstant',
originLeft: 'isOriginLeft',
originTop: 'isOriginTop',
resize: 'isResizeBound',
resizeContainer: 'isResizingContainer'
};
proto._create = function() {
// get items from children
this.reloadItems();
// elements that affect layout, but are not laid out
this.stamps = [];
this.stamp( this.options.stamp );
// set container style
utils.extend( this.element.style, this.options.containerStyle );
// bind resize method
var canBindResize = this._getOption('resize');
if ( canBindResize ) {
this.bindResize();
}
};
// goes through all children again and gets bricks in proper order
proto.reloadItems = function() {
// collection of item elements
this.items = this._itemize( this.element.children );
};
/**
* turn elements into Outlayer.Items to be used in layout
* @param {Array or NodeList or HTMLElement} elems
* @returns {Array} items - collection of new Outlayer Items
*/
proto._itemize = function( elems ) {
var itemElems = this._filterFindItemElements( elems );
var Item = this.constructor.Item;
// create new Outlayer Items for collection
var items = [];
for ( var i=0; i < itemElems.length; i++ ) {
var elem = itemElems[i];
var item = new Item( elem, this );
items.push( item );
}
return items;
};
/**
* get item elements to be used in layout
* @param {Array or NodeList or HTMLElement} elems
* @returns {Array} items - item elements
*/
proto._filterFindItemElements = function( elems ) {
return utils.filterFindElements( elems, this.options.itemSelector );
};
/**
* getter method for getting item elements
* @returns {Array} elems - collection of item elements
*/
proto.getItemElements = function() {
return this.items.map( function( item ) {
return item.element;
});
};
// ----- init & layout ----- //
/**
* lays out all items
*/
proto.layout = function() {
this._resetLayout();
this._manageStamps();
// don't animate first layout
var layoutInstant = this._getOption('layoutInstant');
var isInstant = layoutInstant !== undefined ?
layoutInstant : !this._isLayoutInited;
this.layoutItems( this.items, isInstant );
// flag for initalized
this._isLayoutInited = true;
};
// _init is alias for layout
proto._init = proto.layout;
/**
* logic before any new layout
*/
proto._resetLayout = function() {
this.getSize();
};
proto.getSize = function() {
this.size = getSize( this.element );
};
/**
* get measurement from option, for columnWidth, rowHeight, gutter
* if option is String -> get element from selector string, & get size of element
* if option is Element -> get size of element
* else use option as a number
*
* @param {String} measurement
* @param {String} size - width or height
* @private
*/
proto._getMeasurement = function( measurement, size ) {
var option = this.options[ measurement ];
var elem;
if ( !option ) {
// default to 0
this[ measurement ] = 0;
} else {
// use option as an element
if ( typeof option == 'string' ) {
elem = this.element.querySelector( option );
} else if ( option instanceof HTMLElement ) {
elem = option;
}
// use size of element, if element
this[ measurement ] = elem ? getSize( elem )[ size ] : option;
}
};
/**
* layout a collection of item elements
* @api public
*/
proto.layoutItems = function( items, isInstant ) {
items = this._getItemsForLayout( items );
this._layoutItems( items, isInstant );
this._postLayout();
};
/**
* get the items to be laid out
* you may want to skip over some items
* @param {Array} items
* @returns {Array} items
*/
proto._getItemsForLayout = function( items ) {
return items.filter( function( item ) {
return !item.isIgnored;
});
};
/**
* layout items
* @param {Array} items
* @param {Boolean} isInstant
*/
proto._layoutItems = function( items, isInstant ) {
this._emitCompleteOnItems( 'layout', items );
if ( !items || !items.length ) {
// no items, emit event with empty array
return;
}
var queue = [];
items.forEach( function( item ) {
// get x/y object from method
var position = this._getItemLayoutPosition( item );
// enqueue
position.item = item;
position.isInstant = isInstant || item.isLayoutInstant;
queue.push( position );
}, this );
this._processLayoutQueue( queue );
};
/**
* get item layout position
* @param {Outlayer.Item} item
* @returns {Object} x and y position
*/
proto._getItemLayoutPosition = function( /* item */ ) {
return {
x: 0,
y: 0
};
};
/**
* iterate over array and position each item
* Reason being - separating this logic prevents 'layout invalidation'
* thx @paul_irish
* @param {Array} queue
*/
proto._processLayoutQueue = function( queue ) {
this.updateStagger();
queue.forEach( function( obj, i ) {
this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
}, this );
};
// set stagger from option in milliseconds number
proto.updateStagger = function() {
var stagger = this.options.stagger;
if ( stagger === null || stagger === undefined ) {
this.stagger = 0;
return;
}
this.stagger = getMilliseconds( stagger );
return this.stagger;
};
/**
* Sets position of item in DOM
* @param {Outlayer.Item} item
* @param {Number} x - horizontal position
* @param {Number} y - vertical position
* @param {Boolean} isInstant - disables transitions
*/
proto._positionItem = function( item, x, y, isInstant, i ) {
if ( isInstant ) {
// if not transition, just set CSS
item.goTo( x, y );
} else {
item.stagger( i * this.stagger );
item.moveTo( x, y );
}
};
/**
* Any logic you want to do after each layout,
* i.e. size the container
*/
proto._postLayout = function() {
this.resizeContainer();
};
proto.resizeContainer = function() {
var isResizingContainer = this._getOption('resizeContainer');
if ( !isResizingContainer ) {
return;
}
var size = this._getContainerSize();
if ( size ) {
this._setContainerMeasure( size.width, true );
this._setContainerMeasure( size.height, false );
}
};
/**
* Sets width or height of container if returned
* @returns {Object} size
* @param {Number} width
* @param {Number} height
*/
proto._getContainerSize = noop;
/**
* @param {Number} measure - size of width or height
* @param {Boolean} isWidth
*/
proto._setContainerMeasure = function( measure, isWidth ) {
if ( measure === undefined ) {
return;
}
var elemSize = this.size;
// add padding and border width if border box
if ( elemSize.isBorderBox ) {
measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
elemSize.borderLeftWidth + elemSize.borderRightWidth :
elemSize.paddingBottom + elemSize.paddingTop +
elemSize.borderTopWidth + elemSize.borderBottomWidth;
}
measure = Math.max( measure, 0 );
this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
};
/**
* emit eventComplete on a collection of items events
* @param {String} eventName
* @param {Array} items - Outlayer.Items
*/
proto._emitCompleteOnItems = function( eventName, items ) {
var _this = this;
function onComplete() {
_this.dispatchEvent( eventName + 'Complete', null, [ items ] );
}
var count = items.length;
if ( !items || !count ) {
onComplete();
return;
}
var doneCount = 0;
function tick() {
doneCount++;
if ( doneCount == count ) {
onComplete();
}
}
// bind callback
items.forEach( function( item ) {
item.once( eventName, tick );
});
};
/**
* emits events via EvEmitter and jQuery events
* @param {String} type - name of event
* @param {Event} event - original event
* @param {Array} args - extra arguments
*/
proto.dispatchEvent = function( type, event, args ) {
// add original event to arguments
var emitArgs = event ? [ event ].concat( args ) : args;
this.emitEvent( type, emitArgs );
if ( jQuery ) {
// set this.$element
this.$element = this.$element || jQuery( this.element );
if ( event ) {
// create jQuery event
var $event = jQuery.Event( event );
$event.type = type;
this.$element.trigger( $event, args );
} else {
// just trigger with type if no event available
this.$element.trigger( type, args );
}
}
};
// -------------------------- ignore & stamps -------------------------- //
/**
* keep item in collection, but do not lay it out
* ignored items do not get skipped in layout
* @param {Element} elem
*/
proto.ignore = function( elem ) {
var item = this.getItem( elem );
if ( item ) {
item.isIgnored = true;
}
};
/**
* return item to layout collection
* @param {Element} elem
*/
proto.unignore = function( elem ) {
var item = this.getItem( elem );
if ( item ) {
delete item.isIgnored;
}
};
/**
* adds elements to stamps
* @param {NodeList, Array, Element, or String} elems
*/
proto.stamp = function( elems ) {
elems = this._find( elems );
if ( !elems ) {
return;
}
this.stamps = this.stamps.concat( elems );
// ignore
elems.forEach( this.ignore, this );
};
/**
* removes elements to stamps
* @param {NodeList, Array, or Element} elems
*/
proto.unstamp = function( elems ) {
elems = this._find( elems );
if ( !elems ){
return;
}
elems.forEach( function( elem ) {
// filter out removed stamp elements
utils.removeFrom( this.stamps, elem );
this.unignore( elem );
}, this );
};
/**
* finds child elements
* @param {NodeList, Array, Element, or String} elems
* @returns {Array} elems
*/
proto._find = function( elems ) {
if ( !elems ) {
return;
}
// if string, use argument as selector string
if ( typeof elems == 'string' ) {
elems = this.element.querySelectorAll( elems );
}
elems = utils.makeArray( elems );
return elems;
};
proto._manageStamps = function() {
if ( !this.stamps || !this.stamps.length ) {
return;
}
this._getBoundingRect();
this.stamps.forEach( this._manageStamp, this );
};
// update boundingLeft / Top
proto._getBoundingRect = function() {
// get bounding rect for container element
var boundingRect = this.element.getBoundingClientRect();
var size = this.size;
this._boundingRect = {
left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
top: boundingRect.top + size.paddingTop + size.borderTopWidth,
right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
};
};
/**
* @param {Element} stamp
**/
proto._manageStamp = noop;
/**
* get x/y position of element relative to container element
* @param {Element} elem
* @returns {Object} offset - has left, top, right, bottom
*/
proto._getElementOffset = function( elem ) {
var boundingRect = elem.getBoundingClientRect();
var thisRect = this._boundingRect;
var size = getSize( elem );
var offset = {
left: boundingRect.left - thisRect.left - size.marginLeft,
top: boundingRect.top - thisRect.top - size.marginTop,
right: thisRect.right - boundingRect.right - size.marginRight,
bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
};
return offset;
};
// -------------------------- resize -------------------------- //
// enable event handlers for listeners
// i.e. resize -> onresize
proto.handleEvent = utils.handleEvent;
/**
* Bind layout to window resizing
*/
proto.bindResize = function() {
window.addEventListener( 'resize', this );
this.isResizeBound = true;
};
/**
* Unbind layout to window resizing
*/
proto.unbindResize = function() {
window.removeEventListener( 'resize', this );
this.isResizeBound = false;
};
proto.onresize = function() {
this.resize();
};
utils.debounceMethod( Outlayer, 'onresize', 100 );
proto.resize = function() {
// don't trigger if size did not change
// or if resize was unbound. See #9
if ( !this.isResizeBound || !this.needsResizeLayout() ) {
return;
}
this.layout();
};
/**
* check if layout is needed post layout
* @returns Boolean
*/
proto.needsResizeLayout = function() {
var size = getSize( this.element );
// check that this.size and size are there
// IE8 triggers resize on body size change, so they might not be
var hasSizes = this.size && size;
return hasSizes && size.innerWidth !== this.size.innerWidth;
};
// -------------------------- methods -------------------------- //
/**
* add items to Outlayer instance
* @param {Array or NodeList or Element} elems
* @returns {Array} items - Outlayer.Items
**/
proto.addItems = function( elems ) {
var items = this._itemize( elems );
// add items to collection
if ( items.length ) {
this.items = this.items.concat( items );
}
return items;
};
/**
* Layout newly-appended item elements
* @param {Array or NodeList or Element} elems
*/
proto.appended = function( elems ) {
var items = this.addItems( elems );
if ( !items.length ) {
return;
}
// layout and reveal just the new items
this.layoutItems( items, true );
this.reveal( items );
};
/**
* Layout prepended elements
* @param {Array or NodeList or Element} elems
*/
proto.prepended = function( elems ) {
var items = this._itemize( elems );
if ( !items.length ) {
return;
}
// add items to beginning of collection
var previousItems = this.items.slice(0);
this.items = items.concat( previousItems );
// start new layout
this._resetLayout();
this._manageStamps();
// layout new stuff without transition
this.layoutItems( items, true );
this.reveal( items );
// layout previous items
this.layoutItems( previousItems );
};
/**
* reveal a collection of items
* @param {Array of Outlayer.Items} items
*/
proto.reveal = function( items ) {
this._emitCompleteOnItems( 'reveal', items );
if ( !items || !items.length ) {
return;
}
var stagger = this.updateStagger();
items.forEach( function( item, i ) {
item.stagger( i * stagger );
item.reveal();
});
};
/**
* hide a collection of items
* @param {Array of Outlayer.Items} items
*/
proto.hide = function( items ) {
this._emitCompleteOnItems( 'hide', items );
if ( !items || !items.length ) {
return;
}
var stagger = this.updateStagger();
items.forEach( function( item, i ) {
item.stagger( i * stagger );
item.hide();
});
};
/**
* reveal item elements
* @param {Array}, {Element}, {NodeList} items
*/
proto.revealItemElements = function( elems ) {
var items = this.getItems( elems );
this.reveal( items );
};
/**
* hide item elements
* @param {Array}, {Element}, {NodeList} items
*/
proto.hideItemElements = function( elems ) {
var items = this.getItems( elems );
this.hide( items );
};
/**
* get Outlayer.Item, given an Element
* @param {Element} elem
* @param {Function} callback
* @returns {Outlayer.Item} item
*/
proto.getItem = function( elem ) {
// loop through items to get the one that matches
for ( var i=0; i < this.items.length; i++ ) {
var item = this.items[i];
if ( item.element == elem ) {
// return item
return item;
}
}
};
/**
* get collection of Outlayer.Items, given Elements
* @param {Array} elems
* @returns {Array} items - Outlayer.Items
*/
proto.getItems = function( elems ) {
elems = utils.makeArray( elems );
var items = [];
elems.forEach( function( elem ) {
var item = this.getItem( elem );
if ( item ) {
items.push( item );
}
}, this );
return items;
};
/**
* remove element(s) from instance and DOM
* @param {Array or NodeList or Element} elems
*/
proto.remove = function( elems ) {
var removeItems = this.getItems( elems );
this._emitCompleteOnItems( 'remove', removeItems );
// bail if no items to remove
if ( !removeItems || !removeItems.length ) {
return;
}
removeItems.forEach( function( item ) {
item.remove();
// remove item from collection
utils.removeFrom( this.items, item );
}, this );
};
// ----- destroy ----- //
// remove and disable Outlayer instance
proto.destroy = function() {
// clean up dynamic styles
var style = this.element.style;
style.height = '';
style.position = '';
style.width = '';
// destroy items
this.items.forEach( function( item ) {
item.destroy();
});
this.unbindResize();
var id = this.element.outlayerGUID;
delete instances[ id ]; // remove reference to instance by id
delete this.element.outlayerGUID;
// remove data for jQuery
if ( jQuery ) {
jQuery.removeData( this.element, this.constructor.namespace );
}
};
// -------------------------- data -------------------------- //
/**
* get Outlayer instance from element
* @param {Element} elem
* @returns {Outlayer}
*/
Outlayer.data = function( elem ) {
elem = utils.getQueryElement( elem );
var id = elem && elem.outlayerGUID;
return id && instances[ id ];
};
// -------------------------- create Outlayer class -------------------------- //
/**
* create a layout class
* @param {String} namespace
*/
Outlayer.create = function( namespace, options ) {
// sub-class Outlayer
var Layout = subclass( Outlayer );
// apply new options and compatOptions
Layout.defaults = utils.extend( {}, Outlayer.defaults );
utils.extend( Layout.defaults, options );
Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions );
Layout.namespace = namespace;
Layout.data = Outlayer.data;
// sub-class Item
Layout.Item = subclass( Item );
// -------------------------- declarative -------------------------- //
utils.htmlInit( Layout, namespace );
// -------------------------- jQuery bridge -------------------------- //
// make into jQuery plugin
if ( jQuery && jQuery.bridget ) {
jQuery.bridget( namespace, Layout );
}
return Layout;
};
function subclass( Parent ) {
function SubClass() {
Parent.apply( this, arguments );
}
SubClass.prototype = Object.create( Parent.prototype );
SubClass.prototype.constructor = SubClass;
return SubClass;
}
// ----- helpers ----- //
// how many milliseconds are in each unit
var msUnits = {
ms: 1,
s: 1000
};
// munge time-like parameter into millisecond number
// '0.4s' -> 40
function getMilliseconds( time ) {
if ( typeof time == 'number' ) {
return time;
}
var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
var num = matches && matches[1];
var unit = matches && matches[2];
if ( !num.length ) {
return 0;
}
num = parseFloat( num );
var mult = msUnits[ unit ] || 1;
return num * mult;
}
// ----- fin ----- //
// back in global
Outlayer.Item = Item;
return Outlayer;
}));

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,3 @@
.button-group
{
margin: 50px 0 30px 0;
}
button
{
color: #000;
}
#video-roster {
background-color:#000;
@ -47,20 +38,20 @@ button
#videotext
{
width:600px;
background-color:#000;
width:40%;
background-color:#fff;
opacity:.8;
position:fixed;
z-index:10000;
right:50px;
bottom:50px;
z-index:100;
right:20px;
top:20px;
display:none;
padding:30px;
}
#videotext .video-title
{
color:#fff;
color:#000;
font-size: 1.7em;
background-color:none;
}
@ -78,12 +69,8 @@ button
.playbutton
{
display:block;
position:absolute;
top:70px;
left:90px;
z-index:1000000;
width:60px;
margin-top:30px;
display:none;
pointer-events: none;
}
@ -92,9 +79,7 @@ button
{
display:block;
position:fixed;
top:100px;
left:40px;
z-index:1000000;
z-index:1000;
width:100%;
height:100%;
display:none;
@ -117,8 +102,8 @@ button
display:block;
width:50px;
height:50px;
top:130px;
right:30px;
top:0;
right:0;
background-image:url("/images/close-button-large.png");
background-size:cover;
}
}

View file

@ -130,11 +130,50 @@
,
{
"title": "",
"description": "Lauren Moffatt will speak about her experiences producing virtual reality in an art context, including the struggle to develop a visual language for the medium, the awkward meeting of the gaming and film industries, and the stampede to develop content and services in time for the projected boom.
Lauren Moffatt is an Australian artist currently living in Berlin and working between video, performance and immersive technologies. She is interested in how the dimension of depth in digital moving image can be used as a storytelling device. Her works, often presented in multiple forms, explore contemporary subjectivity and connected bodies as well as the limits between virtual and physical worlds. Over a number of years she has developed a body of work pivoting on stereoscopic photography and video and informed by the history of cinema and broadcast technologies. Her works have been screened and exhibited most recently at Centrale for Contemporary Art in Brussels, New Frontier at the Sundance Film Festival, Les Champs Libres in Rennes and at the ZKM in Karlsruhe.",
"artist": "Lauren Moffatt",
"talk_video_url": "https://vimeo.com/170467514",
"topics": "virtual reality,performance,video art"
},
{
"title": "",
"description": "Onionlab talks about their experience with architecture mappings and how to plan and realize mappings from the idea to the projection itself.
Onionlab is a Barcelona-based multidisciplinary studio that creates interactive products and experiences, motion design movies and audiovisual shows. Their works are based on the aesthetic attention to detail and the technical innovation, making use of the power of scripting and the seduction of music and sound design. Jordi Pont is Onionlabs creative director and has been vjing since 2002 with artistic collectives Lectrovision and Telenoika and also as a resident on Razzmatazz clubs for more than 10 years.",
"artist": "Onionlab",
"talk_video_url": "https://vimeo.com/170467517",
"topics": "mapping,production"
},
{
"title": "MBJ Wetware",
"description": "Marija Bozinovska Jones will elaborate her practice under the pseudonym MBJ Wetware and her approach of live performance as constructing virtual environments extending beyond spatial and audiovisual. She will be covering the conception of GAD Technologies, work commissioned for Club Transmediale 2016 and premiered at Berghain as a collaboration with J G Biberkopf. MBJ will be also presenting her recent work employing voice controlled lasers.
Marija Bozinovska Jones work revolves around identity formation in an era of technocapitalist amplification and perpetual online presence. She explores socio-political implications of planetary scale computation, seeking out apophenic patterns with an array of elements ranging from subcultural formations to totalitarian architecture. Jones explores societys anthropological adaptations intertwined in the framework of networked capitalism, its coping mechanism of coming to terms with challenged ontological axioms of cognition, affection and memory. Under the alias MBJ Wetware, Jones develops immersive live performances simulating heterotopian landscapes.",
"artist": "Marija Bozinovska Jones",
"talk_video_url": "https://vimeo.com/170467518",
"topics": "performance,net art,virtual reality,av"
},
{
"title": "Black Moves",
"description": "Carla Chan introduces us to her aesthetics and the techniques used to create her amorphous, immersive full-dome video 'Black moves'. She will discuss her research into manipulating erratic nature forms in digital and E/M/D/L projects, focusing on different approaches and creation methods in immersive artistic production. Black moves will be presented as a full dome installation at this years festival in the MIRA dome.
Carla Chan is media artist based in Berlin and Hong Kong. She works with a variety of media, such as video, installation, photography and interactive media. Minimal in style and form, Chans works often toy with the blurred boundaries between reality and illusion, figure and abstraction. Her screening Black Moves is selected for showcase at 21st Incubator for Film and Visual media in Asia as a finalist and 22nd International Symposium on Electronic Art (ISEA) in Hong Kong. Black Moves is an immersive video, a spatial drama and a virtual landscape that simulates the forming and de-forming of an amorphous black mass. Black Moves springs from a long obsession and fascination with natural transformations, particularly formless shapes and their movement.",
"artist": "Carla Chan",
"talk_video_url": "https://vimeo.com/170482794",
"topics": "full-dome,research,animation,installation"
}
,
{
"title": "",
"description": "At MIRA Berlin Lauren is going to hold a conference curated by Scope Sessions. She will also participate in the round table focusing on the tools and techniques each artist uses to create unique digital content.",
"artist": "Lauren Moffatt",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/170467514",
"topics": "Video, Inmmersive"
},
@ -142,7 +181,7 @@
"title": "",
"description": "At MIRA Berlin she is holding a conference curated by Scope Sessions. MBJ will also participate in the round table focusing on the tools and techniques each artist uses to create unique digital content.",
"artist": "MBJ Wetware",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/170467518",
"topics": "Society"
},
@ -150,7 +189,7 @@
"title": "",
"description": "Carla Chan is going to hold a conference curated by Scope Sessions and BLACK MOVES will be screened at the MIRA Dome.",
"artist": "Carla Chan",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/170482794",
"topics": "Electronic arts"
}
@ -161,7 +200,7 @@
"title": "'Alice Wonderland meets Monty Python' - (un)imation of Patrick K.-H.",
"description": "(un)imation, unmusic, (un)struments",
"artist": "Patrick K.-H., Andreas Karaoulanis",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/168902369",
"topics": "Drawing, Sound"
},
@ -620,7 +659,7 @@
"title": "50, that next big thing",
"description": "In the past few years weve been eagerly working on a complete rewrite of vvvv which lead to a new visual programming language in combination with a development and runtime environment. In this talk well give you a short introduction into the key features of this new language were internally calling “50″.",
"artist": "Tebjan Halm & Elias Holzer",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/116418592",
"topics": "VVVV,Coding"
}
@ -631,15 +670,15 @@
"title": "Transforma: 2001 bis 2014",
"description": "A chronological presentation of selected works from the world of transforma.",
"artist": "Transforma",
"talk_video_url": "",
"topics": "VJing,Installation,Performance"
"talk_video_url": "https://vimeo.com/115263938",
"topics": "VJ,Installation,Performance"
},
{
"title": "Current Status",
"description": "It's just me showing my work.",
"artist": "Marcel Schwittlick",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/115263939",
"topics": "Coding,Research"
},
@ -647,7 +686,7 @@
"title": "Crossing the border - RANDOM IN ANALOG AND DIGITAL MEDIA",
"description": "Generative factor in a visual message, connected with electronic devices, used in a set of variable objects. Hybrid of media and cultural&philospohical garbology. Reverse engineering.",
"artist": "Marcellina Wellmer",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/115263937",
"topics": "Installation,New Media"
}
@ -696,15 +735,15 @@
"title": "Probing the Past: A Media Archaeology of Handmade Electronic Sound",
"description": "The utopias of electronic sound have hardly changed in its hundred-year history. We still want to imitate existing instruments, create sounds which have never been heard before and realize complex compositions without the need of an orchestra. It is only the tools which have become more complex. But there are dystopias as well, which come especially from using tools designed around other peoples way of creating sound, rather than your own. Instrument builder, teacher and performer Derek Holzer of Macumbista.net will discuss the inspiration of some of the pioneers of 20th Century electronic sound as springboards to some of his own creations, which the audience will have a chance to explore following the talk.",
"artist": "Derek Holzer",
"talk_video_url": "",
"topics": "Media"
"talk_video_url": "https://vimeo.com/107028690",
"topics": "Music,Performance,Sound"
},
{
"title": "Science Inspires Art",
"description": "The talk will focus on how art and science are moving towards one another. It should not be forgotten that both have always been characterised by creative and imaginative processes. Many artist have found their inspiration by the physical and natural world through observation and experiment. Today, new media artist are working on novel ways of scientific communication, searching for the aesthetics on research data and experimenting with new scientific tools. Anyway, who doesnt take a look at the universe, with its sublime and redemptive quality? It makes us all feel small but peaceful.",
"artist": "Imanol Gomez",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/106124225",
"topics": "Science"
},
@ -712,7 +751,7 @@
"title": "Audiovisual Interactions and ludic design for ludic interfaces",
"description": "The talk will review some own project and other state of art related examples around the interactive aspect of live visuals. The use of open source technologies expertise and knowledge share has enhanced the scene of creators and artists looking to use alternative tools for creation of locative and or gesture based media.",
"artist": "Juan Carlos Duarte Regino",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/106124226",
"topics": "Installation"
}
@ -723,7 +762,7 @@
"title": "From a visual journey into another dimension.",
"description": "After introducing themselves and their work, they will focus on the problems for media artists to be part of the traditional gallery-marked in the art business. Even so a lot of Art projects, which use modern technology and try to bring it into a different not consumer-based context, are quite successful, a lot of them are being displayed only in festivals or as digital copies in the internet, rather then being shown in privat galleries. This implements that the creators make a living either from grants, teaching, very small fees or they finance their free art work with client-based commissions. The reasons for this are manifold. A lot of projects are technical experiments on a larger scale, which can hardly be sold as an peace of art that the client could simply place or even hang in his home. Another reason is the fact that a lot of Media Artists rather work on a very conceptual level, creating work that is either only excisting in digital form,very much created for certain spaces or react to certain appearings of modern society. So whenever you would take this projects out of their context they would not make any sense at all.",
"artist": "Quadrature",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/168940417",
"topics": "Design,hardware,Installation"
},
@ -731,8 +770,8 @@
"title": "How to have fun with a six channel guitar pckup",
"description": "Puckette demonstrates what happens when you put individual pickup coils on each string of your guitar, opening up a wide range of sonic possibilities beyond what you can get out of an ordinary pickup. Techniques like filtering and distortion can be applied to the signals before they're mixed. This makes it possible to get results that are both rich sounding and precisely controllable. The software to do this is open source, free to download.",
"artist": "Miller Puckette",
"talk_video_url": "",
"topics": "VVVV,Coding,Sound"
"talk_video_url": "https://vimeo.com/104694866",
"topics": "Software,Coding,Sound,Music"
},
{
@ -777,7 +816,7 @@
"title": "Make love not art",
"description": "die LiCHTPiRATEN zeigen uns, dass nichts aussehen muss wie es gerade scheint langsam begreifen wir, dass wir in einer kuenstlichen welt leben, die aussieht wie sie aussehen soll. die oberflaeche der dinge die uns bestimmen sind erdacht, gestaltet und in unseren alltag geschmuggelt. die LiCHTPiRATEN kapern das antlitz von etwas, uebernehmen darueber kontrolle, zeichnen um, deuten an. Schicht fuer schicht verschmelzen die ebenen der wahrnehmeung und hinterlassen ein vibrieren in der seele, dass daran erinnert: es ist leicht frei zu sein.",
"artist": "Lichtpiraten",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/168922087",
"topics": "Installation,Light"
},
@ -804,29 +843,50 @@
"title": "Guruguru kun",
"description": "Chuuu recently works on the intersection of noise music and live drawings. In his talk, we will give some close-ups to art practices. Follow him on his blog: chuuu.hateblo.jp",
"artist": "Vj Chuu",
"talk_video_url": "",
"topics": "VJing"
"talk_video_url": "https://vimeo.com/93984046",
"topics": "VJ"
},
{
"title": "",
"description": "",
"artist": "Mahir Duman",
"talk_video_url": "",
"topics": "Interactive,Live,Performance"
"talk_video_url": "https://vimeo.com/94032038",
"topics": "Interactive,Performance"
},
{
"title": "",
"description": "During three years Trashpuzzle developed. New people joined the group, equipment has evolved and they gave dozens of shows in clubs around Berlin and other cities. Antique episcope has been replaced by beamer. The transport band is filmed by a live mix of two cameras that are hidden in a black box. And the group expanded to five members, who are pushing the idea forward and have a lot of fun.",
"artist": "Trashpuzzle",
"talk_video_url": "",
"talk_video_url": "https://vimeo.com/94004373",
"topics": "Performance"
}
,
{
"title": "",
"description": "Martin Mayer is a visual artist and VJ based in Munich. Studying media art at the Munich Academy of Fine Arts, he is co-founder of the multimedia art duo mayer+empl.
Specialized in interior and exterior mappings highlighting architectural and physical conditions of the space - their projections are creating entirely new atmospheric spaces.",
"artist": "Martin Mayer",
"talk_video_url": "https://vimeo.com/93069064",
"topics": "mapping,vj"
},
{
"title": "Mixing Art and Science",
"description": "Life sciences and visual arts can fuel each other. Good visualization is pivotal for biological and chemical sciences to illustrate and transmit information.
Protein dynamics and ligand-protein interactions can serve as a canvas for story-telling, and the concept of periodic boundary conditions (PBC) used in molecular simulations, can be exploited as a parallel to the concept of social roles. And such concepts and tools can actually be used by visual artists in their work...",
"artist": "Agnieszka Bronka Bronowska",
"talk_video_url": "https://vimeo.com/93069065",
"topics": "science,dance,research"
}
,
{
"title": "Sinsynplus",
"description": "After his talk, Martin will immediately change spaces and head back to zeitraum.exit to prepare his performance project , that will be performed at 10pm! Will will join them after our session!",
@ -867,7 +927,7 @@
"description": "Valentina will present her project “Berg“, an exploration of Teufelsberg Listening Station comprising a video and a GPS triggered soundscape for iPhone and iPad.",
"artist": "Valentina Ferrandes",
"talk_video_url": "https://vimeo.com/89011441",
"topics": "Video,Sound"
"topics": "Software,Sound"
},
{
@ -875,7 +935,7 @@
"description": "Drøp is an electronic music project born in Berlin in 2010 by Giuseppe Bifulcosound designer and engineer. It focuses on sounds investigation and experimentation, not that much in an aesthetic meaning, rather than in a perceptual and sensorial one, considering the sound as a bundle of informations that deal with psycho-acoustic and music therapy.",
"artist": "Andrea Familari aka. Fax ",
"talk_video_url": "http://vimeo.com/88436760",
"topics": "VJing,Mapping"
"topics": "VJ,Mapping"
}
,
@ -932,7 +992,7 @@
"description": "David Szauder will present touch.gl, an app to create a glitch composition using your fingers. glitch.gl offers several glitch method options, noizes, databending, offsets for composition from different sources, such as camera input or image files. touch.gl was recently exhibited in the Centre Pompidou (Paris, France), during the show called DigitART organised and curated by Abdel Bounane. He will also premiere the latest soon to be released 6th version of his other application GlitchPatternGenerator. The audiencewill have the chance to play with both apps after the presentation.",
"artist": "pixelnoizz",
"talk_video_url": "http://vimeo.com/77971353",
"topics": "Glitch,Pixel"
"topics": "Glitch,Net art,generative,coding,software"
},
{
@ -978,7 +1038,7 @@
"description": "",
"artist": "Joel Dittrich",
"talk_video_url": "http://vimeo.com/70332059",
"topics": "Research,Project"
"topics": "Research,Av,Music,VJ"
},
{
@ -994,7 +1054,7 @@
"description": "As VJ Juladi she creates new imagery and makes sounds visible. She specializes in analog and handmade visuals. Responding live to music, she experiments with the movements of her hands and body in addition to placing various objects in front of the camera: feathers, leafs, fabrics, fire, etc. to create mesmerizing effects which are sent through a video mixer and out to a screen. For the last few years she has also been using her whole body for the visuals, starting to dance, perform and move in front of the screen. The pictures which appear are always different. Simple hand movements result in intriguing patterns and shapes on the screen …. which sometimes even look like birds or digital animated forms.",
"artist": "VJ Juladi",
"talk_video_url": "https://vimeo.com/72834682",
"topics": "Vjing"
"topics": "Vj"
}
,
@ -1020,8 +1080,8 @@
"title": "Kunst, Kultur & Kino Collage",
"description": "“Kunst, Kultur & Kino Kollage” will be an examination of the process of re-appropriating the images and sounds of pop culture, propaganda, educational films, and the tools of the populist media to create subversive audiovisual art. The talk will feature an analysis of the creation of the debut ReVerse Bullets album, “Drapetomania!,” along with a preview of new material collaborated with Nicolo Sommer (BIINDS).",
"artist": "ReVerse Bullets",
"talk_video_url": "",
"topics": "Collective,Activism"
"talk_video_url": "https://vimeo.com/168901581",
"topics": "Av,Music,Politics"
}
,
@ -1051,7 +1111,7 @@
"description": "In 2010 theyve started their audio-visual noise project Domestic Violence, which merges field recordings, live coding and audio-responsive glitches, by using self-made interfaces, controllers and patches. Domestic Violence performed in Finland, Germany, UK, Italy and Poland. work by Tikul & Jendre has been presented at digital arts and video festivals around the world. They are constantly trying to challenge the viewer, through exploration of identity / queerness of human body / architectural objects and their transformations, synthetic-organic textures, glitch aesthetics, physicality of image and sound.Their works are attempting to bend the perception of time intensify the senses and reactivate the dismissed areas of psyche.",
"artist": "pussykrew",
"talk_video_url": "http://vimeo.com/65547327",
"topics": "3D,AV Performance"
"topics": "3D,AV"
},
{
@ -1105,7 +1165,7 @@
"description": "Geso is the moniker he uses for his most personal and experimental work, specially focused in video-art and visual performances. His videos are a combination of glitches, geometric graphics, landscapes and images from nature, evoking a short of lost paradise or residual image from a better world. The concepts that often dominate his work are related to different levels of communication and its paradoxes, the digital language and errors, usually revealing a connection with different aspects from human conscience and spirituality, like altered states of mind.",
"artist": "Geso",
"talk_video_url": "https://vimeo.com/62081169",
"topics": "Design,AV Performance"
"topics": "Design,AV"
},
{
@ -1124,7 +1184,7 @@
"description": "Jem about her Talk: “For scope sessions I will present a selection of projects from 2012 that range from large scale festival VJing to new AV collaborations, as well as the strange world of VJ competitions. Through these projects I will give some insight into my background and work process and discuss how the immediacy of Vjing and the processes of improvisation and performance have been useful techniques in the development of new ideas.”",
"artist": "Jem The Misfit",
"talk_video_url": "https://vimeo.com/56904567",
"topics": "AV Performance"
"topics": "AV"
},
{
@ -1132,7 +1192,7 @@
"description": "In his talk he gives an insight to his special mix of violin play, computer synthetics, video timelines and ideas about it.",
"artist": "Zan Lyons",
"talk_video_url": "https://vimeo.com/56907705",
"topics": "AV Performance,Music"
"topics": "AV,Music"
},
{
@ -1178,7 +1238,7 @@
"description": "In his talk, A. N. Fischer is going to talk about his artwork “Schwarm”, a software that creates constantly changing, abstract composition running in real time. As this work comes to life through software that executes a coded behaviour, the computer system becomes an integral part of the creation and perception of the artwork itself.",
"artist": "Andreas Nicolas Fischer",
"talk_video_url": "https://vimeo.com/52136497",
"topics": "Interaction,Generative,Coding"
"topics": "Interactive,Generative,Coding"
},
{
@ -1186,7 +1246,7 @@
"description": "With his background in computer science and automation technology, he started developing interactive systems in 1993. For many years he was codirector of Palindrome Performance group, developing media performances which toured worldwide and have received numerous awards. While his early works were focusing on movement-to-sound relations using bioelectrical sensor devices as well as video motion sensing, he continued with a focus on connecting interactive visuals with the body itself. He developed the video technologies and interactive stage projections for Chunky Moves recent intermedia works Glow and Mortal engine. For his contribution on Glow he was rewarded with a Green room award for Design in Dance. Both Pieces have been touring for many years now, including venues like BAM, New York, The Edinburgh Festival, The Sydney Opera house.",
"artist": "Frieder Weiss",
"talk_video_url": "https://vimeo.com/52208994",
"topics": "Performance,Dance,Interaction"
"topics": "Performance,Dance,Interactive"
},
{
@ -1194,7 +1254,7 @@
"description": "In his talk, he will give some insight into how mathematical modelling can be used as an artistic tool to break the determinism of man-machine interaction and create a corporeal experience in a world without haptic feedback.",
"artist": "Felix Bonowski",
"talk_video_url": "https://vimeo.com/52134418",
"topics": "Interaction,Software"
"topics": "Interactive,Software"
}
,
@ -1227,6 +1287,58 @@
,
{
"title": "AV-Invader Mapping",
"description": "Laura is a visual arts lover dedicated to direct and produce live visuals projects and experimental pieces for commercial brands, art exhibitions and worldwide academic presentations. She produces herself and runs her own laboratory and audiovisual label "Optikal Ink Lab", an independent project dedicated to create AV works and aimed to integrate digital arts, video projections, video mapping and real-time narratives.",
"artist": "Laura Ramirez (OptikaVJ)",
"talk_video_url": "https://vimeo.com/43841396",
"topics": "mapping,av"
},
{
"title": "TouchOSC & TouchViz",
"description": "Dr. Mo talks with Robert about his Apps:
TouchOSC
Modular OSC and MIDI control surface for iPhone / iPod Touch / iPad Sends and receives Open Sound Control messages over a Wi-Fi network using the UDP protocol and supports both CoreMIDI and the Line 6 MIDI Mobilizer interfaces for sending and receiving MIDI messages.
TouchViZ
Professional, portable VJ system for iPad 2 At home or in the club, professionally or just for fun, you can now create impressive visuals straight from your iPad.",
"artist": "Robert Fischer (Hexler)",
"talk_video_url": "https://vimeo.com/43849383",
"topics": "coding,software"
},
{
"title": ""Lava" Live Dance Performance",
"description": "Andreas Karaoulanis comes from a Computer Science and Animation background. His current work deals with interactive media design and animation. He has present his work in Museum Of London, Moscow, Paris and in various Galleries and spaces around Europe. One of his latest projects is "bestbefore", an online interactive showcase blog.
Together with Katerina Liana presented at LPM 2012 their Live Performance called Lava where Dance meets Visuals.",
"artist": "Andreas Karaoulanis & Katerina Liana",
"talk_video_url": "https://vimeo.com/43857617",
"topics": "dance,performance,animation"
},
{
"title": "VVVV and IRIS VJ tool",
"description": "vvvv is a hybrid graphical/textual programming environment for easy prototyping and development. It is designed to facilitate the handling of large media environments with physical interfaces, real-time motion graphics, audio and video that can interact with many users simultaneously.
IRIS Interactive Realtime Image Synthesizer is a powerful software platform for realtime image synthesis, video compositing and spatial media design.
MESO is working on the border line between technology and design offering an integrated view on digital media system design.",
"artist": "Valerie & David ( Meso )",
"talk_video_url": "https://vimeo.com/43857618",
"topics": "software,vj,coding"
},
{
"title": "Origin, present and future of Live Cinema",
"description": "The Light Surgeons is a collective of pioneering multimedia artists founded in 1995 by creative director Christopher Thomas Allen.
It now functions as an media arts production company which develops new work in a diverse range of mediums; print, photography, motion graphics, digital film production, exhibitions, installations and ground breaking live audio visual performances.
Toby harris A.K.A *spark is a digital media maverick, he crosses the disciplines of artist, designer and engineer in the pursuit of anything that uses media to make people interact or think in unexpected ways.",
"artist": "Toby Harris (*spark) & Light Surgeons",
"talk_video_url": "https://vimeo.com/43962834",
"topics": "live cinema,vj,performance,av"
}
,
{
"title": "CAS presentation",
"description": "Dalibor will introduce us the department and the areas they work in, but centerpiece of this talk is show some of the spectrum of works being done by the students.",
@ -1289,6 +1401,17 @@
,
{
"title": "AV in Austria",
"description": "Interview mit Eva Bischof (4youreye) und Lisa Malle (Frau Fitzke), zwei langjährigen Protagonistinnen der Wiener Visualistenszene - im Gespräch über das ehemalige internationale VJ Festival "Contact Europe", dem jährlich von ihnen organiserten "AV Playground" und die Szene in Österreich. Das Interview entstand im März 2012 im Rahmen des B-sEite Festival für Jetztkultur in Mannheim in Kooperation mit armitage.tv",
"artist": "4youreye & Frau Fitzke",
"talk_video_url": "https://vimeo.com/43736732",
"topics": "festival,VJ"
}
,
{
"title": "",
"description": "In their presentation Shai Levy and Marc Tiedemann will give a live performance of their app, talk about its development through the many stages of conceptualizing, researching and creating and will share their thoughts on the pros and cons of using a touch-screen a creative medium.",
@ -1320,8 +1443,8 @@
"title": "",
"description": "",
"artist": "MFO",
"talk_video_url": "",
"topics": "AV,Perfomance"
"talk_video_url": "https://vimeo.com/39914745",
"topics": "AV,Performance"
},
{
@ -1348,7 +1471,7 @@
"description": "A technique that can be used in various forms, from live dj ing to theater and dance performances. Software used VDMX ,a firewire camera plus lots of white A3 papers, black markers!",
"artist": "Andreas Karaoulanis",
"talk_video_url": "",
"topics": "Perfomance,Illustration"
"topics": "Performance,Illustration"
},
{
@ -1362,6 +1485,49 @@
,
{
"title": "roBOt Festival",
"description": "In an interview with Eklis Rellüm, Francesco Salizzoni talks about the annual robot festival in Bologna, Italy",
"artist": "Francesco Salizzoni",
"talk_video_url": "https://vimeo.com/35201883",
"topics": "festival"
},
{
"title": "Freemote Festival",
"description": "In an interview with Eklis Rellüm, Willem van der Schans talks about the annual FREEMOTE festival in Utrecht, Netherlands",
"artist": "Willem van der Schans",
"talk_video_url": "https://vimeo.com/35209282",
"topics": "Festival"
},
{
"title": "Elektro Moon Vision",
"description": "In an interview with Eklis Rellüm, Elwira Wojtunik and Popesz Csaba Láng of Elektro Moon Vision talk about their installation at FREEMOTE and their planned future festival in Kraków, Poland",
"artist": "Elektro Moon Vision",
"talk_video_url": "https://vimeo.com/35213957",
"topics": "installation,festival"
},
{
"title": "Live Performers Meeting",
"description": "In an interview with Eklis Rellüm, Ioann Maria and Gianluca del Gobbo talk about their Live Performers Meeting (LPM) that takes place every year in Rome, IT",
"artist": "Live Performers Meeting",
"talk_video_url": "https://vimeo.com/36078765",
"topics": "festival"
},
{
"title": "B-Seite Festival",
"description": "In einem Interview mit Eklis Rellüm spricht Benjamin Jantzen über das B-Seite Festival für Jetztkultur in Mannheim, DE",
"artist": "Benjamin Jantzen",
"talk_video_url": "https://vimeo.com/36141129",
"topics": "festival"
}
,
{
"title": "",
"description": "Tetsuya Hori and Yurie Ido will present their video performance “dead” and explain their collaborative work.",

View file

@ -6,8 +6,8 @@
</description>
<link>http://scopesessions.org/</link>
<atom:link href="http://scopesessions.org /feed.xml " rel="self" type="application/rss+xml" />
<pubDate>Mon, 16 Jan 2017 00:32:48 +0100</pubDate>
<lastBuildDate>Mon, 16 Jan 2017 00:32:48 +0100</lastBuildDate>
<pubDate>Sun, 22 Jan 2017 18:31:03 +0100</pubDate>
<lastBuildDate>Sun, 22 Jan 2017 18:31:03 +0100</lastBuildDate>
<generator>Jekyll v3.1.2</generator>
<item>
@ -82,6 +82,18 @@
</item>
<item>
<title>Scope @ MIRA Berlin</title>
<description>
</description>
<pubDate>Sat, 11 Jun 2016 00:00:00 +0200</pubDate>
<link>http://scopesessions.org/special/2016/06/11/MIRA.html</link>
<guid isPermaLink="true">http://scopesessions.org/special/2016/06/11/MIRA.html</guid>
<category>special</category>
</item>
<item>
<title>Scope @ MIRA FEstival Berlin</title>
<description>
@ -118,17 +130,5 @@
</item>
<item>
<title>053</title>
<description>
</description>
<pubDate>Thu, 10 Mar 2016 00:00:00 +0100</pubDate>
<link>http://scopesessions.org/session/2016/03/10/053.html</link>
<guid isPermaLink="true">http://scopesessions.org/session/2016/03/10/053.html</guid>
<category>session</category>
</item>
</channel>
</rss>

File diff suppressed because it is too large Load diff

View file

@ -80,7 +80,7 @@
</tbody>
</table>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more