diff options
author | David DeSandro <desandrocodes@gmail.com> | 2016-07-08 14:17:15 -0400 |
---|---|---|
committer | David DeSandro <desandrocodes@gmail.com> | 2016-07-08 14:17:15 -0400 |
commit | fc6489dfee7c9a5c76fe0dfda564d5b5097ce543 (patch) | |
tree | 0138c05ce2c02c50e47df7780261989a69023d79 | |
parent | 11b6840146534c4f4265dc4f6f8fd942c377550b (diff) | |
parent | adf5f1c45373e69b38e179b13325ba18b6bb0846 (diff) | |
download | flickity-fc6489dfee7c9a5c76fe0dfda564d5b5097ce543.zip flickity-fc6489dfee7c9a5c76fe0dfda564d5b5097ce543.tar.gz flickity-fc6489dfee7c9a5c76fe0dfda564d5b5097ce543.tar.bz2 |
Merge branch 'v2'
55 files changed, 1850 insertions, 969 deletions
@@ -1,6 +1,6 @@ # Flickity -_Touch, responsive, flickable galleries_ +_Touch, responsive, flickable carousels_ See [flickity.metafizzy.co](http://flickity.metafizzy.co) for complete docs and demos. @@ -9,26 +9,26 @@ See [flickity.metafizzy.co](http://flickity.metafizzy.co) for complete docs and ### Download + CSS: - - [flickity.css](https://github.com/metafizzy/flickity/raw/master/dist/flickity.css) un-minified, or - - [flickity.css](https://github.com/metafizzy/flickity/raw/master/dist/flickity.min.css) minified + - [flickity.css](https://github.com/metafizzy/flickity/raw/master/dist/flickity.min.css) minified, or + - [flickity.css](https://github.com/metafizzy/flickity/raw/master/dist/flickity.css) un-minified + JavaScript: - - [flickity.pkgd.js](https://github.com/metafizzy/flickity/raw/master/dist/flickity.pkgd.js) un-minified, or - - [flickity.pkgd.min.js](https://github.com/metafizzy/flickity/raw/master/dist/flickity.pkgd.min.js) minified + - [flickity.pkgd.min.js](https://github.com/metafizzy/flickity/raw/master/dist/flickity.pkgd.min.js) minified, or + - [flickity.pkgd.js](https://github.com/metafizzy/flickity/raw/master/dist/flickity.pkgd.js) un-minified ### CDN Link directly to [Flickity files on cdnjs](https://cdnjs.com/libraries/flickity). ``` html -<link rel="stylesheet" href="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.css"> -<!-- or --> <link rel="stylesheet" href="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.min.css"> +<!-- or --> +<link rel="stylesheet" href="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.css"> ``` ``` html -<script src="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.js"></script> -<!-- or --> <script src="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.min.js"></script> +<!-- or --> +<script src="https://npmcdn.com/flickity@1.2/dist/flickity.pkgd.js"></script> ``` ### Package managers @@ -54,10 +54,10 @@ If you are creating an open source application under a license compatible with t Flickity works with a container element and a set of child cell elements ``` html -<div class="gallery"> - <div class="cell">...</div> - <div class="cell">...</div> - <div class="cell">...</div> +<div class="carousel"> + <div class="carousel-cell">...</div> + <div class="carousel-cell">...</div> + <div class="carousel-cell">...</div> ... </div> ``` @@ -71,6 +71,9 @@ var flky = new Flickity( '.gallery', { accessibility: true, // enable keyboard navigation, pressing left & right keys + adaptiveHeight: false, + // set carousel height to the selected slide + autoPlay: false, // advances to the next cell // if true, default is 3 seconds @@ -92,6 +95,10 @@ var flky = new Flickity( '.gallery', { draggable: true, // enables dragging & flicking + dragThreshold: 3, + // number of pixels a user must scroll horizontally to start dragging + // increase to allow more room for vertical scroll for touch devices + freeScroll: false, // enables content to be freely scrolled and flicked // without aligning cells @@ -99,6 +106,9 @@ var flky = new Flickity( '.gallery', { friction: 0.2, // smaller number = easier to flick farther + groupCells: false, + // group cells together in slides + initialIndex: 0, // zero-based index of the initial selected cell @@ -131,8 +141,6 @@ var flky = new Flickity( '.gallery', { watchCSS: false, // watches the content of :after of the element // activates if #element:after { content: 'flickity' } - // IE8 and Android 2.3 do not support watching :after - // set watch: 'fallbackOn' to enable for these browsers wrapAround: false // at end of cells, wraps-around to first for infinite scrolling @@ -1,28 +1,23 @@ { "name": "flickity", - "version": "1.2.1", "description": "Touch, responsive, flickable galleries", "main": [ "js/index.js", "css/flickity.css" ], "dependencies": { - "classie": "~1.0.1", - "doc-ready": "~1.0.4", - "eventEmitter": "~4.2.11", - "eventie": "~1.0.5", - "fizzy-ui-utils": "~1.0.1", - "get-size": "~1.2.2", - "get-style-property": "~1.0.4", - "matches-selector": "~1.0.2", - "tap-listener": "~1.1.1", - "unidragger": "~1.1.5" + "desandro-matches-selector": "^2.0.0", + "ev-emitter": "^1.0.2", + "fizzy-ui-utils": "^2.0.0", + "get-size": "^2.0.0", + "tap-listener": "^2.0.0", + "unidragger": "^2.1.0" }, "devDependencies": { - "flickity-imagesloaded": "~1.0.0", - "flickity-as-nav-for": "~1.0.0", - "jquery-bridget": "~1.1.0", - "qunit": "~1.16.0" + "flickity-imagesloaded": "v2", + "flickity-as-nav-for": "v2", + "jquery-bridget": "^2.0.0", + "qunit": "^2.0.0" }, "moduleType": [ "amd", diff --git a/css/flickity.css b/css/flickity.css index bb62af2..7c8dc92 100644 --- a/css/flickity.css +++ b/css/flickity.css @@ -56,7 +56,6 @@ http://flickity.metafizzy.co cursor: pointer; /* vertically center */ -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); transform: translateY(-50%); } @@ -68,7 +67,6 @@ http://flickity.metafizzy.co } .flickity-prev-next-button:active { - filter: alpha(opacity=60); /* IE8 */ opacity: 0.6; } @@ -85,7 +83,6 @@ http://flickity.metafizzy.co } .flickity-prev-next-button:disabled { - filter: alpha(opacity=30); /* IE8 */ opacity: 0.3; cursor: auto; } @@ -102,12 +99,6 @@ http://flickity.metafizzy.co fill: #333; } -/* color & size if no SVG - IE8 and Android 2.3 */ -.flickity-prev-next-button.no-svg { - color: #333; - font-size: 26px; -} - /* ---- page dots ---- */ .flickity-page-dots { @@ -130,12 +121,10 @@ http://flickity.metafizzy.co margin: 0 8px; background: #333; border-radius: 50%; - filter: alpha(opacity=25); /* IE8 */ opacity: 0.25; cursor: pointer; } .flickity-page-dots .dot.is-selected { - filter: alpha(opacity=100); /* IE8 */ opacity: 1; } diff --git a/gulpfile.js b/gulpfile.js index 92b4215..49dadd6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -39,54 +39,9 @@ gulp.task( 'hint', [ 'hint-js', 'hint-test', 'hint-task', 'jsonlint' ]); // -------------------------- RequireJS makes pkgd -------------------------- // -// refactored from gulp-requirejs-optimize -// https://www.npmjs.com/package/gulp-requirejs-optimize/ - var gutil = require('gulp-util'); -var through = require('through2'); -var requirejs = require('requirejs'); var chalk = require('chalk'); - -function rjsOptimize( options ) { - var stream; - - requirejs.define('node/print', [], function() { - return function(msg) { - if( msg.substring(0, 5) === 'Error' ) { - gutil.log( chalk.red( msg ) ); - } else { - gutil.log( msg ); - } - }; - }); - - options = options || {}; - - stream = through.obj(function (file, enc, cb) { - if ( file.isNull() ) { - this.push( file ); - return cb(); - } - - options.logLevel = 2; - - options.out = function( text ) { - var outFile = new gutil.File({ - path: file.relative, - contents: new Buffer( text ) - }); - cb( null, outFile ); - }; - - gutil.log('RequireJS optimizing'); - requirejs.optimize( options, null, function( err ) { - var gulpError = new gutil.PluginError( 'requirejsOptimize', err.message ); - stream.emit( 'error', gulpError ); - }); - }); - - return stream; -} +var rjsOptimize = require('gulp-requirejs-optimize'); // regex for banner comment var reBannerComment = new RegExp('^\\s*(?:\\/\\*[\\s\\S]*?\\*\\/)\\s*'); @@ -111,7 +66,7 @@ gulp.task( 'requirejs', function() { baseUrl: 'bower_components', optimize: 'none', include: [ - 'jquery-bridget/jquery.bridget', + 'jquery-bridget/jquery-bridget', 'flickity/js/index', 'flickity-as-nav-for/as-nav-for', 'flickity-imagesloaded/flickity-imagesloaded' diff --git a/js/add-remove-cell.js b/js/add-remove-cell.js index aa5b746..8b9e038 100644 --- a/js/add-remove-cell.js +++ b/js/add-remove-cell.js @@ -1,7 +1,7 @@ +// add, remove cell ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ @@ -10,7 +10,7 @@ ], function( Flickity, utils ) { return factory( window, Flickity, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, @@ -33,21 +33,22 @@ // append cells to a document fragment function getCellsFragment( cells ) { var fragment = document.createDocumentFragment(); - for ( var i=0, len = cells.length; i < len; i++ ) { - var cell = cells[i]; + cells.forEach( function( cell ) { fragment.appendChild( cell.element ); - } + }); return fragment; } // -------------------------- add/remove cell prototype -------------------------- // +var proto = Flickity.prototype; + /** * Insert, prepend, or append cells * @param {Element, Array, NodeList} elems * @param {Integer} index */ -Flickity.prototype.insert = function( elems, index ) { +proto.insert = function( elems, index ) { var cells = this._makeCells( elems ); if ( !cells || !cells.length ) { return; @@ -84,11 +85,11 @@ Flickity.prototype.insert = function( elems, index ) { this._cellAddedRemoved( index, selectedIndexDelta ); }; -Flickity.prototype.append = function( elems ) { +proto.append = function( elems ) { this.insert( elems, this.cells.length ); }; -Flickity.prototype.prepend = function( elems ) { +proto.prepend = function( elems ) { this.insert( elems, 0 ); }; @@ -96,18 +97,19 @@ Flickity.prototype.prepend = function( elems ) { * Remove cells * @param {Element, Array, NodeList} elems */ -Flickity.prototype.remove = function( elems ) { +proto.remove = function( elems ) { var cells = this.getCells( elems ); var selectedIndexDelta = 0; - var i, len, cell; + var len = cells.length; + var i, cell; // calculate selectedIndexDelta, easier if done in seperate loop - for ( i=0, len = cells.length; i < len; i++ ) { + for ( i=0; i < len; i++ ) { cell = cells[i]; - var wasBefore = utils.indexOf( this.cells, cell ) < this.selectedIndex; + var wasBefore = this.cells.indexOf( cell ) < this.selectedIndex; selectedIndexDelta -= wasBefore ? 1 : 0; } - for ( i=0, len = cells.length; i < len; i++ ) { + for ( i=0; i < len; i++ ) { cell = cells[i]; cell.remove(); // remove item from collection @@ -121,27 +123,29 @@ Flickity.prototype.remove = function( elems ) { }; // updates when cells are added or removed -Flickity.prototype._cellAddedRemoved = function( changedCellIndex, selectedIndexDelta ) { +proto._cellAddedRemoved = function( changedCellIndex, selectedIndexDelta ) { + // TODO this math isn't perfect with grouped slides selectedIndexDelta = selectedIndexDelta || 0; this.selectedIndex += selectedIndexDelta; - this.selectedIndex = Math.max( 0, Math.min( this.cells.length - 1, this.selectedIndex ) ); + this.selectedIndex = Math.max( 0, Math.min( this.slides.length - 1, this.selectedIndex ) ); - this.emitEvent( 'cellAddedRemoved', [ changedCellIndex, selectedIndexDelta ] ); this.cellChange( changedCellIndex, true ); + // backwards compatibility + this.emitEvent( 'cellAddedRemoved', [ changedCellIndex, selectedIndexDelta ] ); }; /** * logic to be run after a cell's size changes * @param {Element} elem - cell's element */ -Flickity.prototype.cellSizeChange = function( elem ) { +proto.cellSizeChange = function( elem ) { var cell = this.getCell( elem ); if ( !cell ) { return; } cell.getSize(); - var index = utils.indexOf( this.cells, cell ); + var index = this.cells.indexOf( cell ); this.cellChange( index ); }; @@ -149,11 +153,12 @@ Flickity.prototype.cellSizeChange = function( elem ) { * logic any time a cell is changed: added, removed, or size changed * @param {Integer} changedCellIndex - index of the changed cell, optional */ -Flickity.prototype.cellChange = function( changedCellIndex, isPositioningSlider ) { +proto.cellChange = function( changedCellIndex, isPositioningSlider ) { var prevSlideableWidth = this.slideableWidth; this._positionCells( changedCellIndex ); this._getWrapShiftCells(); this.setGallerySize(); + this.emitEvent( 'cellChange', [ changedCellIndex ] ); // position slider if ( this.options.freeScroll ) { // shift x by change in slideableWidth diff --git a/js/animate.js b/js/animate.js index 6fc8540..a8112b3 100644 --- a/js/animate.js +++ b/js/animate.js @@ -1,20 +1,18 @@ +// animate ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'get-style-property/get-style-property', 'fizzy-ui-utils/utils' - ], function( getStyleProperty, utils ) { - return factory( window, getStyleProperty, utils ); + ], function( utils ) { + return factory( window, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('desandro-get-style-property'), require('fizzy-ui-utils') ); } else { @@ -22,51 +20,30 @@ window.Flickity = window.Flickity || {}; window.Flickity.animatePrototype = factory( window, - window.getStyleProperty, window.fizzyUIUtils ); } -}( window, function factory( window, getStyleProperty, utils ) { +}( window, function factory( window, utils ) { 'use strict'; // -------------------------- requestAnimationFrame -------------------------- // -// https://gist.github.com/1866474 +// get rAF, prefixed, if present +var requestAnimationFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame; +// fallback to setTimeout var lastTime = 0; -var prefixes = 'webkit moz ms o'.split(' '); -// get unprefixed rAF and cAF, if present -var requestAnimationFrame = window.requestAnimationFrame; -var cancelAnimationFrame = window.cancelAnimationFrame; -// loop through vendor prefixes and get prefixed rAF and cAF -var prefix; -for( var i = 0; i < prefixes.length; i++ ) { - if ( requestAnimationFrame && cancelAnimationFrame ) { - break; - } - prefix = prefixes[i]; - requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ]; - cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] || - window[ prefix + 'CancelRequestAnimationFrame' ]; -} - -// fallback to setTimeout and clearTimeout if either request/cancel is not supported -if ( !requestAnimationFrame || !cancelAnimationFrame ) { +if ( !requestAnimationFrame ) { requestAnimationFrame = function( callback ) { var currTime = new Date().getTime(); var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); - var id = window.setTimeout( function() { - callback( currTime + timeToCall ); - }, timeToCall ); + var id = setTimeout( callback, timeToCall ); lastTime = currTime + timeToCall; return id; }; - - cancelAnimationFrame = function( id ) { - window.clearTimeout( id ); - }; } // -------------------------- animate -------------------------- // @@ -99,20 +76,16 @@ proto.animate = function() { _this.animate(); }); } - - /** / - // log animation frame rate - var now = new Date(); - if ( this.then ) { - console.log( ~~( 1000 / (now-this.then)) + 'fps' ) - } - this.then = now; - /**/ }; -var transformProperty = getStyleProperty('transform'); -var is3d = !!getStyleProperty('perspective'); +var transformProperty = ( function () { + var style = document.documentElement.style; + if ( typeof style.transform == 'string' ) { + return 'transform'; + } + return 'WebkitTransform'; +})(); proto.positionSlider = function() { var x = this.x; @@ -124,7 +97,6 @@ proto.positionSlider = function() { } x = x + this.cursorPosition; - // reverse if right-to-left and using transform x = this.options.rightToLeft && transformProperty ? -x : x; @@ -133,19 +105,25 @@ proto.positionSlider = function() { if ( transformProperty ) { // use 3D tranforms for hardware acceleration on iOS // but use 2D when settled, for better font-rendering - this.slider.style[ transformProperty ] = is3d && this.isAnimating ? + this.slider.style[ transformProperty ] = this.isAnimating ? 'translate3d(' + value + ',0,0)' : 'translateX(' + value + ')'; } else { this.slider.style[ this.originSide ] = value; } + // scroll event + var firstSlide = this.slides[0]; + if ( firstSlide ) { + var positionX = -this.x - firstSlide.target; + var progress = positionX / this.slidesWidth; + this.emitEvent( 'scroll', [ progress, positionX ] ); + } }; proto.positionSliderAtSelected = function() { if ( !this.cells.length ) { return; } - var selectedCell = this.cells[ this.selectedIndex ]; - this.x = -selectedCell.target; + this.x = -this.selectedSlide.target; this.positionSlider(); }; @@ -169,9 +147,7 @@ proto.settle = function( previousX ) { this.isAnimating = false; delete this.isFreeScrolling; // render position with translateX when settled - if ( is3d ) { - this.positionSlider(); - } + this.positionSlider(); this.dispatchEvent('settle'); } }; @@ -186,7 +162,7 @@ proto.shiftWrapCells = function( x ) { }; proto._shiftCells = function( cells, gap, shift ) { - for ( var i=0, len = cells.length; i < len; i++ ) { + for ( var i=0; i < cells.length; i++ ) { var cell = cells[i]; var cellShift = gap > 0 ? shift : 0; cell.wrapShift( cellShift ); @@ -198,7 +174,7 @@ proto._unshiftCells = function( cells ) { if ( !cells || !cells.length ) { return; } - for ( var i=0, len = cells.length; i < len; i++ ) { + for ( var i=0; i < cells.length; i++ ) { cells[i].wrapShift( 0 ); } }; @@ -206,22 +182,18 @@ proto._unshiftCells = function( cells ) { // -------------------------- physics -------------------------- // proto.integratePhysics = function() { - this.velocity += this.accel; this.x += this.velocity; this.velocity *= this.getFrictionFactor(); - // reset acceleration - this.accel = 0; }; proto.applyForce = function( force ) { - this.accel += force; + this.velocity += force; }; proto.getFrictionFactor = function() { return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ]; }; - proto.getRestingPosition = function() { // my thanks to Steven Wittens, who simplified this math greatly return this.x + this.velocity / ( 1 - this.getFrictionFactor() ); @@ -239,14 +211,10 @@ proto.applyDragForce = function() { proto.applySelectedAttraction = function() { // do not attract if pointer down or no cells - var len = this.cells.length; - if ( this.isPointerDown || this.isFreeScrolling || !len ) { + if ( this.isPointerDown || this.isFreeScrolling || !this.cells.length ) { return; } - var cell = this.cells[ this.selectedIndex ]; - var wrap = this.options.wrapAround && len > 1 ? - this.slideableWidth * Math.floor( this.selectedIndex / len ) : 0; - var distance = ( cell.target + wrap ) * -1 - this.x; + var distance = this.selectedSlide.target * -1 - this.x; var force = distance * this.options.selectedAttraction; this.applyForce( force ); }; @@ -1,7 +1,7 @@ +// Flickity.Cell ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ @@ -9,7 +9,7 @@ ], function( getSize ) { return factory( window, getSize ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, @@ -35,42 +35,39 @@ function Cell( elem, parent ) { this.create(); } -var isIE8 = 'attachEvent' in window; +var proto = Cell.prototype; -Cell.prototype.create = function() { +proto.create = function() { this.element.style.position = 'absolute'; - // IE8 prevent child from changing focus http://stackoverflow.com/a/17525223/182183 - if ( isIE8 ) { - this.element.setAttribute( 'unselectable', 'on' ); - } this.x = 0; this.shift = 0; }; -Cell.prototype.destroy = function() { +proto.destroy = function() { // reset style this.element.style.position = ''; var side = this.parent.originSide; this.element.style[ side ] = ''; }; -Cell.prototype.getSize = function() { +proto.getSize = function() { this.size = getSize( this.element ); }; -Cell.prototype.setPosition = function( x ) { +proto.setPosition = function( x ) { this.x = x; - this.setDefaultTarget(); + this.updateTarget(); this.renderPosition( x ); }; -Cell.prototype.setDefaultTarget = function() { +// setDefaultTarget v1 method, backwards compatibility, remove in v3 +proto.updateTarget = proto.setDefaultTarget = function() { var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight'; this.target = this.x + this.size[ marginProperty ] + this.size.width * this.parent.cellAlign; }; -Cell.prototype.renderPosition = function( x ) { +proto.renderPosition = function( x ) { // render position of cell with in slider var side = this.parent.originSide; this.element.style[ side ] = this.parent.getPositionValue( x ); @@ -79,12 +76,12 @@ Cell.prototype.renderPosition = function( x ) { /** * @param {Integer} factor - 0, 1, or -1 **/ -Cell.prototype.wrapShift = function( shift ) { +proto.wrapShift = function( shift ) { this.shift = shift; this.renderPosition( this.x + this.parent.slideableWidth * shift ); }; -Cell.prototype.remove = function() { +proto.remove = function() { this.element.parentNode.removeChild( this.element ); }; @@ -1,24 +1,20 @@ +// drag ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'classie/classie', - 'eventie/eventie', './flickity', 'unidragger/unidragger', 'fizzy-ui-utils/utils' - ], function( classie, eventie, Flickity, Unidragger, utils ) { - return factory( window, classie, eventie, Flickity, Unidragger, utils ); + ], function( Flickity, Unidragger, utils ) { + return factory( window, Flickity, Unidragger, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('desandro-classie'), - require('eventie'), require('./flickity'), require('unidragger'), require('fizzy-ui-utils') @@ -27,31 +23,21 @@ // browser global window.Flickity = factory( window, - window.classie, - window.eventie, window.Flickity, window.Unidragger, window.fizzyUIUtils ); } -}( window, function factory( window, classie, eventie, Flickity, Unidragger, utils ) { +}( window, function factory( window, Flickity, Unidragger, utils ) { 'use strict'; -// handle IE8 prevent default -function preventDefaultEvent( event ) { - if ( event.preventDefault ) { - event.preventDefault(); - } else { - event.returnValue = false; - } -} - // ----- defaults ----- // utils.extend( Flickity.defaults, { - draggable: true + draggable: true, + dragThreshold: 3, }); // ----- create ----- // @@ -60,50 +46,69 @@ Flickity.createMethods.push('_createDrag'); // -------------------------- drag prototype -------------------------- // -utils.extend( Flickity.prototype, Unidragger.prototype ); +var proto = Flickity.prototype; +utils.extend( proto, Unidragger.prototype ); // -------------------------- -------------------------- // -Flickity.prototype._createDrag = function() { +proto._createDrag = function() { this.on( 'activate', this.bindDrag ); this.on( 'uiChange', this._uiChangeDrag ); this.on( 'childUIPointerDown', this._childUIPointerDownDrag ); this.on( 'deactivate', this.unbindDrag ); }; -Flickity.prototype.bindDrag = function() { +proto.bindDrag = function() { if ( !this.options.draggable || this.isDragBound ) { return; } - classie.add( this.element, 'is-draggable' ); + this.element.classList.add('is-draggable'); this.handles = [ this.viewport ]; this.bindHandles(); this.isDragBound = true; }; -Flickity.prototype.unbindDrag = function() { +proto.unbindDrag = function() { if ( !this.isDragBound ) { return; } - classie.remove( this.element, 'is-draggable' ); + this.element.classList.remove('is-draggable'); this.unbindHandles(); delete this.isDragBound; }; -Flickity.prototype._uiChangeDrag = function() { +proto._uiChangeDrag = function() { delete this.isFreeScrolling; }; -Flickity.prototype._childUIPointerDownDrag = function( event ) { - preventDefaultEvent( event ); +proto._childUIPointerDownDrag = function( event ) { + event.preventDefault(); this.pointerDownFocus( event ); }; // -------------------------- pointer events -------------------------- // -Flickity.prototype.pointerDown = function( event, pointer ) { - // dismiss range sliders - if ( event.target.nodeName == 'INPUT' && event.target.type == 'range' ) { +// nodes that have text fields +var cursorNodes = { + TEXTAREA: true, + INPUT: true, +}; + +// input types that do not have text fields +var clickTypes = { + radio: true, + checkbox: true, + button: true, + submit: true, + image: true, + file: true, +}; + +proto.pointerDown = function( event, pointer ) { + // dismiss inputs with text fields. #404 + var isCursorInput = cursorNodes[ event.target.nodeName ] && + !clickTypes[ event.target.type ]; + if ( isCursorInput ) { // reset pointerDown logic this.isPointerDown = false; delete this.pointerIdentifier; @@ -122,12 +127,12 @@ Flickity.prototype.pointerDown = function( event, pointer ) { this.pointerDownFocus( event ); // stop if it was moving this.dragX = this.x; - classie.add( this.viewport, 'is-pointer-down' ); + this.viewport.classList.add('is-pointer-down'); // bind move and end events this._bindPostStartEvents( event ); // track scrolling - this.pointerDownScroll = Unidragger.getScrollPosition(); - eventie.bind( window, 'scroll', this ); + this.pointerDownScroll = getScrollPosition(); + window.addEventListener( 'scroll', this ); this.dispatchEvent( 'pointerDown', event, [ pointer ] ); }; @@ -142,7 +147,7 @@ var focusNodes = { SELECT: true }; -Flickity.prototype.pointerDownFocus = function( event ) { +proto.pointerDownFocus = function( event ) { // focus element, if not touch, and its not an input or select if ( !this.options.accessibility || touchStartEvents[ event.type ] || focusNodes[ event.target.nodeName ] ) { @@ -156,46 +161,54 @@ Flickity.prototype.pointerDownFocus = function( event ) { } }; +proto.canPreventDefaultOnPointerDown = function( event ) { + // prevent default, unless touchstart or <select> + var isTouchstart = event.type == 'touchstart'; + var targetNodeName = event.target.nodeName; + return !isTouchstart && targetNodeName != 'SELECT'; +}; + // ----- move ----- // -Flickity.prototype.hasDragStarted = function( moveVector ) { - return Math.abs( moveVector.x ) > 3; +proto.hasDragStarted = function( moveVector ) { + return Math.abs( moveVector.x ) > this.options.dragThreshold; }; // ----- up ----- // -Flickity.prototype.pointerUp = function( event, pointer ) { - classie.remove( this.viewport, 'is-pointer-down' ); +proto.pointerUp = function( event, pointer ) { + delete this.isTouchScrolling; + this.viewport.classList.remove('is-pointer-down'); this.dispatchEvent( 'pointerUp', event, [ pointer ] ); this._dragPointerUp( event, pointer ); }; -Flickity.prototype.pointerDone = function() { - eventie.unbind( window, 'scroll', this ); +proto.pointerDone = function() { + window.removeEventListener( 'scroll', this ); delete this.pointerDownScroll; }; // -------------------------- dragging -------------------------- // -Flickity.prototype.dragStart = function( event, pointer ) { +proto.dragStart = function( event, pointer ) { this.dragStartPosition = this.x; this.startAnimation(); this.dispatchEvent( 'dragStart', event, [ pointer ] ); }; -Flickity.prototype.dragMove = function( event, pointer, moveVector ) { - preventDefaultEvent( event ); +proto.dragMove = function( event, pointer, moveVector ) { + event.preventDefault(); this.previousDragX = this.dragX; // reverse if right-to-left var direction = this.options.rightToLeft ? -1 : 1; var dragX = this.dragStartPosition + moveVector.x * direction; - if ( !this.options.wrapAround && this.cells.length ) { + if ( !this.options.wrapAround && this.slides.length ) { // slow drag - var originBound = Math.max( -this.cells[0].target, this.dragStartPosition ); + var originBound = Math.max( -this.slides[0].target, this.dragStartPosition ); dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX; - var endBound = Math.min( -this.getLastCell().target, this.dragStartPosition ); + var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition ); dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX; } @@ -205,7 +218,7 @@ Flickity.prototype.dragMove = function( event, pointer, moveVector ) { this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] ); }; -Flickity.prototype.dragEnd = function( event, pointer ) { +proto.dragEnd = function( event, pointer ) { if ( this.options.freeScroll ) { this.isFreeScrolling = true; } @@ -214,11 +227,11 @@ Flickity.prototype.dragEnd = function( event, pointer ) { if ( this.options.freeScroll && !this.options.wrapAround ) { // if free-scroll & not wrap around - // do not free-scroll if going outside of bounding cells - // so bounding cells can attract slider, and keep it in bounds + // do not free-scroll if going outside of bounding slides + // so bounding slides can attract slider, and keep it in bounds var restingX = this.getRestingPosition(); - this.isFreeScrolling = -restingX > this.cells[0].target && - -restingX < this.getLastCell().target; + this.isFreeScrolling = -restingX > this.slides[0].target && + -restingX < this.getLastSlide().target; } else if ( !this.options.freeScroll && index == this.selectedIndex ) { // boost selection if selected index has not changed index += this.dragEndBoostSelect(); @@ -226,14 +239,17 @@ Flickity.prototype.dragEnd = function( event, pointer ) { delete this.previousDragX; // apply selection // TODO refactor this, selecting here feels weird + // HACK, set flag so dragging stays in correct direction + this.isDragSelect = this.options.wrapAround; this.select( index ); + delete this.isDragSelect; this.dispatchEvent( 'dragEnd', event, [ pointer ] ); }; -Flickity.prototype.dragEndRestingSelect = function() { +proto.dragEndRestingSelect = function() { var restingX = this.getRestingPosition(); - // how far away from selected cell - var distance = Math.abs( this.getCellDistance( -restingX, this.selectedIndex ) ); + // how far away from selected slide + var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) ); // get closet resting going up and going down var positiveResting = this._getClosestResting( restingX, distance, 1 ); var negativeResting = this._getClosestResting( restingX, distance, -1 ); @@ -251,7 +267,7 @@ Flickity.prototype.dragEndRestingSelect = function() { * @param {Integer} increment - +1 or -1, going up or down * @returns {Object} - { distance: {Number}, index: {Integer} } */ -Flickity.prototype._getClosestResting = function( restingX, distance, increment ) { +proto._getClosestResting = function( restingX, distance, increment ) { var index = this.selectedIndex; var minDistance = Infinity; var condition = this.options.contain && !this.options.wrapAround ? @@ -261,7 +277,7 @@ Flickity.prototype._getClosestResting = function( restingX, distance, increment // measure distance to next cell index += increment; minDistance = distance; - distance = this.getCellDistance( -restingX, index ); + distance = this.getSlideDistance( -restingX, index ); if ( distance === null ) { break; } @@ -275,25 +291,25 @@ Flickity.prototype._getClosestResting = function( restingX, distance, increment }; /** - * measure distance between x and a cell target + * measure distance between x and a slide target * @param {Number} x - * @param {Integer} index - cell index + * @param {Integer} index - slide index */ -Flickity.prototype.getCellDistance = function( x, index ) { - var len = this.cells.length; - // wrap around if at least 2 cells +proto.getSlideDistance = function( x, index ) { + var len = this.slides.length; + // wrap around if at least 2 slides var isWrapAround = this.options.wrapAround && len > 1; - var cellIndex = isWrapAround ? utils.modulo( index, len ) : index; - var cell = this.cells[ cellIndex ]; - if ( !cell ) { + var slideIndex = isWrapAround ? utils.modulo( index, len ) : index; + var slide = this.slides[ slideIndex ]; + if ( !slide ) { return null; } - // add distance for wrap-around cells + // add distance for wrap-around slides var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0; - return x - ( cell.target + wrap ); + return x - ( slide.target + wrap ); }; -Flickity.prototype.dragEndBoostSelect = function() { +proto.dragEndBoostSelect = function() { // do not boost if no previousDragX or dragMoveTime if ( this.previousDragX === undefined || !this.dragMoveTime || // or if drag was held for 100 ms @@ -301,7 +317,7 @@ Flickity.prototype.dragEndBoostSelect = function() { return 0; } - var distance = this.getCellDistance( -this.dragX, this.selectedIndex ); + var distance = this.getSlideDistance( -this.dragX, this.selectedIndex ); var delta = this.previousDragX - this.dragX; if ( distance > 0 && delta > 0 ) { // boost to next if moving towards the right, and positive velocity @@ -315,14 +331,35 @@ Flickity.prototype.dragEndBoostSelect = function() { // ----- staticClick ----- // -Flickity.prototype.staticClick = function( event, pointer ) { +proto.staticClick = function( event, pointer ) { // get clickedCell, if cell was clicked var clickedCell = this.getParentCell( event.target ); var cellElem = clickedCell && clickedCell.element; - var cellIndex = clickedCell && utils.indexOf( this.cells, clickedCell ); + var cellIndex = clickedCell && this.cells.indexOf( clickedCell ); this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] ); }; +// ----- scroll ----- // + +proto.onscroll = function() { + var scroll = getScrollPosition(); + var scrollMoveX = this.pointerDownScroll.x - scroll.x; + var scrollMoveY = this.pointerDownScroll.y - scroll.y; + // cancel click/tap if scroll is too much + if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) { + this._pointerDone(); + } +}; + +// ----- utils ----- // + +function getScrollPosition() { + return { + x: window.pageXOffset, + y: window.pageYOffset + }; +} + // ----- ----- // return Flickity; diff --git a/js/flickity.js b/js/flickity.js index 5704a6f..ae9ac7c 100644 --- a/js/flickity.js +++ b/js/flickity.js @@ -1,34 +1,28 @@ -/** - * Flickity main - */ - +// Flickity main ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'classie/classie', - 'eventEmitter/EventEmitter', - 'eventie/eventie', + 'ev-emitter/ev-emitter', 'get-size/get-size', 'fizzy-ui-utils/utils', './cell', + './slide', './animate' - ], function( classie, EventEmitter, eventie, getSize, utils, Cell, animatePrototype ) { - return factory( window, classie, EventEmitter, eventie, getSize, utils, Cell, animatePrototype ); + ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) { + return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('desandro-classie'), - require('wolfy87-eventemitter'), - require('eventie'), + require('ev-emitter'), require('get-size'), require('fizzy-ui-utils'), require('./cell'), + require('./slide'), require('./animate') ); } else { @@ -37,18 +31,17 @@ window.Flickity = factory( window, - window.classie, - window.EventEmitter, - window.eventie, + window.EvEmitter, window.getSize, window.fizzyUIUtils, _Flickity.Cell, + _Flickity.Slide, _Flickity.animatePrototype ); } -}( window, function factory( window, classie, EventEmitter, eventie, getSize, - utils, Cell, animatePrototype ) { +}( window, function factory( window, EvEmitter, getSize, + utils, Cell, Slide, animatePrototype ) { 'use strict'; @@ -94,11 +87,13 @@ function Flickity( element, options ) { Flickity.defaults = { accessibility: true, + // adaptiveHeight: false, cellAlign: 'center', // cellSelector: undefined, // contain: false, freeScrollFriction: 0.075, // friction when free-scrolling friction: 0.28, // friction when selecting + namespaceJQueryEvents: true, // initialIndex: 0, percentPosition: true, resize: true, @@ -111,10 +106,11 @@ Flickity.defaults = { // hash of methods triggered on _create() Flickity.createMethods = []; +var proto = Flickity.prototype; // inherit EventEmitter -utils.extend( Flickity.prototype, EventEmitter.prototype ); +utils.extend( proto, EvEmitter.prototype ); -Flickity.prototype._create = function() { +proto._create = function() { // add id for Flickity.data var id = this.guid = ++GUID; this.element.flickityGUID = id; // expando @@ -126,23 +122,19 @@ Flickity.prototype._create = function() { // initial physics properties this.x = 0; this.velocity = 0; - this.accel = 0; this.originSide = this.options.rightToLeft ? 'right' : 'left'; // create viewport & slider this.viewport = document.createElement('div'); this.viewport.className = 'flickity-viewport'; - Flickity.setUnselectable( this.viewport ); this._createSlider(); if ( this.options.resize || this.options.watchCSS ) { - eventie.bind( window, 'resize', this ); - this.isResizeBound = true; + window.addEventListener( 'resize', this ); } - for ( var i=0, len = Flickity.createMethods.length; i < len; i++ ) { - var method = Flickity.createMethods[i]; + Flickity.createMethods.forEach( function( method ) { this[ method ](); - } + }, this ); if ( this.options.watchCSS ) { this.watchCSS(); @@ -156,18 +148,18 @@ Flickity.prototype._create = function() { * set options * @param {Object} opts */ -Flickity.prototype.option = function( opts ) { +proto.option = function( opts ) { utils.extend( this.options, opts ); }; -Flickity.prototype.activate = function() { +proto.activate = function() { if ( this.isActive ) { return; } this.isActive = true; - classie.add( this.element, 'flickity-enabled' ); + this.element.classList.add('flickity-enabled'); if ( this.options.rightToLeft ) { - classie.add( this.element, 'flickity-rtl' ); + this.element.classList.add('flickity-rtl'); } this.getSize(); @@ -183,10 +175,10 @@ Flickity.prototype.activate = function() { // allow element to focusable this.element.tabIndex = 0; // listen for key presses - eventie.bind( this.element, 'keydown', this ); + this.element.addEventListener( 'keydown', this ); } - this.emit('activate'); + this.emitEvent('activate'); var index; var initialIndex = this.options.initialIndex; @@ -204,7 +196,7 @@ Flickity.prototype.activate = function() { }; // slider positions the cells -Flickity.prototype._createSlider = function() { +proto._createSlider = function() { // slider element does all the positioning var slider = document.createElement('div'); slider.className = 'flickity-slider'; @@ -212,12 +204,12 @@ Flickity.prototype._createSlider = function() { this.slider = slider; }; -Flickity.prototype._filterFindCellElements = function( elems ) { +proto._filterFindCellElements = function( elems ) { return utils.filterFindElements( elems, this.options.cellSelector ); }; // goes through all children -Flickity.prototype.reloadCells = function() { +proto.reloadCells = function() { // collection of item elements this.cells = this._makeCells( this.slider.children ); this.positionCells(); @@ -230,26 +222,27 @@ Flickity.prototype.reloadCells = function() { * @param {Array or NodeList or HTMLElement} elems * @returns {Array} items - collection of new Flickity Cells */ -Flickity.prototype._makeCells = function( elems ) { +proto._makeCells = function( elems ) { var cellElems = this._filterFindCellElements( elems ); // create new Flickity for collection - var cells = []; - for ( var i=0, len = cellElems.length; i < len; i++ ) { - var elem = cellElems[i]; - var cell = new Cell( elem, this ); - cells.push( cell ); - } + var cells = cellElems.map( function( cellElem ) { + return new Cell( cellElem, this ); + }, this ); return cells; }; -Flickity.prototype.getLastCell = function() { +proto.getLastCell = function() { return this.cells[ this.cells.length - 1 ]; }; +proto.getLastSlide = function() { + return this.slides[ this.slides.length - 1 ]; +}; + // positions all cells -Flickity.prototype.positionCells = function() { +proto.positionCells = function() { // size all cells this._sizeCells( this.cells ); // position all cells @@ -260,7 +253,7 @@ Flickity.prototype.positionCells = function() { * position certain cells * @param {Integer} index - which cell to start with */ -Flickity.prototype._positionCells = function( index ) { +proto._positionCells = function( index ) { index = index || 0; // also measure maxCellHeight // start 0 if positioning all cells @@ -271,38 +264,106 @@ Flickity.prototype._positionCells = function( index ) { var startCell = this.cells[ index - 1 ]; cellX = startCell.x + startCell.size.outerWidth; } - var cell; - for ( var len = this.cells.length, i=index; i < len; i++ ) { - cell = this.cells[i]; + var len = this.cells.length; + for ( var i=index; i < len; i++ ) { + var cell = this.cells[i]; cell.setPosition( cellX ); cellX += cell.size.outerWidth; this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight ); } // keep track of cellX for wrap-around this.slideableWidth = cellX; - // contain cell target - this._containCells(); + // slides + this.updateSlides(); + // contain slides target + this._containSlides(); + // update slidesWidth + this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0; }; /** * cell.getSize() on multiple cells * @param {Array} cells */ -Flickity.prototype._sizeCells = function( cells ) { - for ( var i=0, len = cells.length; i < len; i++ ) { - var cell = cells[i]; +proto._sizeCells = function( cells ) { + cells.forEach( function( cell ) { cell.getSize(); + }); +}; + +// -------------------------- -------------------------- // + +proto.updateSlides = function() { + this.slides = []; + if ( !this.cells.length ) { + return; } + + var slide = new Slide( this ); + this.slides.push( slide ); + var isOriginLeft = this.originSide == 'left'; + var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft'; + + var canCellFit = this._getCanCellFit(); + + this.cells.forEach( function( cell, i ) { + // just add cell if first cell in slide + if ( !slide.cells.length ) { + slide.addCell( cell ); + return; + } + + var slideWidth = ( slide.outerWidth - slide.firstMargin ) + + ( cell.size.outerWidth - cell.size[ nextMargin ] ); + + if ( canCellFit.call( this, i, slideWidth ) ) { + slide.addCell( cell ); + } else { + // doesn't fit, new slide + slide.updateTarget(); + + slide = new Slide( this ); + this.slides.push( slide ); + slide.addCell( cell ); + } + }, this ); + // last slide + slide.updateTarget(); + // update .selectedSlide + this.updateSelectedSlide(); +}; + +proto._getCanCellFit = function() { + var groupCells = this.options.groupCells; + if ( !groupCells ) { + return function() { + return false; + }; + } else if ( typeof groupCells == 'number' ) { + // group by number. 3 -> [0,1,2], [3,4,5], ... + var number = parseInt( groupCells, 10 ); + return function( i ) { + return ( i % number ) !== 0; + }; + } + // default, group by width of slide + // parse '75% + var percentMatch = typeof groupCells == 'string' && + groupCells.match(/^(\d+)%$/); + var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1; + return function( i, slideWidth ) { + return slideWidth <= ( this.size.innerWidth + 1 ) * percent; + }; }; // alias _init for jQuery plugin .flickity() -Flickity.prototype._init = -Flickity.prototype.reposition = function() { +proto._init = +proto.reposition = function() { this.positionCells(); this.positionSliderAtSelected(); }; -Flickity.prototype.getSize = function() { +proto.getSize = function() { this.size = getSize( this.element ); this.setCellAlign(); this.cursorPosition = this.size.innerWidth * this.cellAlign; @@ -324,18 +385,20 @@ var cellAlignShorthands = { } }; -Flickity.prototype.setCellAlign = function() { +proto.setCellAlign = function() { var shorthand = cellAlignShorthands[ this.options.cellAlign ]; this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign; }; -Flickity.prototype.setGallerySize = function() { +proto.setGallerySize = function() { if ( this.options.setGallerySize ) { - this.viewport.style.height = this.maxCellHeight + 'px'; + var height = this.options.adaptiveHeight && this.selectedSlide ? + this.selectedSlide.height : this.maxCellHeight; + this.viewport.style.height = height + 'px'; } }; -Flickity.prototype._getWrapShiftCells = function() { +proto._getWrapShiftCells = function() { // only for wrap-around if ( !this.options.wrapAround ) { return; @@ -355,7 +418,7 @@ Flickity.prototype._getWrapShiftCells = function() { this.afterShiftCells = this._getGapCells( gapX, 0, 1 ); }; -Flickity.prototype._getGapCells = function( gapX, cellIndex, increment ) { +proto._getGapCells = function( gapX, cellIndex, increment ) { // keep adding cells until the cover the initial gap var cells = []; while ( gapX > 0 ) { @@ -373,32 +436,30 @@ Flickity.prototype._getGapCells = function( gapX, cellIndex, increment ) { // ----- contain ----- // // contain cell targets so no excess sliding -Flickity.prototype._containCells = function() { +proto._containSlides = function() { if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) { return; } - var startMargin = this.options.rightToLeft ? 'marginRight' : 'marginLeft'; - var endMargin = this.options.rightToLeft ? 'marginLeft' : 'marginRight'; - var firstCellStartMargin = this.cells[0].size[ startMargin ]; - var lastCell = this.getLastCell(); - var contentWidth = this.slideableWidth - lastCell.size[ endMargin ]; - var endLimit = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign ); + var isRightToLeft = this.options.rightToLeft; + var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft'; + var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight'; + var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ]; // content is less than gallery size var isContentSmaller = contentWidth < this.size.innerWidth; + // bounds + var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ]; + var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign ); // contain each cell target - for ( var i=0, len = this.cells.length; i < len; i++ ) { - var cell = this.cells[i]; - // reset default target - cell.setDefaultTarget(); + this.slides.forEach( function( slide ) { if ( isContentSmaller ) { // all cells fit inside gallery - cell.target = contentWidth * this.cellAlign; + slide.target = contentWidth * this.cellAlign; } else { // contain to bounds - cell.target = Math.max( cell.target, this.cursorPosition + firstCellStartMargin ); - cell.target = Math.min( cell.target, endLimit ); + slide.target = Math.max( slide.target, beginBound ); + slide.target = Math.min( slide.target, endBound ); } - } + }, this ); }; // ----- ----- // @@ -409,80 +470,144 @@ Flickity.prototype._containCells = function() { * @param {Event} event - original event * @param {Array} args - extra arguments */ -Flickity.prototype.dispatchEvent = function( type, event, args ) { +proto.dispatchEvent = function( type, event, args ) { var emitArgs = [ event ].concat( args ); this.emitEvent( type, emitArgs ); if ( jQuery && this.$element ) { + // default trigger with type if no event + type += this.options.namespaceJQueryEvents ? '.flickity' : ''; + var $event = type; 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 ); + var jQEvent = jQuery.Event( event ); + jQEvent.type = type; + $event = jQEvent; } + this.$element.trigger( $event, args ); } }; // -------------------------- select -------------------------- // /** - * @param {Integer} index - index of the cell + * @param {Integer} index - index of the slide * @param {Boolean} isWrap - will wrap-around to last/first if at the end * @param {Boolean} isInstant - will immediately set position at selected cell */ -Flickity.prototype.select = function( index, isWrap, isInstant ) { +proto.select = function( index, isWrap, isInstant ) { if ( !this.isActive ) { return; } index = parseInt( index, 10 ); - // wrap position so slider is within normal area - var len = this.cells.length; - if ( this.options.wrapAround && len > 1 ) { - if ( index < 0 ) { - this.x -= this.slideableWidth; - } else if ( index >= len ) { - this.x += this.slideableWidth; - } - } + this._wrapSelect( index ); if ( this.options.wrapAround || isWrap ) { - index = utils.modulo( index, len ); + index = utils.modulo( index, this.slides.length ); } // bail if invalid index - if ( !this.cells[ index ] ) { + if ( !this.slides[ index ] ) { return; } this.selectedIndex = index; - this.setSelectedCell(); + this.updateSelectedSlide(); if ( isInstant ) { this.positionSliderAtSelected(); } else { this.startAnimation(); } + if ( this.options.adaptiveHeight ) { + this.setGallerySize(); + } + + this.dispatchEvent('select'); + // old v1 event name, remove in v3 this.dispatchEvent('cellSelect'); }; -Flickity.prototype.previous = function( isWrap ) { +// wraps position for wrapAround, to move to closest slide. #113 +proto._wrapSelect = function( index ) { + var len = this.slides.length; + var isWrapping = this.options.wrapAround && len > 1; + if ( !isWrapping ) { + return index; + } + var wrapIndex = utils.modulo( index, len ); + // go to shortest + var delta = Math.abs( wrapIndex - this.selectedIndex ); + var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex ); + var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex ); + if ( !this.isDragSelect && backWrapDelta < delta ) { + index += len; + } else if ( !this.isDragSelect && forewardWrapDelta < delta ) { + index -= len; + } + // wrap position so slider is within normal area + if ( index < 0 ) { + this.x -= this.slideableWidth; + } else if ( index >= len ) { + this.x += this.slideableWidth; + } +}; + +proto.previous = function( isWrap ) { this.select( this.selectedIndex - 1, isWrap ); }; -Flickity.prototype.next = function( isWrap ) { +proto.next = function( isWrap ) { this.select( this.selectedIndex + 1, isWrap ); }; -Flickity.prototype.setSelectedCell = function() { - this._removeSelectedCellClass(); - this.selectedCell = this.cells[ this.selectedIndex ]; - this.selectedElement = this.selectedCell.element; - classie.add( this.selectedElement, 'is-selected' ); +proto.updateSelectedSlide = function() { + var slide = this.slides[ this.selectedIndex ]; + // selectedIndex could be outside of slides, if triggered before resize() + if ( !slide ) { + return; + } + // unselect previous selected slide + this.unselectSelectedSlide(); + // update new selected slide + this.selectedSlide = slide; + slide.select(); + this.selectedCells = slide.cells; + this.selectedElements = slide.getCellElements(); + // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility + // Remove in v3? + this.selectedCell = slide.cells[0]; + this.selectedElement = this.selectedElements[0]; +}; + +proto.unselectSelectedSlide = function() { + if ( this.selectedSlide ) { + this.selectedSlide.unselect(); + } }; -Flickity.prototype._removeSelectedCellClass = function() { - if ( this.selectedCell ) { - classie.remove( this.selectedCell.element, 'is-selected' ); +/** + * select slide from number or cell element + * @param {Element or Number} elem + */ +proto.selectCell = function( value, isWrap, isInstant ) { + // get cell + var cell; + if ( typeof value == 'number' ) { + cell = this.cells[ value ]; + } else { + // use string as selector + if ( typeof value == 'string' ) { + value = this.element.querySelector( value ); + } + // get cell from element + cell = this.getCell( value ); + } + // select slide that has cell + for ( var i=0; cell && i < this.slides.length; i++ ) { + var slide = this.slides[i]; + var index = slide.cells.indexOf( cell ); + if ( index != -1 ) { + this.select( i, isWrap, isInstant ); + return; + } } }; @@ -493,9 +618,9 @@ Flickity.prototype._removeSelectedCellClass = function() { * @param {Element} elem * @returns {Flickity.Cell} item */ -Flickity.prototype.getCell = function( elem ) { +proto.getCell = function( elem ) { // loop through cells to get the one that matches - for ( var i=0, len = this.cells.length; i < len; i++ ) { + for ( var i=0; i < this.cells.length; i++ ) { var cell = this.cells[i]; if ( cell.element == elem ) { return cell; @@ -508,16 +633,15 @@ Flickity.prototype.getCell = function( elem ) { * @param {Element, Array, NodeList} elems * @returns {Array} cells - Flickity.Cells */ -Flickity.prototype.getCells = function( elems ) { +proto.getCells = function( elems ) { elems = utils.makeArray( elems ); var cells = []; - for ( var i=0, len = elems.length; i < len; i++ ) { - var elem = elems[i]; + elems.forEach( function( elem ) { var cell = this.getCell( elem ); if ( cell ) { cells.push( cell ); } - } + }, this ); return cells; }; @@ -525,12 +649,10 @@ Flickity.prototype.getCells = function( elems ) { * get cell elements * @returns {Array} cellElems */ -Flickity.prototype.getCellElements = function() { - var cellElems = []; - for ( var i=0, len = this.cells.length; i < len; i++ ) { - cellElems.push( this.cells[i].element ); - } - return cellElems; +proto.getCellElements = function() { + return this.cells.map( function( cell ) { + return cell.element; + }); }; /** @@ -538,7 +660,7 @@ Flickity.prototype.getCellElements = function() { * @param {Element} elem * @returns {Flickit.Cell} cell */ -Flickity.prototype.getParentCell = function( elem ) { +proto.getParentCell = function( elem ) { // first check if elem is cell var cell = this.getCell( elem ); if ( cell ) { @@ -550,28 +672,28 @@ Flickity.prototype.getParentCell = function( elem ) { }; /** - * get cells adjacent to a cell - * @param {Integer} adjCount - number of adjacent cells - * @param {Integer} index - index of cell to start + * get cells adjacent to a slide + * @param {Integer} adjCount - number of adjacent slides + * @param {Integer} index - index of slide to start * @returns {Array} cells - array of Flickity.Cells */ -Flickity.prototype.getAdjacentCellElements = function( adjCount, index ) { +proto.getAdjacentCellElements = function( adjCount, index ) { if ( !adjCount ) { - return [ this.selectedElement ]; + return this.selectedSlide.getCellElements(); } index = index === undefined ? this.selectedIndex : index; - var len = this.cells.length; + var len = this.slides.length; if ( 1 + ( adjCount * 2 ) >= len ) { return this.getCellElements(); } var cellElems = []; for ( var i = index - adjCount; i <= index + adjCount ; i++ ) { - var cellIndex = this.options.wrapAround ? utils.modulo( i, len ) : i; - var cell = this.cells[ cellIndex ]; - if ( cell ) { - cellElems.push( cell.element ); + var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i; + var slide = this.slides[ slideIndex ]; + if ( slide ) { + cellElems = cellElems.concat( slide.getCellElements() ); } } return cellElems; @@ -579,24 +701,24 @@ Flickity.prototype.getAdjacentCellElements = function( adjCount, index ) { // -------------------------- events -------------------------- // -Flickity.prototype.uiChange = function() { - this.emit('uiChange'); +proto.uiChange = function() { + this.emitEvent('uiChange'); }; -Flickity.prototype.childUIPointerDown = function( event ) { +proto.childUIPointerDown = function( event ) { this.emitEvent( 'childUIPointerDown', [ event ] ); }; // ----- resize ----- // -Flickity.prototype.onresize = function() { +proto.onresize = function() { this.watchCSS(); this.resize(); }; utils.debounceMethod( Flickity, 'onresize', 150 ); -Flickity.prototype.resize = function() { +proto.resize = function() { if ( !this.isActive ) { return; } @@ -608,45 +730,19 @@ Flickity.prototype.resize = function() { this.positionCells(); this._getWrapShiftCells(); this.setGallerySize(); - this.positionSliderAtSelected(); + this.emitEvent('resize'); + // update selected index for group slides, instant + // TODO: position can be lost between groups of various numbers + var selectedElement = this.selectedElements && this.selectedElements[0]; + this.selectCell( selectedElement, false, true ); }; -var supportsConditionalCSS = Flickity.supportsConditionalCSS = ( function() { - var supports; - return function checkSupport() { - if ( supports !== undefined ) { - return supports; - } - if ( !getComputedStyle ) { - supports = false; - return; - } - // style body's :after and check that - var style = document.createElement('style'); - var cssText = document.createTextNode('body:after { content: "foo"; display: none; }'); - style.appendChild( cssText ); - document.head.appendChild( style ); - var afterContent = getComputedStyle( document.body, ':after' ).content; - // check if able to get :after content - supports = afterContent.indexOf('foo') != -1; - document.head.removeChild( style ); - return supports; - }; -})(); - // watches the :after property, activates/deactivates -Flickity.prototype.watchCSS = function() { +proto.watchCSS = function() { var watchOption = this.options.watchCSS; if ( !watchOption ) { return; } - var supports = supportsConditionalCSS(); - if ( !supports ) { - // activate if watch option is fallbackOn - var method = watchOption == 'fallbackOn' ? 'activate' : 'deactivate'; - this[ method ](); - return; - } var afterContent = getComputedStyle( this.element, ':after' ).content; // activate if :after { content: 'flickity' } @@ -660,7 +756,7 @@ Flickity.prototype.watchCSS = function() { // ----- keydown ----- // // go previous/next if left/right keys pressed -Flickity.prototype.onkeydown = function( event ) { +proto.onkeydown = function( event ) { // only work if element is in focus if ( !this.options.accessibility || ( document.activeElement && document.activeElement != this.element ) ) { @@ -683,36 +779,33 @@ Flickity.prototype.onkeydown = function( event ) { // -------------------------- destroy -------------------------- // // deactivate all Flickity functionality, but keep stuff available -Flickity.prototype.deactivate = function() { +proto.deactivate = function() { if ( !this.isActive ) { return; } - classie.remove( this.element, 'flickity-enabled' ); - classie.remove( this.element, 'flickity-rtl' ); + this.element.classList.remove('flickity-enabled'); + this.element.classList.remove('flickity-rtl'); // destroy cells - for ( var i=0, len = this.cells.length; i < len; i++ ) { - var cell = this.cells[i]; + this.cells.forEach( function( cell ) { cell.destroy(); - } - this._removeSelectedCellClass(); + }); + this.unselectSelectedSlide(); this.element.removeChild( this.viewport ); // move child elements back into element moveElements( this.slider.children, this.element ); if ( this.options.accessibility ) { this.element.removeAttribute('tabIndex'); - eventie.unbind( this.element, 'keydown', this ); + this.element.removeEventListener( 'keydown', this ); } // set flags this.isActive = false; - this.emit('deactivate'); + this.emitEvent('deactivate'); }; -Flickity.prototype.destroy = function() { +proto.destroy = function() { this.deactivate(); - if ( this.isResizeBound ) { - eventie.unbind( window, 'resize', this ); - } - this.emit('destroy'); + window.removeEventListener( 'resize', this ); + this.emitEvent('destroy'); if ( jQuery && this.$element ) { jQuery.removeData( this.element, 'flickity' ); } @@ -722,21 +815,10 @@ Flickity.prototype.destroy = function() { // -------------------------- prototype -------------------------- // -utils.extend( Flickity.prototype, animatePrototype ); +utils.extend( proto, animatePrototype ); // -------------------------- extras -------------------------- // -// quick check for IE8 -var isIE8 = 'attachEvent' in window; - -Flickity.setUnselectable = function( elem ) { - if ( !isIE8 ) { - return; - } - // IE8 prevent child from changing focus http://stackoverflow.com/a/17525223/182183 - elem.setAttribute( 'unselectable', 'on' ); -}; - /** * get Flickity instance from element * @param {Element} elem diff --git a/js/index.js b/js/index.js index 400a5e4..a992b4b 100644 --- a/js/index.js +++ b/js/index.js @@ -1,18 +1,17 @@ /*! - * Flickity v1.2.1 + * Flickity v2.0.0 * Touch, responsive, flickable galleries * * Licensed GPLv3 for open source use * or Flickity Commercial License for commercial use * * http://flickity.metafizzy.co - * Copyright 2015 Metafizzy + * Copyright 2016 Metafizzy */ ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ @@ -24,7 +23,7 @@ './add-remove-cell', './lazyload' ], factory ); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('./flickity'), diff --git a/js/lazyload.js b/js/lazyload.js index e885cf7..f22357e 100644 --- a/js/lazyload.js +++ b/js/lazyload.js @@ -1,23 +1,19 @@ +// lazyload ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'classie/classie', - 'eventie/eventie', './flickity', 'fizzy-ui-utils/utils' - ], function( classie, eventie, Flickity, utils ) { - return factory( window, classie, eventie, Flickity, utils ); + ], function( Flickity, utils ) { + return factory( window, Flickity, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('desandro-classie'), - require('eventie'), require('./flickity'), require('fizzy-ui-utils') ); @@ -25,23 +21,22 @@ // browser global factory( window, - window.classie, - window.eventie, window.Flickity, window.fizzyUIUtils ); } -}( window, function factory( window, classie, eventie, Flickity, utils ) { +}( window, function factory( window, Flickity, utils ) { 'use strict'; Flickity.createMethods.push('_createLazyload'); +var proto = Flickity.prototype; -Flickity.prototype._createLazyload = function() { - this.on( 'cellSelect', this.lazyLoad ); +proto._createLazyload = function() { + this.on( 'select', this.lazyLoad ); }; -Flickity.prototype.lazyLoad = function() { +proto.lazyLoad = function() { var lazyLoad = this.options.lazyLoad; if ( !lazyLoad ) { return; @@ -51,16 +46,14 @@ Flickity.prototype.lazyLoad = function() { var cellElems = this.getAdjacentCellElements( adjCount ); // get lazy images in those cells var lazyImages = []; - for ( var i=0, len = cellElems.length; i < len; i++ ) { - var cellElem = cellElems[i]; + cellElems.forEach( function( cellElem ) { var lazyCellImages = getCellLazyImages( cellElem ); lazyImages = lazyImages.concat( lazyCellImages ); - } + }); // load lazy images - for ( i=0, len = lazyImages.length; i < len; i++ ) { - var img = lazyImages[i]; + lazyImages.forEach( function( img ) { new LazyLoader( img, this ); - } + }, this ); }; function getCellLazyImages( cellElem ) { @@ -88,8 +81,8 @@ function LazyLoader( img, flickity ) { LazyLoader.prototype.handleEvent = utils.handleEvent; LazyLoader.prototype.load = function() { - eventie.bind( this.img, 'load', this ); - eventie.bind( this.img, 'error', this ); + this.img.addEventListener( 'load', this ); + this.img.addEventListener( 'error', this ); // load image this.img.src = this.img.getAttribute('data-flickity-lazyload'); // remove attr @@ -106,14 +99,14 @@ LazyLoader.prototype.onerror = function( event ) { LazyLoader.prototype.complete = function( event, className ) { // unbind events - eventie.unbind( this.img, 'load', this ); - eventie.unbind( this.img, 'error', this ); + this.img.removeEventListener( 'load', this ); + this.img.removeEventListener( 'error', this ); var cell = this.flickity.getParentCell( this.img ); var cellElem = cell && cell.element; this.flickity.cellSizeChange( cellElem ); - classie.add( this.img, className ); + this.img.classList.add( className ); this.flickity.dispatchEvent( 'lazyLoad', event, cellElem ); }; diff --git a/js/page-dots.js b/js/page-dots.js index d604dfd..90b7210 100644 --- a/js/page-dots.js +++ b/js/page-dots.js @@ -1,22 +1,20 @@ +// page dots ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'eventie/eventie', './flickity', 'tap-listener/tap-listener', 'fizzy-ui-utils/utils' - ], function( eventie, Flickity, TapListener, utils ) { - return factory( window, eventie, Flickity, TapListener, utils ); + ], function( Flickity, TapListener, utils ) { + return factory( window, Flickity, TapListener, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('eventie'), require('./flickity'), require('tap-listener'), require('fizzy-ui-utils') @@ -25,14 +23,13 @@ // browser global factory( window, - window.eventie, window.Flickity, window.TapListener, window.fizzyUIUtils ); } -}( window, function factory( window, eventie, Flickity, TapListener, utils ) { +}( window, function factory( window, Flickity, TapListener, utils ) { // -------------------------- PageDots -------------------------- // @@ -49,21 +46,11 @@ PageDots.prototype._create = function() { // create holder element this.holder = document.createElement('ol'); this.holder.className = 'flickity-page-dots'; - Flickity.setUnselectable( this.holder ); // create dots, array of elements this.dots = []; - // update on select - var _this = this; - this.onCellSelect = function() { - _this.updateSelected(); - }; - this.parent.on( 'cellSelect', this.onCellSelect ); // tap this.on( 'tap', this.onTap ); - // pointerDown - this.on( 'pointerDown', function onPointerDown( button, event ) { - _this.parent.childUIPointerDown( event ); - }); + }; PageDots.prototype.activate = function() { @@ -80,8 +67,8 @@ PageDots.prototype.deactivate = function() { }; PageDots.prototype.setDots = function() { - // get difference between number of cells and number of dots - var delta = this.parent.cells.length - this.dots.length; + // get difference between number of slides and number of dots + var delta = this.parent.slides.length - this.dots.length; if ( delta > 0 ) { this.addDots( delta ); } else if ( delta < 0 ) { @@ -107,10 +94,9 @@ PageDots.prototype.removeDots = function( count ) { // remove from this.dots collection var removeDots = this.dots.splice( this.dots.length - count, count ); // remove from DOM - for ( var i=0, len = removeDots.length; i < len; i++ ) { - var dot = removeDots[i]; + removeDots.forEach( function( dot ) { this.holder.removeChild( dot ); - } + }, this ); }; PageDots.prototype.updateSelected = function() { @@ -134,7 +120,7 @@ PageDots.prototype.onTap = function( event ) { } this.parent.uiChange(); - var index = utils.indexOf( this.dots, target ); + var index = this.dots.indexOf( target ); this.parent.select( index ); }; @@ -152,25 +138,38 @@ utils.extend( Flickity.defaults, { Flickity.createMethods.push('_createPageDots'); -Flickity.prototype._createPageDots = function() { +var proto = Flickity.prototype; + +proto._createPageDots = function() { if ( !this.options.pageDots ) { return; } this.pageDots = new PageDots( this ); + // events this.on( 'activate', this.activatePageDots ); - this.on( 'cellAddedRemoved', this.onCellAddedRemovedPageDots ); + this.on( 'select', this.updateSelectedPageDots ); + this.on( 'cellChange', this.updatePageDots ); + this.on( 'resize', this.updatePageDots ); this.on( 'deactivate', this.deactivatePageDots ); + + this.pageDots.on( 'pointerDown', function( button, event ) { + this.childUIPointerDown( event ); + }.bind( this )); }; -Flickity.prototype.activatePageDots = function() { +proto.activatePageDots = function() { this.pageDots.activate(); }; -Flickity.prototype.onCellAddedRemovedPageDots = function() { +proto.updateSelectedPageDots = function() { + this.pageDots.updateSelected(); +}; + +proto.updatePageDots = function() { this.pageDots.setDots(); }; -Flickity.prototype.deactivatePageDots = function() { +proto.deactivatePageDots = function() { this.pageDots.deactivate(); }; diff --git a/js/player.js b/js/player.js index e3cdac9..6a16aba 100644 --- a/js/player.js +++ b/js/player.js @@ -1,36 +1,33 @@ +// player & autoPlay ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'eventEmitter/EventEmitter', - 'eventie/eventie', + 'ev-emitter/ev-emitter', 'fizzy-ui-utils/utils', './flickity' - ], function( EventEmitter, eventie, utils, Flickity ) { - return factory( EventEmitter, eventie, utils, Flickity ); + ], function( EvEmitter, utils, Flickity ) { + return factory( EvEmitter, utils, Flickity ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( - require('wolfy87-eventemitter'), - require('eventie'), + require('ev-emitter'), require('fizzy-ui-utils'), require('./flickity') ); } else { // browser global factory( - window.EventEmitter, - window.eventie, + window.EvEmitter, window.fizzyUIUtils, window.Flickity ); } -}( window, function factory( EventEmitter, eventie, utils, Flickity ) { +}( window, function factory( EvEmitter, utils, Flickity ) { 'use strict'; @@ -53,24 +50,33 @@ function Player( parent ) { this.state = 'stopped'; // visibility change event handler if ( visibilityEvent ) { - var _this = this; this.onVisibilityChange = function() { - _this.visibilityChange(); - }; + this.visibilityChange(); + }.bind( this ); + this.onVisibilityPlay = function() { + this.visibilityPlay(); + }.bind( this ); } } -Player.prototype = new EventEmitter(); +Player.prototype = Object.create( EvEmitter.prototype ); // start play Player.prototype.play = function() { if ( this.state == 'playing' ) { return; } + // do not play if page is hidden, start playing when page is visible + var isPageHidden = document[ hiddenProperty ]; + if ( visibilityEvent && isPageHidden ) { + document.addEventListener( visibilityEvent, this.onVisibilityPlay ); + return; + } + this.state = 'playing'; // listen to visibility change if ( visibilityEvent ) { - document.addEventListener( visibilityEvent, this.onVisibilityChange, false ); + document.addEventListener( visibilityEvent, this.onVisibilityChange ); } // start ticking this.tick(); @@ -99,7 +105,7 @@ Player.prototype.stop = function() { this.clear(); // remove visibility change event if ( visibilityEvent ) { - document.removeEventListener( visibilityEvent, this.onVisibilityChange, false ); + document.removeEventListener( visibilityEvent, this.onVisibilityChange ); } }; @@ -115,7 +121,7 @@ Player.prototype.pause = function() { }; Player.prototype.unpause = function() { - // re-start play if in unpaused state + // re-start play if paused if ( this.state == 'paused' ) { this.play(); } @@ -123,8 +129,13 @@ Player.prototype.unpause = function() { // pause if page visibility is hidden, unpause if visible Player.prototype.visibilityChange = function() { - var isHidden = document[ hiddenProperty ]; - this[ isHidden ? 'pause' : 'unpause' ](); + var isPageHidden = document[ hiddenProperty ]; + this[ isPageHidden ? 'pause' : 'unpause' ](); +}; + +Player.prototype.visibilityPlay = function() { + this.play(); + document.removeEventListener( visibilityEvent, this.onVisibilityPlay ); }; // -------------------------- Flickity -------------------------- // @@ -134,8 +145,9 @@ utils.extend( Flickity.defaults, { }); Flickity.createMethods.push('_createPlayer'); +var proto = Flickity.prototype; -Flickity.prototype._createPlayer = function() { +proto._createPlayer = function() { this.player = new Player( this ); this.on( 'activate', this.activatePlayer ); @@ -144,56 +156,52 @@ Flickity.prototype._createPlayer = function() { this.on( 'deactivate', this.deactivatePlayer ); }; -Flickity.prototype.activatePlayer = function() { +proto.activatePlayer = function() { if ( !this.options.autoPlay ) { return; } this.player.play(); - eventie.bind( this.element, 'mouseenter', this ); - this.isMouseenterBound = true; + this.element.addEventListener( 'mouseenter', this ); }; // Player API, don't hate the ... thanks I know where the door is -Flickity.prototype.playPlayer = function() { +proto.playPlayer = function() { this.player.play(); }; -Flickity.prototype.stopPlayer = function() { +proto.stopPlayer = function() { this.player.stop(); }; -Flickity.prototype.pausePlayer = function() { +proto.pausePlayer = function() { this.player.pause(); }; -Flickity.prototype.unpausePlayer = function() { +proto.unpausePlayer = function() { this.player.unpause(); }; -Flickity.prototype.deactivatePlayer = function() { +proto.deactivatePlayer = function() { this.player.stop(); - if ( this.isMouseenterBound ) { - eventie.unbind( this.element, 'mouseenter', this ); - delete this.isMouseenterBound; - } + this.element.removeEventListener( 'mouseenter', this ); }; // ----- mouseenter/leave ----- // // pause auto-play on hover -Flickity.prototype.onmouseenter = function() { +proto.onmouseenter = function() { if ( !this.options.pauseAutoPlayOnHover ) { return; } this.player.pause(); - eventie.bind( this.element, 'mouseleave', this ); + this.element.addEventListener( 'mouseleave', this ); }; // resume auto-play on hover off -Flickity.prototype.onmouseleave = function() { +proto.onmouseleave = function() { this.player.unpause(); - eventie.unbind( this.element, 'mouseleave', this ); + this.element.removeEventListener( 'mouseleave', this ); }; // ----- ----- // diff --git a/js/prev-next-button.js b/js/prev-next-button.js index 22841f2..a50d694 100644 --- a/js/prev-next-button.js +++ b/js/prev-next-button.js @@ -1,24 +1,20 @@ -// -------------------------- prev/next button -------------------------- // - +// prev/next buttons ( function( window, factory ) { - 'use strict'; // universal module definition - + /* jshint strict: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ - 'eventie/eventie', './flickity', 'tap-listener/tap-listener', 'fizzy-ui-utils/utils' - ], function( eventie, Flickity, TapListener, utils ) { - return factory( window, eventie, Flickity, TapListener, utils ); + ], function( Flickity, TapListener, utils ) { + return factory( window, Flickity, TapListener, utils ); }); - } else if ( typeof exports == 'object' ) { + } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, - require('eventie'), require('./flickity'), require('tap-listener'), require('fizzy-ui-utils') @@ -27,36 +23,17 @@ // browser global factory( window, - window.eventie, window.Flickity, window.TapListener, window.fizzyUIUtils ); } -}( window, function factory( window, eventie, Flickity, TapListener, utils ) { - +}( window, function factory( window, Flickity, TapListener, utils ) { 'use strict'; -// ----- inline SVG support ----- // - var svgURI = 'http://www.w3.org/2000/svg'; -// only check on demand, not on script load -var supportsInlineSVG = ( function() { - var supports; - function checkSupport() { - if ( supports !== undefined ) { - return supports; - } - var div = document.createElement('div'); - div.innerHTML = '<svg/>'; - supports = ( div.firstChild && div.firstChild.namespaceURI ) == svgURI; - return supports; - } - return checkSupport; -})(); - // -------------------------- PrevNextButton -------------------------- // function PrevNextButton( direction, parent ) { @@ -84,34 +61,25 @@ PrevNextButton.prototype._create = function() { element.setAttribute( 'aria-label', this.isPrevious ? 'previous' : 'next' ); - Flickity.setUnselectable( element ); // create arrow - if ( supportsInlineSVG() ) { - var svg = this.createSVG(); - element.appendChild( svg ); - } else { - // SVG not supported, set button text - this.setArrowText(); - element.className += ' no-svg'; - } + var svg = this.createSVG(); + element.appendChild( svg ); // update on select - var _this = this; - this.onCellSelect = function() { - _this.update(); - }; - this.parent.on( 'cellSelect', this.onCellSelect ); + this.parent.on( 'select', function() { + this.update(); + }.bind( this )); // tap this.on( 'tap', this.onTap ); // pointerDown this.on( 'pointerDown', function onPointerDown( button, event ) { - _this.parent.childUIPointerDown( event ); - }); + this.parent.childUIPointerDown( event ); + }.bind( this )); }; PrevNextButton.prototype.activate = function() { this.bindTap( this.element ); // click events from keyboard - eventie.bind( this.element, 'click', this ); + this.element.addEventListener( 'click', this ); // add to DOM this.parent.element.appendChild( this.element ); }; @@ -122,7 +90,7 @@ PrevNextButton.prototype.deactivate = function() { // do regular TapListener destroy TapListener.prototype.destroy.call( this ); // click events from keyboard - eventie.unbind( this.element, 'click', this ); + this.element.removeEventListener( 'click', this ); }; PrevNextButton.prototype.createSVG = function() { @@ -156,12 +124,6 @@ function getArrowMovements( shape ) { ' Z'; } -PrevNextButton.prototype.setArrowText = function() { - var parentOptions = this.parent.options; - var arrowText = this.isLeft ? parentOptions.leftArrowText : parentOptions.rightArrowText; - utils.setText( this.element, arrowText ); -}; - PrevNextButton.prototype.onTap = function() { if ( !this.isEnabled ) { return; @@ -200,14 +162,14 @@ PrevNextButton.prototype.disable = function() { }; PrevNextButton.prototype.update = function() { - // index of first or last cell, if previous or next - var cells = this.parent.cells; - // enable is wrapAround and at least 2 cells - if ( this.parent.options.wrapAround && cells.length > 1 ) { + // index of first or last slide, if previous or next + var slides = this.parent.slides; + // enable is wrapAround and at least 2 slides + if ( this.parent.options.wrapAround && slides.length > 1 ) { this.enable(); return; } - var lastIndex = cells.length ? cells.length - 1 : 0; + var lastIndex = slides.length ? slides.length - 1 : 0; var boundIndex = this.isPrevious ? 0 : lastIndex; var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable'; this[ method ](); @@ -221,8 +183,6 @@ PrevNextButton.prototype.destroy = function() { utils.extend( Flickity.defaults, { prevNextButtons: true, - leftArrowText: '‹', - rightArrowText: '›', arrowShape: { x0: 10, x1: 60, y1: 50, @@ -232,8 +192,9 @@ utils.extend( Flickity.defaults, { }); Flickity.createMethods.push('_createPrevNextButtons'); +var proto = Flickity.prototype; -Flickity.prototype._createPrevNextButtons = function() { +proto._createPrevNextButtons = function() { if ( !this.options.prevNextButtons ) { return; } @@ -244,13 +205,13 @@ Flickity.prototype._createPrevNextButtons = function() { this.on( 'activate', this.activatePrevNextButtons ); }; -Flickity.prototype.activatePrevNextButtons = function() { +proto.activatePrevNextButtons = function() { this.prevButton.activate(); this.nextButton.activate(); this.on( 'deactivate', this.deactivatePrevNextButtons ); }; -Flickity.prototype.deactivatePrevNextButtons = function() { +proto.deactivatePrevNextButtons = function() { this.prevButton.deactivate(); this.nextButton.deactivate(); this.off( 'deactivate', this.deactivatePrevNextButtons ); diff --git a/js/slide.js b/js/slide.js new file mode 100644 index 0000000..8650b0d --- /dev/null +++ b/js/slide.js @@ -0,0 +1,76 @@ +// slide +( function( window, factory ) { + // universal module definition + /* jshint strict: false */ + if ( typeof define == 'function' && define.amd ) { + // AMD + define( factory ); + } else if ( typeof module == 'object' && module.exports ) { + // CommonJS + module.exports = factory(); + } else { + // browser global + window.Flickity = window.Flickity || {}; + window.Flickity.Slide = factory(); + } + +}( window, function factory() { +'use strict'; + +function Slide( parent ) { + this.parent = parent; + this.isOriginLeft = parent.originSide == 'left'; + this.cells = []; + this.outerWidth = 0; + this.height = 0; +} + +var proto = Slide.prototype; + +proto.addCell = function( cell ) { + this.cells.push( cell ); + this.outerWidth += cell.size.outerWidth; + this.height = Math.max( cell.size.outerHeight, this.height ); + // first cell stuff + if ( this.cells.length == 1 ) { + this.x = cell.x; // x comes from first cell + var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight'; + this.firstMargin = cell.size[ beginMargin ]; + } +}; + +proto.updateTarget = function() { + var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft'; + var lastCell = this.getLastCell(); + var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0; + var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin ); + this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign; +}; + +proto.getLastCell = function() { + return this.cells[ this.cells.length - 1 ]; +}; + +proto.select = function() { + this.changeSelectedClass('add'); +}; + +proto.unselect = function() { + this.changeSelectedClass('remove'); +}; + +proto.changeSelectedClass = function( method ) { + this.cells.forEach( function( cell ) { + cell.element.classList[ method ]('is-selected'); + }); +}; + +proto.getCellElements = function() { + return this.cells.map( function( cell ) { + return cell.element; + }); +}; + +return Slide; + +})); diff --git a/package.json b/package.json index 5152511..d9cc247 100644 --- a/package.json +++ b/package.json @@ -5,29 +5,24 @@ "main": "js/index.js", "style": "css/flickity.css", "dependencies": { - "desandro-classie": "~1.0.1", - "desandro-matches-selector": "~1.0.2", - "doc-ready": "~1.0.3", - "eventie": "~1.0.6", - "get-size": "~1.2.2", - "desandro-get-style-property": "~1.0.4", - "wolfy87-eventemitter": "~4.2.11", - "unidragger": "~1.1.5", - "fizzy-ui-utils": "~1.0.0", - "tap-listener": "~1.1.1" + "desandro-matches-selector": "^2.0.0", + "ev-emitter": "^1.0.2", + "fizzy-ui-utils": "^2.0.0", + "get-size": "^2.0.0", + "tap-listener": "^2.0.0", + "unidragger": "^2.1.0" }, "devDependencies": { "flickity-imagesloaded": "~1.0.0", "flickity-as-nav-for": "~1.0.0", - "jquery-bridget": "~1.1.0", + "jquery-bridget": "^2.0.0", "gulp": "^3.8.10", "gulp-jshint": "^1.9.0", "gulp-rename": "^1.2.0", "gulp-util": "^3.0.2", - "through2": "^0.6.3", - "requirejs": "^2.1.15", "chalk": "^0.5.1", "gulp-replace": "^0.5.1", + "gulp-requirejs-optimize": "github:metafizzy/gulp-requirejs-optimize", "gulp-uglify": "^1.0.2", "gulp-json-lint": "0.0.1", "gulp-clean-css": "^2.0.4", diff --git a/sandbox/adaptive-height.html b/sandbox/adaptive-height.html new file mode 100644 index 0000000..7c01e76 --- /dev/null +++ b/sandbox/adaptive-height.html @@ -0,0 +1,119 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + + <title>slides</title> + + <link rel="stylesheet" href="../css/flickity.css" /> + +<style> +* { box-sizing: border-box; } + +html { overflow-y: scroll; } + +.carousel { + border: 1px solid; + margin-bottom: 40px; +} + +.flickity-viewport { + overflow: visible; + transition: height 0.2s; +} + +.carousel__cell { + width: 32%; + height: 100px; + background: #BDF; + margin-left: 1%; + margin-right: 1%; + font-size: 40px; +} + +.carousel__cell.is-selected { + background: #68F; +} + +.carousel__cell--height2 { height: 200px; } +.carousel__cell--height3 { height: 300px; } +.carousel__cell--height4 { height: 400px; } + +/* ---- ---- */ + +.image-carousel img { + display: block; + width: 50%; +} + +</style> + +</head> +<body> + + <h1>slides</h1> + +<div class="carousel carousel1"> + <div class="carousel__cell carousel__cell--height2">0</div> + <div class="carousel__cell">1</div> + <div class="carousel__cell">2</div> + <div class="carousel__cell carousel__cell--height2">3</div> + <div class="carousel__cell carousel__cell--height3">4</div> + <div class="carousel__cell">5</div> + <div class="carousel__cell carousel__cell--height4">6</div> + <div class="carousel__cell">7</div> + <div class="carousel__cell carousel__cell--height3">8</div> + <div class="carousel__cell">9</div> + <div class="carousel__cell">10</div> +</div> + +<div class="carousel image-carousel"> + <img src="http://i.imgur.com/r8p3Xgq.jpg" /> + <img src="http://i.imgur.com/q9zO6tw.jpg" /> + <img src="http://i.imgur.com/bwy74ok.jpg" /> + <img src="http://i.imgur.com/bAZWoqx.jpg" /> + <img src="http://i.imgur.com/PgmEBSB.jpg" /> + <img src="http://i.imgur.com/aboaFoB.jpg" /> + <img src="http://i.imgur.com/LkmcILl.jpg" /> + <img src="http://i.imgur.com/hODreXI.jpg" /> + <img src="http://i.imgur.com/UORFJ3w.jpg" /> +</div> + +<script src="../bower_components/get-size/get-size.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> +<script src="../bower_components/unipointer/unipointer.js"></script> +<script src="../bower_components/unidragger/unidragger.js"></script> +<script src="../bower_components/tap-listener/tap-listener.js"></script> +<script src="../bower_components/fizzy-ui-utils/utils.js"></script> + +<script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> +<script src="../js/animate.js"></script> +<script src="../js/flickity.js"></script> +<script src="../js/drag.js"></script> +<script src="../js/prev-next-button.js"></script> +<script src="../js/page-dots.js"></script> +<script src="../js/player.js"></script> +<script src="../js/add-remove-cell.js"></script> +<script src="../js/lazyload.js"></script> + +<script> +var flkty = new Flickity( '.carousel1', { + adaptiveHeight: true, + // groupCells: true, + // wrapAround: true, +}); + +var imgFlkty = new Flickity( '.image-carousel', { + adaptiveHeight: true +}); + +window.onload = function() { + imgFlkty.reposition(); +} +</script> + +</body> +</html> diff --git a/sandbox/add-remove.html b/sandbox/add-remove.html index aeb9e86..4134ec4 100644 --- a/sandbox/add-remove.html +++ b/sandbox/add-remove.html @@ -115,19 +115,32 @@ </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> + <h2>reposition</h2> + + <div id="reposition"> + <div class="container variable-width"> + <div class="cell w2"><b>1</b></div> + <div class="cell"><b>2</b></div> + <div class="cell w3"><b>3</b></div> + <div class="cell"><b>4</b></div> + <div class="cell"><b>5</b></div> + <div class="cell w2"><b>6</b></div> + <div class="cell"><b>7</b></div> + <div class="cell w2"><b>8</b></div> + <div class="cell"><b>9</b></div> + </div> + </div> + <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> @@ -138,7 +151,6 @@ <script> -var utils = fizzyUIUtils; var cellCount = 6; function randInt( num ) { @@ -157,11 +169,11 @@ function makeCell() { var cell = document.createElement('div'); cell.className = 'cell ' + getRandom( widthClasses ) + ' ' + getRandom( nClasses ); var b = document.createElement('b'); - utils.setText( b, ++cellCount ); + b.textContent = ++cellCount; cell.appendChild( b ); var removeButton = document.createElement('button'); removeButton.className = 'remove-button'; - utils.setText( removeButton, '×' ); + removeButton.textContent = '×'; cell.appendChild( removeButton ); return cell; } @@ -207,18 +219,31 @@ function onAppendClick( event ) { flkty.append([ makeCell(), makeCell(), makeCell() ]); } -window.onload = function() { +// init +var demos = document.querySelectorAll('.demo'); +for ( var i=0; i < demos.length; i++ ) { + var demo = demos[i]; + demo.querySelector('.container').addEventListener( 'click', onContainerClick ); + demo.querySelector('.prepend-button').addEventListener( 'click', onPrependClick ); + demo.querySelector('.insert-button').addEventListener( 'click', onInsertClick ); + demo.querySelector('.append-button').addEventListener( 'click', onAppendClick ); +} - var demos = document.querySelectorAll('.demo'); - for ( var i=0, len = demos.length; i < len; i++ ) { - var demo = demos[i]; - eventie.bind( demo.querySelector('.container'), 'click', onContainerClick ); - eventie.bind( demo.querySelector('.prepend-button'), 'click', onPrependClick ); - eventie.bind( demo.querySelector('.insert-button'), 'click', onInsertClick ); - eventie.bind( demo.querySelector('.append-button'), 'click', onAppendClick ); - } +// ----- reposition ----- // + +(function() { + var flkty = new Flickity('#reposition .container'); + flkty.on( 'staticClick', function( event, pointer, cellElem ) { + cellElem.classList.toggle('w3'); + flkty.reposition(); + }); -}; + window.mapTargets = function() { + return flkty.slides.map( function( slide ) { + return ~~slide.target; + }); + } +})(); </script> diff --git a/sandbox/ajax.html b/sandbox/ajax.html index c9103fc..8cf8a64 100644 --- a/sandbox/ajax.html +++ b/sandbox/ajax.html @@ -24,22 +24,19 @@ <div class="gallery"></div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../bower_components/imagesloaded/imagesloaded.js"></script> <script src="../bower_components/jquery/dist/jquery.min.js"></script> -<script src="../bower_components/jquery-bridget/jquery.bridget.js"></script> +<script src="../bower_components/jquery-bridget/jquery-bridget.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/basic.html b/sandbox/basic.html index 8c218c5..a7ab003 100644 --- a/sandbox/basic.html +++ b/sandbox/basic.html @@ -155,19 +155,16 @@ <div class="cell n2"></div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> @@ -186,7 +183,7 @@ window.onload = function() { // flky.on( 'dragMove', function( event, pointer ) { // console.log( event.type, pointer.pageX, pointer.pageY ); // }); - flky.on( 'cellSelect', function() { + flky.on( 'select', function() { console.log('selected', flky.selectedIndex ); }); diff --git a/sandbox/freescroll.html b/sandbox/freescroll.html index 42d55d5..8b23f22 100644 --- a/sandbox/freescroll.html +++ b/sandbox/freescroll.html @@ -77,19 +77,16 @@ <div class="gallery-cell"></div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/group-cells.html b/sandbox/group-cells.html new file mode 100644 index 0000000..8be70e2 --- /dev/null +++ b/sandbox/group-cells.html @@ -0,0 +1,103 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + + <title>group cells</title> + + <link rel="stylesheet" href="../css/flickity.css" /> + +<style> +* { box-sizing: border-box; } + +html { overflow-y: scroll; } + +.carousel { + border: 1px solid; + margin-bottom: 40px; +/* width: 1000px;*/ +} + +.carousel__cell { +/* width: 25%;*/ + width: 32%; + height: 200px; + background: #BDF; + margin-left: 1%; + margin-right: 1%; + font-size: 40px; +} + +/*.carousel__cell--width2 { width: 40%; } +.carousel__cell--width3 { width: 80%; }*/ + +.carousel__cell--width2 { width: 66%; } +.carousel__cell--width3 { width: 100%; } + +.carousel__cell.is-selected { + background: #68F; +} + +@media (min-width: 1000px) { + /* fit four */ + .carousel__cell { width: 23.5%; } + .carousel__cell--width2 { width: 49%; } + .carousel__cell--width3 { width: 74.5%; } +} + + +</style> + +</head> +<body> + + <h1>group cells</h1> + +<div class="carousel carousel1"> + <div class="carousel__cell carousel__cell--width2">0</div> + <div class="carousel__cell">1</div> + <div class="carousel__cell">2</div> + <div class="carousel__cell carousel__cell--width2">3</div> + <div class="carousel__cell carousel__cell--width2">4</div> + <div class="carousel__cell">5</div> + <div class="carousel__cell">6</div> + <div class="carousel__cell">7</div> + <div class="carousel__cell carousel__cell--width3">8</div> + <div class="carousel__cell">9</div> + <div class="carousel__cell">10</div> +</div> + + + +<script src="../bower_components/get-size/get-size.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> +<script src="../bower_components/unipointer/unipointer.js"></script> +<script src="../bower_components/unidragger/unidragger.js"></script> +<script src="../bower_components/tap-listener/tap-listener.js"></script> +<script src="../bower_components/fizzy-ui-utils/utils.js"></script> + +<script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> +<script src="../js/animate.js"></script> +<script src="../js/flickity.js"></script> +<script src="../js/drag.js"></script> +<script src="../js/prev-next-button.js"></script> +<script src="../js/page-dots.js"></script> +<script src="../js/player.js"></script> +<script src="../js/add-remove-cell.js"></script> +<script src="../js/lazyload.js"></script> + +<script> +var flkty = new Flickity( '.carousel1', { + groupCells: true, + wrapAround: true, + // cellAlign: 'right' +}); + + +</script> + +</body> +</html> diff --git a/sandbox/jquery.html b/sandbox/jquery.html index cca1cdc..a3b53e0 100644 --- a/sandbox/jquery.html +++ b/sandbox/jquery.html @@ -32,21 +32,18 @@ <div class="cell n6">6</div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../bower_components/jquery/dist/jquery.min.js"></script> -<script src="../bower_components/jquery-bridget/jquery.bridget.js"></script> +<script src="../bower_components/jquery-bridget/jquery-bridget.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> @@ -65,15 +62,15 @@ $( function() { // console.log( event.type, pointer.pageX, pointer.pageY ); // }); - $gallery1.on( 'cellSelect', function() { - console.log('selected', flkty.selectedIndex ); + $gallery1.on( 'cellSelect.flickity', function( event ) { + console.log('selected', event.type, 'ns:' + event.namespace, flkty.selectedIndex ); }); - $gallery1.on( 'settle', function( event ) { + $gallery1.on( 'settle.flickity', function( event ) { console.log('settled', flkty.x, event.type ); }); - $gallery1.on( 'staticClick', function( event ) { + $gallery1.on( 'staticClick.flickity', function( event ) { console.log('staticClick', event.type ); }); diff --git a/sandbox/lazyload.html b/sandbox/lazyload.html index f888e4a..7607023 100644 --- a/sandbox/lazyload.html +++ b/sandbox/lazyload.html @@ -112,21 +112,18 @@ <!-- jQuery --> <script src="../bower_components/jquery/dist/jquery.js"></script> -<script src="../bower_components/jquery-bridget/jquery.bridget.js"></script> +<script src="../bower_components/jquery-bridget/jquery-bridget.js"></script> <!-- dependencies --> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <!-- Flickity --> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> @@ -137,7 +134,6 @@ <script src="../js/lazyload.js"></script> <script> -docReady( function() { var $jQCarousel = $('.carousel--jq').flickity({ lazyLoad: true @@ -146,7 +142,6 @@ docReady( function() { $jQCarousel.on( 'lazyLoad', function( event, cellElem ) { }); -}); </script> </body> diff --git a/sandbox/media.html b/sandbox/media.html index 1c68572..e0d4c34 100644 --- a/sandbox/media.html +++ b/sandbox/media.html @@ -117,19 +117,16 @@ </div> </div> --> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/right-to-left.html b/sandbox/right-to-left.html index 74a29db..44aaa54 100644 --- a/sandbox/right-to-left.html +++ b/sandbox/right-to-left.html @@ -35,19 +35,16 @@ <div class="cell n6"><b>6</b></div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/scroll-event.html b/sandbox/scroll-event.html new file mode 100644 index 0000000..b84ac8f --- /dev/null +++ b/sandbox/scroll-event.html @@ -0,0 +1,268 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + + <title>scroll event</title> + + <link rel="stylesheet" href="../css/flickity.css" /> + +<style> +* { box-sizing: border-box; } + +html { overflow-y: scroll; } + +.carousel { + border: 1px solid; + margin-bottom: 40px; +/* width: 1000px;*/ +} + +.carousel__cell { +/* width: 25%;*/ + width: 32%; + height: 200px; + background: #BDF; + margin-left: 1%; + margin-right: 1%; + font-size: 40px; +} + +/*.carousel__cell--width2 { width: 40%; } +.carousel__cell--width3 { width: 80%; }*/ + +.carousel__cell--width2 { width: 66%; } +.carousel__cell--width3 { width: 100%; } + +.carousel__cell.is-selected { + background: #68F; +} + +.progress-bar { + height: 10px; + width: 0; + background: #333; +} + +@media (min-width: 1000px) { + /* fit four */ + .carousel__cell { width: 23.5%; } + .carousel__cell--width2 { width: 49%; } + .carousel__cell--width3 { width: 74.5%; } +} + + + +/* ---- parallax ---- */ + +.parallax { + margin-top: 100px; + position: relative; + overflow-x: hidden; + padding-bottom: 40px; +} + +.parallax__carousel__cell { + background: hsla(0, 100%, 50%, 0.4); + height: 220px; + width: 50%; + margin: 40px 5%; +} + +.parallax__layer { + position: absolute; + left: 0; + top: 0; +} + +.parallax__layer--bg { + top: 70px; + width: 80%; + height: 160px; +} + +.parallax__layer--fg { + pointer-events: none; + width: 125%; + height: 300px; +} + +.parallax__layer__cell { + position: absolute; + width: 50%; + margin: 0 5%; + height: 100%; +} + +.parallax__layer__cell:nth-child(1) { left: 0%; } +.parallax__layer__cell:nth-child(2) { left: 60%; } +.parallax__layer__cell:nth-child(3) { left: 120%; } +.parallax__layer__cell:nth-child(4) { left: 180%; } +.parallax__layer__cell:nth-child(5) { left: 240%; } + +.parallax__layer__cell--bg { + background: hsla(210, 100%, 50%, 0.4); +} + +.parallax__layer__cell--fg { + background: hsla(60, 100%, 50%, 0.4); +} + + +/* ---- ---- */ + +.image-carousel__cell { + margin-right: 20px; + overflow: hidden; +} + +.image-carousel__cell img { + display: block; + height: 400px; +} +</style> + +</head> +<body> + + <h1>scroll event</h1> + +<div class="carousel carousel1"> + <div class="carousel__cell carousel__cell--width2">0</div> + <div class="carousel__cell">1</div> + <div class="carousel__cell">2</div> + <div class="carousel__cell carousel__cell--width2">3</div> + <div class="carousel__cell carousel__cell--width2">4</div> + <div class="carousel__cell">5</div> + <div class="carousel__cell">6</div> + <div class="carousel__cell">7</div> + <div class="carousel__cell carousel__cell--width3">8</div> + <div class="carousel__cell">9</div> + <div class="carousel__cell">10</div> +</div> + +<div class="progress-bar"></div> + +<div class="parallax"> + + <div class="parallax__layer parallax__layer--bg"> + <div class="parallax__layer__cell parallax__layer__cell--bg"></div> + <div class="parallax__layer__cell parallax__layer__cell--bg"></div> + <div class="parallax__layer__cell parallax__layer__cell--bg"></div> + <div class="parallax__layer__cell parallax__layer__cell--bg"></div> + <div class="parallax__layer__cell parallax__layer__cell--bg"></div> + </div> + + <div class="parallax__carousel"> + <div class="parallax__carousel__cell"></div> + <div class="parallax__carousel__cell"></div> + <div class="parallax__carousel__cell"></div> + <div class="parallax__carousel__cell"></div> + <div class="parallax__carousel__cell"></div> + </div> + + <div class="parallax__layer parallax__layer--fg"> + <div class="parallax__layer__cell parallax__layer__cell--fg"></div> + <div class="parallax__layer__cell parallax__layer__cell--fg"></div> + <div class="parallax__layer__cell parallax__layer__cell--fg"></div> + <div class="parallax__layer__cell parallax__layer__cell--fg"></div> + <div class="parallax__layer__cell parallax__layer__cell--fg"></div> + </div> + +</div> + +<div class="image-carousel"> + <div class="image-carousel__cell"><img src="http://i.imgur.com/r8p3Xgq.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/q9zO6tw.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/bwy74ok.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/hODreXI.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/UORFJ3w.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/bAZWoqx.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/PgmEBSB.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/aboaFoB.jpg" /></div> + <div class="image-carousel__cell"><img src="http://i.imgur.com/LkmcILl.jpg" /></div> + </div> + +<script src="../bower_components/get-size/get-size.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> +<script src="../bower_components/unipointer/unipointer.js"></script> +<script src="../bower_components/unidragger/unidragger.js"></script> +<script src="../bower_components/tap-listener/tap-listener.js"></script> +<script src="../bower_components/fizzy-ui-utils/utils.js"></script> + +<script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> +<script src="../js/animate.js"></script> +<script src="../js/flickity.js"></script> +<script src="../js/drag.js"></script> +<script src="../js/prev-next-button.js"></script> +<script src="../js/page-dots.js"></script> +<script src="../js/player.js"></script> +<script src="../js/add-remove-cell.js"></script> +<script src="../js/lazyload.js"></script> + +<script> +var flkty = new Flickity( '.carousel1', { + initialIndex: 2, + // groupCells: true, + // wrapAround: true, + // cellAlign: 'right' +}); + +var progressBar = document.querySelector('.progress-bar'); + +flkty.on( 'scroll', function( progress ) { + console.log( progress ); + var width = Math.max( 0, Math.min( 1, progress ) ); + progressBar.style.width = width * 100 + '%'; +}); + +flkty.reposition(); + +// ----- ----- // + +var paraBG = document.querySelector('.parallax__layer--bg'); +var paraFG = document.querySelector('.parallax__layer--fg'); + +var paraFlkty = new Flickity( '.parallax__carousel', { + +}); + +var cellRatio = 0.6; +var bgRatio = 0.8; +var fgRatio = 1.25; + +paraFlkty.on( 'scroll', function( progress ) { + // console.log( progress ); + paraBG.style.left = ( 0.5 - ( 0.5 + progress * 4 ) * cellRatio * bgRatio ) * 100 + '%'; + paraFG.style.left = ( 0.5 - ( 0.5 + progress * 4 ) * cellRatio * fgRatio ) * 100 + '%'; +}); + +paraFlkty.reposition(); + +// ----- ----- // + + +var imgFlkty = new Flickity( '.image-carousel', { +}); + +window.onload = function() { + imgFlkty.reposition(); +} + +var imgs = document.querySelectorAll('.image-carousel img'); + +imgFlkty.on( 'scroll', function( progress ) { + imgFlkty.slides.forEach( function( slide, i ) { + var img = imgs[i]; + var x = ( slide.target + imgFlkty.x ) * -0.333; + img.style.transform = 'translateX( ' + x + 'px)'; + }); +}); + +</script> + +</body> +</html> diff --git a/sandbox/single.html b/sandbox/single.html index 49492d6..fc19208 100644 --- a/sandbox/single.html +++ b/sandbox/single.html @@ -24,19 +24,16 @@ <div class="cell n1">7</div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/styles.html b/sandbox/styles.html index 08cea91..00a476e 100644 --- a/sandbox/styles.html +++ b/sandbox/styles.html @@ -38,19 +38,16 @@ <div class="cell">5</div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/sandbox/tap-listener.html b/sandbox/tap-listener.html index 40a1632..e254cff 100644 --- a/sandbox/tap-listener.html +++ b/sandbox/tap-listener.html @@ -26,16 +26,12 @@ <div class="button1">Button 1</div> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script> -window.onload = function() { - - var tapListener = window.tapListener = new TapListener( document.querySelector('.button1') ); tapListener.on( 'tap', function() { @@ -44,7 +40,6 @@ window.onload = function() { document.body.appendChild( p ); }); -}; </script> </body> diff --git a/sandbox/v2-sizzle.html b/sandbox/v2-sizzle.html new file mode 100644 index 0000000..1f819ae --- /dev/null +++ b/sandbox/v2-sizzle.html @@ -0,0 +1,218 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + + <title>v2 sizzle</title> + + <link rel="stylesheet" href="../css/flickity.css" media="screen" /> + + <style> + + /* Texta Regular */ + @font-face { + font-family: 'Texta'; + src: url('2D333F_2_0.woff2') format('woff2'); + } + + body { font-family: Texta; } + + * { box-sizing: border-box; } + + .parallax-container { + position: relative; + width: 360px; + height: 400px; + overflow: hidden; + margin: 40px auto; + } + + .carousel { + width: 100%; + } + + .flickity-viewport { + transition: height 0.2s; + } + + .cell { + width: 360px; + height: 200px; + margin-right: 10px; + background: #8C8; + border-radius: 8px; + } + + .cell--half-width { + width: 175px; + } + + .cell--third-width { + width: calc((360px - 20px) / 3); + } + + .cell--height1 { + height: 300px; + } + + .cell--height2 { + height: 250px; + } + + .cell__word { + color: white; + font-size: 54px; + line-height: 1.0; + display: block; + padding: 20px; + width: 100%; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + text-align: center; + } + + + .cell--half-width .cell__word { + font-size: 40px; + } + + .cell__word--group { text-align: right; } + .cell__word--cells { text-align: left; } + + .cell--parallax { opacity: 0.6; } + + .flickity-prev-next-button { + width: 36px; + height: 36px; + } + + .parallax-layer { + position: absolute; + left: 0; + top: 0; + pointer-events: none; + } + + .parallax-layer--bg { + width: calc((100% + 10px)* 0.7); + } + + .parallax-bg-cell { + width: 252px; + height: 140px; + background: #19F; + position: absolute; + top: 30px; + border-radius: 6px; + opacity: 0.6; + } + +/* .parallax-bg-cell:nth-child(1) { left: 0px; } + .parallax-bg-cell:nth-child(2) { left: 296px; } + .parallax-bg-cell:nth-child(3) { left: 592px; } + .parallax-bg-cell:nth-child(4) { left: 888px; }*/ + .parallax-bg-cell:nth-child(1) { left: 1036px; } + .parallax-bg-cell:nth-child(2) { left: 1295px; } + + .parallax-layer--fg { + width: calc((100% + 10px)* 1.5); + } + + .parallax-fg-cell { + width: 100%; + position: absolute; + top: 0; + font-size: 54px; + line-height: 200px; + text-align: center; + color: white; + } + + .parallax-fg-cell:nth-child(1) { left: 400%; } + .parallax-fg-cell:nth-child(2) { left: 500%; } + .parallax-fg-cell:nth-child(3) { left: 600%; } + + </style> + +</head> +<body> + +<div class="parallax-container"> + <div class="parallax-layer parallax-layer--bg"> + <!-- <div class="parallax-bg-cell"></div> + <div class="parallax-bg-cell"></div> + <div class="parallax-bg-cell"></div> + <div class="parallax-bg-cell"></div> --> + <div class="parallax-bg-cell"></div> + <div class="parallax-bg-cell"></div> + </div> + + <div class="carousel"> + <div class="cell cell--half-width"> + <span class="cell__word cell__word--group">Group</span> + </div> + <div class="cell cell--half-width"> + <span class="cell__word cell__word--cells">cells</span> + </div> + <div class="cell cell--third-width"></div> + <div class="cell cell--third-width"></div> + <div class="cell cell--third-width"></div> + <div class="cell cell--height1"> + <span class="cell__word">Adaptive height</span> + </div> + <div class="cell"> + </div> + <div class="cell cell--parallax"></div> + <div class="cell cell--parallax"></div> + <div class="cell"></div> + </div> + + <div class="parallax-layer parallax-layer--fg"> + <div class="parallax-fg-cell">Parallax</div> + <div class="parallax-fg-cell">whoa</div> + <div class="parallax-fg-cell">Flickity v2</div> + </div> +</div> + +<script src="../bower_components/get-size/get-size.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> +<script src="../bower_components/unipointer/unipointer.js"></script> +<script src="../bower_components/unidragger/unidragger.js"></script> +<script src="../bower_components/tap-listener/tap-listener.js"></script> +<script src="../bower_components/fizzy-ui-utils/utils.js"></script> + +<script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> +<script src="../js/animate.js"></script> +<script src="../js/flickity.js"></script> +<script src="../js/drag.js"></script> +<script src="../js/prev-next-button.js"></script> +<script src="../js/page-dots.js"></script> +<script src="../js/player.js"></script> +<script src="../js/add-remove-cell.js"></script> + +<script> +var flkty = new Flickity( '.carousel', { + groupCells: true, + adaptiveHeight: true, + wrapAround: true, +}); + +var paraBg = document.querySelector('.parallax-layer--bg'); +var paraFg = document.querySelector('.parallax-layer--fg'); +var count = flkty.slides.length - 1; + +flkty.on( 'scroll', function( progress ) { + paraBg.style.left = ( 0.5 - ( 0.5 + progress * count ) * 0.7 ) * (37/36) * 100 + '%'; + paraFg.style.left = ( 0.5 - ( 0.5 + progress * count ) *1.5 ) * (37/36) * 100 + '%'; +}); + +flkty.reposition(); +</script> + +</body> +</html> diff --git a/sandbox/wrap-around.html b/sandbox/wrap-around.html index f518af8..18e2b7a 100644 --- a/sandbox/wrap-around.html +++ b/sandbox/wrap-around.html @@ -106,19 +106,16 @@ <div class="cell n5">5</div> </div> -<script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> -<script src="../bower_components/matches-selector/matches-selector.js"></script> -<script src="../bower_components/eventEmitter/EventEmitter.js"></script> -<script src="../bower_components/eventie/eventie.js"></script> -<script src="../bower_components/doc-ready/doc-ready.js"></script> -<script src="../bower_components/classie/classie.js"></script> +<script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> +<script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../js/cell.js"></script> +<script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/test/.jshintrc b/test/.jshintrc index 09697b0..677c29f 100644 --- a/test/.jshintrc +++ b/test/.jshintrc @@ -7,23 +7,6 @@ "predef": { "Flickity": false, "matchesSelector": false, - "classie": false, - "docReady": false, - - "asyncTest": false, - "deepEqual": false, - "equal": false, - "expect": false, - "module": false, - "notDeepEqual": false, - "notEqual": false, - "notStrictEqual": false, - "ok": false, - "QUnit": false, - "raises": false, - "start": false, - "stop": false, - "strictEqual": false, - "test": false + "QUnit": false } } diff --git a/test/drag.html b/test/drag.html index b2dec65..eac906c 100644 --- a/test/drag.html +++ b/test/drag.html @@ -26,20 +26,17 @@ <script src="../bower_components/qunit/qunit/qunit.js"></script> <!-- dependencies --> - <script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> - <script src="../bower_components/matches-selector/matches-selector.js"></script> - <script src="../bower_components/eventEmitter/EventEmitter.js"></script> - <script src="../bower_components/eventie/eventie.js"></script> - <script src="../bower_components/doc-ready/doc-ready.js"></script> - <script src="../bower_components/classie/classie.js"></script> + <script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> + <script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> - <script src="../bower_components/imagesloaded/imagesloaded.js"></script> +<!-- <script src="../bower_components/imagesloaded/imagesloaded.js"></script> --> <!-- Flickity source --> <script src="../js/cell.js"></script> + <script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> diff --git a/test/index.html b/test/index.html index 5dc7d2e..6de5c26 100644 --- a/test/index.html +++ b/test/index.html @@ -13,20 +13,17 @@ <script src="../bower_components/qunit/qunit/qunit.js"></script> <!-- dependencies --> - <script src="../bower_components/get-style-property/get-style-property.js"></script> <script src="../bower_components/get-size/get-size.js"></script> - <script src="../bower_components/matches-selector/matches-selector.js"></script> - <script src="../bower_components/eventEmitter/EventEmitter.js"></script> - <script src="../bower_components/eventie/eventie.js"></script> - <script src="../bower_components/doc-ready/doc-ready.js"></script> - <script src="../bower_components/classie/classie.js"></script> - <script src="../bower_components/imagesloaded/imagesloaded.js"></script> +<!-- <script src="../bower_components/imagesloaded/imagesloaded.js"></script> --> + <script src="../bower_components/desandro-matches-selector/matches-selector.js"></script> + <script src="../bower_components/ev-emitter/ev-emitter.js"></script> <script src="../bower_components/fizzy-ui-utils/utils.js"></script> <script src="../bower_components/unipointer/unipointer.js"></script> <script src="../bower_components/unidragger/unidragger.js"></script> <script src="../bower_components/tap-listener/tap-listener.js"></script> <!-- Flickity source --> <script src="../js/cell.js"></script> + <script src="../js/slide.js"></script> <script src="../js/animate.js"></script> <script src="../js/flickity.js"></script> <script src="../js/drag.js"></script> @@ -58,6 +55,9 @@ <script src="unit/add-remove-cells.js"></script> <script src="unit/destroy.js"></script> <script src="unit/lazyload.js"></script> + <script src="unit/group-cells.js"></script> + <script src="unit/adaptive-height.js"></script> + <script src="unit/select-cell.js"></script> </head> <body> @@ -216,5 +216,54 @@ <div class="cell"><img data-flickity-lazyload="http://i.imgur.com/LkmcILl.jpg" /></div> </div> + <h2>groupCells</h2> + <div id="group-cells" class="gallery"> + <div class="cell"></div> + <div class="cell cell--width2"></div> + <div class="cell"></div> + + <div class="cell cell--width3"></div> + <div class="cell"></div> + + <div class="cell cell--width2"></div> + <div class="cell cell--width2"></div> + + <div class="cell cell--width2"></div> + + <div class="cell cell--width4"></div> + + <div class="cell"></div> + <div class="cell"></div> + <div class="cell cell--width2"></div> + + <div class="cell"></div> + <div class="cell"></div> + </div> + + <h2>adaptiveHeight</h2> + <div id="adaptive-height" class="gallery"> + <div class="cell cell--height2"></div> + <div class="cell"></div> + <div class="cell cell--height3"></div> + + <div class="cell"></div> + <div class="cell cell--height4"></div> + <div class="cell cell--height2"></div> + + <div class="cell"></div> + <div class="cell cell--height2"></div> + </div> + + <div id="select-cell" class="gallery"> + <div class="cell select-cell__0">0</div> + <div class="cell select-cell__1">1</div> + <div class="cell select-cell__2">2</div> + <div class="cell select-cell__3">3</div> + <div class="cell select-cell__4">4</div> + <div class="cell select-cell__5">5</div> + <div class="cell select-cell__6">6</div> + <div class="cell select-cell__7">7</div> + </div> + </body> </html> diff --git a/test/test.css b/test/test.css index 4759fcf..f8ef806 100644 --- a/test/test.css +++ b/test/test.css @@ -1,3 +1,5 @@ +/** { box-sizing: border-box; }*/ + body { font-family: sans-serif; color: #333; @@ -37,3 +39,32 @@ body { display: block; max-height: 100px; } + +/* ---- group-cells ---- */ + +#group-cells .cell { + width: 100px; +/* border: 1px solid;*/ +} + +#group-cells .cell--width2 { width: 200px; } +#group-cells .cell--width3 { width: 300px; } +#group-cells .cell--width4 { width: 400px; } + +#group-cells.is-expanded { width: 600px; } + +#group-cells .cell:nth-child(2n) { background: #09F; } + +/* ---- adaptive-height ---- */ + +#adaptive-height .cell { width: 33.33%; } + +#adaptive-height .cell--height2 { height: 200px; } +#adaptive-height .cell--height3 { height: 300px; } +#adaptive-height .cell--height4 { height: 400px; } + +#adaptive-height .cell:nth-child(2n) { background: #09F; } + +/* ---- select-cell ---- */ + +#select-cell .cell { width: 33.33%; } diff --git a/test/unit/adaptive-height.js b/test/unit/adaptive-height.js new file mode 100644 index 0000000..655ac4a --- /dev/null +++ b/test/unit/adaptive-height.js @@ -0,0 +1,29 @@ +QUnit.test( 'adaptiveHeight', function( assert ) { + 'use strict'; + + var flkty = new Flickity( '#adaptive-height', { + adaptiveHeight: true + }); + + // 2,1,3, 1,4,2, 1,2,1 + + function checkSelectHeight( index, height ) { + flkty.select( index, false, true ); + assert.equal( flkty.viewport.style.height, height + 'px', 'slide ' + index ); + } + + checkSelectHeight( 0, 200 ); + checkSelectHeight( 1, 100 ); + checkSelectHeight( 2, 300 ); + checkSelectHeight( 3, 100 ); + checkSelectHeight( 4, 400 ); + checkSelectHeight( 5, 200 ); + + flkty.options.groupCells = true; + flkty.resize(); + + checkSelectHeight( 0, 300 ); + checkSelectHeight( 1, 400 ); + checkSelectHeight( 2, 200 ); + +}); diff --git a/test/unit/add-remove-cells.js b/test/unit/add-remove-cells.js index 29786f8..b483839 100644 --- a/test/unit/add-remove-cells.js +++ b/test/unit/add-remove-cells.js @@ -1,5 +1,4 @@ -test( 'add/remove cells', function() { - +QUnit.test( 'add/remove cells', function( assert ) { 'use strict'; function makeCellElem() { @@ -16,77 +15,75 @@ test( 'add/remove cells', function() { return isPercent ? diff < 0.1 : diff <= 1; } - var elem = document.querySelector('#add-remove-cells'); var flkty = new Flickity( elem ); var sliderElem = elem.querySelector('.flickity-slider'); function checkCellElem( cellElem, index, message ) { - equal( sliderElem.children[ index ], cellElem, message + ' cell element in DOM correct' ); - equal( flkty.cells[ index ].element, cellElem, message + ' element added as cell' ); - ok( isPositionApprox( cellElem.style.left, index * 25 ), ' element positioned' ); + assert.equal( sliderElem.children[ index ], cellElem, message + ' cell element in DOM correct' ); + assert.equal( flkty.cells[ index ].element, cellElem, message + ' element added as cell' ); + assert.ok( isPositionApprox( cellElem.style.left, index * 25 ), ' element positioned' ); } // prepend cell element var cellElem = makeCellElem(); flkty.prepend( cellElem ); checkCellElem( cellElem, 0, 'prepended' ); - equal( flkty.selectedIndex, 1, 'selectedIndex +1 after prepend' ); + assert.equal( flkty.selectedIndex, 1, 'selectedIndex +1 after prepend' ); // append cell element cellElem = makeCellElem(); flkty.append( cellElem ); var lastIndex = flkty.cells.length - 1; checkCellElem( cellElem, lastIndex, 'appended' ); - equal( flkty.selectedIndex, 1, 'selectedIndex same after prepend' ); + assert.equal( flkty.selectedIndex, 1, 'selectedIndex same after prepend' ); // insert single cell element cellElem = makeCellElem(); // this one gets removed first flkty.select( 2 ); flkty.insert( cellElem, 2 ); checkCellElem( cellElem, 2, 'single inserted' ); - equal( flkty.selectedIndex, 3, 'selectedIndex +1 after insert before' ); + assert.equal( flkty.selectedIndex, 3, 'selectedIndex +1 after insert before' ); flkty.insert( makeCellElem(), 4 ); - equal( flkty.selectedIndex, 3, 'selectedIndex same after insert before' ); + assert.equal( flkty.selectedIndex, 3, 'selectedIndex same after insert before' ); // insert multiple cell elements var cellElems = [ makeCellElem(), makeCellElem(), makeCellElem() ]; flkty.insert( cellElems, 3 ); checkCellElem( cellElems[0], 3, 'first multiple inserted' ); checkCellElem( cellElems[1], 4, 'second multiple inserted' ); checkCellElem( cellElems[2], 5, 'third multiple inserted' ); - equal( flkty.selectedIndex, 6, 'selectedIndex +6 after 3 insert before' ); + assert.equal( flkty.selectedIndex, 6, 'selectedIndex +6 after 3 insert before' ); function checkCellPositions() { var isGap = false; for ( var i=0, len = flkty.cells.length; i < len; i++ ) { var cell = flkty.cells[i]; if ( !isPositionApprox( cell.element.style.left, i * 25 ) ) { - ok( false, 'gap in cell position ' + i + ' after removal' ); + assert.ok( false, 'gap in cell position ' + i + ' after removal' ); isGap = true; } } - ok( !isGap, 'no gaps in cell positions' ); + assert.ok( !isGap, 'no gaps in cell positions' ); } // remove single cell element that was inserted var len = flkty.cells.length; flkty.remove( cellElem ); - equal( len - sliderElem.children.length, 1, 'element removed from DOM' ); - equal( len - flkty.cells.length, 1, 'cell removed' ); - equal( flkty.selectedIndex, 5, 'selectedIndex -1 after remove before' ); + assert.equal( len - sliderElem.children.length, 1, 'element removed from DOM' ); + assert.equal( len - flkty.cells.length, 1, 'cell removed' ); + assert.equal( flkty.selectedIndex, 5, 'selectedIndex -1 after remove before' ); checkCellPositions(); // remove multiple len = flkty.cells.length; flkty.select( 4 ); flkty.remove([ cellElems[2], cellElems[0], cellElems[1] ]); - equal( len - sliderElem.children.length, 3, 'elements removed from DOM' ); - equal( len - flkty.cells.length, 3, 'cells removed' ); - equal( flkty.selectedIndex, 2, 'selectedIndex -2 after 2 removed before' ); + assert.equal( len - sliderElem.children.length, 3, 'elements removed from DOM' ); + assert.equal( len - flkty.cells.length, 3, 'cells removed' ); + assert.equal( flkty.selectedIndex, 2, 'selectedIndex -2 after 2 removed before' ); checkCellPositions(); // remove all cells flkty.remove( flkty.getCellElements() ); - equal( flkty.cells.length, 0, 'all cells removed' ); + assert.equal( flkty.cells.length, 0, 'all cells removed' ); flkty.resize(); - ok( true, 'resize with zero items didnt freak out' ); - + assert.ok( true, 'resize with zero items didnt freak out' ); }); diff --git a/test/unit/auto-play.js b/test/unit/auto-play.js index 9d6431d..ad1803a 100644 --- a/test/unit/auto-play.js +++ b/test/unit/auto-play.js @@ -1,5 +1,4 @@ -test( 'auto play', function( assert ) { - +QUnit.test( 'auto play', function( assert ) { 'use strict'; var done = assert.async(); @@ -9,9 +8,10 @@ test( 'auto play', function( assert ) { }); var selectCount = 0; + var testDelay = flkty.options.autoPlay + 100; var tests; - + function nextTest() { if ( tests.length ) { var next = tests.shift(); @@ -21,39 +21,52 @@ test( 'auto play', function( assert ) { done(); } } - + tests = [ // check that player runs function() { var onSelect = function() { selectCount++; if ( selectCount < 5 ) { - equal( flkty.selectedIndex, selectCount % flkty.cells.length, + assert.equal( flkty.selectedIndex, selectCount % flkty.cells.length, 'auto-played to ' + flkty.selectedIndex ); } else if ( selectCount == 5 ) { // HACK do async, should be able to stop after a tick - flkty.off( 'cellSelect', onSelect ); + flkty.off( 'select', onSelect ); nextTest(); } }; - flkty.on( 'cellSelect', onSelect ); + flkty.on( 'select', onSelect ); }, // pause & unpause function() { function onPauseSelect() { - ok( false, 'player ticked during pause' ); + assert.ok( false, 'player ticked during pause' ); } - flkty.on( 'cellSelect', onPauseSelect ); + flkty.on( 'select', onPauseSelect ); flkty.pausePlayer(); setTimeout( function() { - ok( true, 'player did not tick during pause' ); - flkty.off( 'cellSelect', onPauseSelect ); - flkty.once( 'cellSelect', function() { - ok( true, 'player resumed after unpausing' ); + assert.ok( true, 'player did not tick during pause' ); + flkty.off( 'select', onPauseSelect ); + flkty.once( 'select', function() { + assert.ok( true, 'player resumed after unpausing' ); nextTest(); }); flkty.unpausePlayer(); - }, flkty.options.autoPlay + 100 ); + }, testDelay ); + }, + // stopPlayer + function() { + var ticks = 0; + function onSelect() { + ticks++; + } + flkty.stopPlayer(); + setTimeout( function() { + flkty.off( 'select', onSelect ); + assert.equal( ticks, 0, 'no ticks after stopped' ); + nextTest(); + }, testDelay * 2 ); }, // double playPlayer() function() { @@ -62,15 +75,15 @@ test( 'auto play', function( assert ) { ticks++; } flkty.stopPlayer(); - flkty.on( 'cellSelect', onSelect ); + flkty.on( 'select', onSelect ); flkty.playPlayer(); flkty.playPlayer(); setTimeout( function() { - flkty.off( 'cellSelect', onSelect ); - equal( ticks, 1, 'only one tick after double playPlayer' ); + flkty.off( 'select', onSelect ); + assert.equal( ticks, 1, 'only one tick after double playPlayer' ); nextTest(); - }, flkty.options.autoPlay + 100 ); - } + }, testDelay ); + }, ]; nextTest(); diff --git a/test/unit/cell-selector.js b/test/unit/cell-selector.js index a6945e1..80c1282 100644 --- a/test/unit/cell-selector.js +++ b/test/unit/cell-selector.js @@ -1,4 +1,4 @@ -test( 'cellSelector', function() { +QUnit.test( 'cellSelector', function( assert ) { 'use strict'; var elem = document.querySelector('#cell-selector'); @@ -19,14 +19,14 @@ test( 'cellSelector', function() { // getCellElements() var cellElems = flkty.getCellElements(); var queriedCellElems = elem.querySelectorAll( flkty.options.cellSelector ); - equal( cellElems.length, flkty.cells.length, 'getCellElements returns corrent number of elements' ); + assert.equal( cellElems.length, flkty.cells.length, 'getCellElements returns corrent number of elements' ); for( i=0, len = cellElems.length; i < len; i++ ) { - equal( cellElems[i], queriedCellElems[i], 'cell element same as queried cell element' ); + assert.equal( cellElems[i], queriedCellElems[i], 'cell element same as queried cell element' ); } - ok( cellsMatchSelector, 'all cell elements match cellSelector' ); + assert.ok( cellsMatchSelector, 'all cell elements match cellSelector' ); - equal( notCell1.parentNode, elem, 'notCell1 parent node is still gallery' ); - equal( notCell2.parentNode, elem, 'notCell2 parent node is still gallery' ); + assert.equal( notCell1.parentNode, elem, 'notCell1 parent node is still gallery' ); + assert.equal( notCell2.parentNode, elem, 'notCell2 parent node is still gallery' ); }); diff --git a/test/unit/contain.js b/test/unit/contain.js index 4cffb3d..1c26650 100644 --- a/test/unit/contain.js +++ b/test/unit/contain.js @@ -1,4 +1,4 @@ -test( 'contain', function() { +QUnit.test( 'contain', function( assert ) { 'use strict'; @@ -6,16 +6,16 @@ test( 'contain', function() { contain: true }); - equal( Math.round( flkty.x + flkty.cursorPosition ), 0, 'selected at 0, position left edge' ); + assert.equal( Math.round( flkty.x + flkty.cursorPosition ), 0, 'selected at 0, position left edge' ); flkty.select( 1 ); flkty.positionSliderAtSelected(); - equal( Math.round( flkty.x + flkty.cursorPosition ), 0, 'selected at 1, position left edge' ); + assert.equal( Math.round( flkty.x + flkty.cursorPosition ), 0, 'selected at 1, position left edge' ); flkty.select( 4 ); flkty.positionSliderAtSelected(); var endLimit = flkty.slideableWidth - flkty.size.innerWidth * ( 1 - flkty.cellAlign ); - equal( Math.round( -endLimit ), Math.round( flkty.x ), 'selected at 4, position right edge' ); + assert.equal( Math.round( -endLimit ), Math.round( flkty.x ), 'selected at 4, position right edge' ); flkty.select( 5 ); flkty.positionSliderAtSelected(); - equal( Math.round( -endLimit ), Math.round( flkty.x ), 'selected at 5, position right edge' ); + assert.equal( Math.round( -endLimit ), Math.round( flkty.x ), 'selected at 5, position right edge' ); }); diff --git a/test/unit/destroy.js b/test/unit/destroy.js index de65d31..df94b7a 100644 --- a/test/unit/destroy.js +++ b/test/unit/destroy.js @@ -1,4 +1,4 @@ -test( 'destroy', function( assert ) { +QUnit.test( 'destroy', function( assert ) { 'use strict'; @@ -9,15 +9,15 @@ test( 'destroy', function( assert ) { // do it async setTimeout( function() { flkty.destroy(); - strictEqual( elem.flickityGUID, undefined, 'flickityGUID removed' ); - ok( !flkty.isActive, 'not active' ); - ok( !Flickity.data( elem ), '.data() returns falsey' ); - ok( elem.children[0], '.cell', 'cell is back as first child' ); - ok( !matchesSelector( elem, '.flickity-enabled'), 'flickity-enabled class removed' ); - ok( !elem.querySelector('.flickity-prev-next-button'), 'no buttons' ); - ok( !elem.querySelector('.flickity-page-dots'), 'no page dots' ); - ok( !elem.style.height, 'no height set' ); - ok( !elem.children[0].style.left, 'first cell has no left position' ); + assert.strictEqual( elem.flickityGUID, undefined, 'flickityGUID removed' ); + assert.ok( !flkty.isActive, 'not active' ); + assert.ok( !Flickity.data( elem ), '.data() returns falsey' ); + assert.ok( elem.children[0], '.cell', 'cell is back as first child' ); + assert.ok( !matchesSelector( elem, '.flickity-enabled'), 'flickity-enabled class removed' ); + assert.ok( !elem.querySelector('.flickity-prev-next-button'), 'no buttons' ); + assert.ok( !elem.querySelector('.flickity-page-dots'), 'no page dots' ); + assert.ok( !elem.style.height, 'no height set' ); + assert.ok( !elem.children[0].style.left, 'first cell has no left position' ); done(); }, 20 ); diff --git a/test/unit/drag.js b/test/unit/drag.js index 1bcf846..8859215 100644 --- a/test/unit/drag.js +++ b/test/unit/drag.js @@ -62,19 +62,19 @@ function getDoNextDragTest( done ) { function getFakeDragTest( args ) { var assert = args.assert; var flkty = args.flickity; - var msgCell = 'cell[' + args.index + ']'; + var msgCell = 'slide[' + args.index + ']'; return function fakeDragTest() { var selectMsg = ( args.message ? args.message + '. ' : '' ) + 'selected ' + msgCell; - flkty.once( 'cellSelect', function() { + flkty.once( 'select', function() { assert.equal( flkty.selectedIndex, args.index, selectMsg ); }); var settleMsg = ( args.message ? args.message + '. ' : '' ) + 'settled ' + msgCell; - var target = flkty.cells[ args.index ].target; + var target = flkty.slides[ args.index ].target; flkty.once( 'settle', function() { assert.equal( Math.round( -flkty.x ), Math.round( target ), settleMsg ); - args.callback(); + setTimeout( args.callback ); }); fakeDrag( args.flickity, args.dragPositions ); @@ -83,7 +83,7 @@ function getFakeDragTest( args ) { -test( 'drag', function( assert ) { +QUnit.test( 'drag', function( assert ) { // async test var done = assert.async(); @@ -119,17 +119,17 @@ test( 'drag', function( assert ) { // minimal movement to trigger static click function() { flkty.once( 'staticClick', function() { - ok( true, 'staticClick fired on non-drag'); - equal( flkty.selectedIndex, 2, 'selected index still at 2 after click' ); - doNextDragTest(); + assert.ok( true, 'staticClick fired on non-drag'); + assert.equal( flkty.selectedIndex, 2, 'selected index still at 2 after click' ); + setTimeout( doNextDragTest ); }); fakeDrag( flkty, [ 0, 1, 0, -2, -1 ] ); }, // move out then back to where it started function() { flkty.once( 'settle', function() { - equal( flkty.selectedIndex, 2, 'move out then back. same cell' ); - doNextDragTest(); + assert.equal( flkty.selectedIndex, 2, 'move out then back. same cell' ); + setTimeout( doNextDragTest ); }); fakeDrag( flkty, [ 0, 10, 20, 30, 20 ] ); }, @@ -144,7 +144,7 @@ test( 'drag', function( assert ) { }); -test( 'drag with wrapAround', function( assert ) { +QUnit.test( 'drag with wrapAround', function( assert ) { // async test var done = assert.async(); diff --git a/test/unit/empty.js b/test/unit/empty.js index c8f865f..b12fa0c 100644 --- a/test/unit/empty.js +++ b/test/unit/empty.js @@ -1,17 +1,17 @@ -test('empty', function() { +QUnit.test( 'empty', function( assert ) { 'use strict'; var gallery = document.querySelector('#empty'); var flkty = new Flickity( gallery ); - ok( true, 'empty gallery ok' ); - ok( flkty.prevButton.element.disabled, 'previous button disabled' ); - ok( flkty.nextButton.element.disabled, 'next button disabled' ); - equal( flkty.pageDots.dots.length, 0, '0 page dots'); + assert.ok( true, 'empty gallery ok' ); + assert.ok( flkty.prevButton.element.disabled, 'previous button disabled' ); + assert.ok( flkty.nextButton.element.disabled, 'next button disabled' ); + assert.equal( flkty.pageDots.dots.length, 0, '0 page dots'); flkty.resize(); - ok( true, 'resize with empty gallery ok'); + assert.ok( true, 'resize with empty gallery ok'); function makeCellElem() { var cellElem = document.createElement('div'); @@ -20,12 +20,12 @@ test('empty', function() { } flkty.append( makeCellElem() ); - equal( flkty.cells.length, 1, 'added cell to empty gallery' ); + assert.equal( flkty.cells.length, 1, 'added cell to empty gallery' ); - ok( flkty.prevButton.element.disabled, 'previous button disabled' ); - ok( flkty.nextButton.element.disabled, 'next button disabled' ); - equal( flkty.pageDots.dots.length, 1, '1 page dots'); + assert.ok( flkty.prevButton.element.disabled, 'previous button disabled' ); + assert.ok( flkty.nextButton.element.disabled, 'next button disabled' ); + assert.equal( flkty.pageDots.dots.length, 1, '1 page dots'); // destroy and re-init with higher initialIndex flkty.destroy(); @@ -34,6 +34,6 @@ test('empty', function() { }); // #291 - ok( true, 'initializing with initialIndex > cells doesnt throw error' ); + assert.ok( true, 'initializing with initialIndex > cells doesnt throw error' ); }); diff --git a/test/unit/get-parent-cell.js b/test/unit/get-parent-cell.js index 349ada4..ef8d3fc 100644 --- a/test/unit/get-parent-cell.js +++ b/test/unit/get-parent-cell.js @@ -1,39 +1,37 @@ -test( 'getParentCell', function() { +QUnit.test( 'getParentCell', function( assert ) { 'use strict'; - var utils = window.fizzyUIUtils; - var gallery = document.querySelector('#get-parent-cell'); var flkty = new Flickity( gallery ); // cell1 var cell = flkty.getParentCell( gallery.querySelector('.cell1') ); - ok( cell, 'getParentCell( cell ) ok' ); - ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); - var index = utils.indexOf( flkty.cells, cell ); - equal( index, 0, 'cell is index 0' ); + assert.ok( cell, 'getParentCell( cell ) ok' ); + assert.ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); + var index = flkty.cells.indexOf( cell ); + assert.equal( index, 0, 'cell is index 0' ); // cell3 cell = flkty.getParentCell( gallery.querySelector('.cell3') ); - ok( cell, 'getParentCell( cell ) ok' ); - ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); - index = utils.indexOf( flkty.cells, cell ); - equal( index, 2, 'cell is index 2' ); + assert.ok( cell, 'getParentCell( cell ) ok' ); + assert.ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); + index = flkty.cells.indexOf( cell ); + assert.equal( index, 2, 'cell is index 2' ); // child1 cell = flkty.getParentCell( gallery.querySelector('.child1') ); - ok( cell, 'getParentCell( cell ) ok' ); - ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); - index = utils.indexOf( flkty.cells, cell ); - equal( index, 0, 'cell is index 0' ); + assert.ok( cell, 'getParentCell( cell ) ok' ); + assert.ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); + index = flkty.cells.indexOf( cell ); + assert.equal( index, 0, 'cell is index 0' ); // child2 cell = flkty.getParentCell( gallery.querySelector('.child2') ); - ok( cell, 'getParentCell( cell ) ok' ); - ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); - index = utils.indexOf( flkty.cells, cell ); - equal( index, 1, 'cell is index 1' ); + assert.ok( cell, 'getParentCell( cell ) ok' ); + assert.ok( cell instanceof Flickity.Cell, 'cell is Flickity.Cell' ); + index = flkty.cells.indexOf( cell ); + assert.equal( index, 1, 'cell is index 1' ); // outside cell = flkty.getParentCell( document.querySelector('.outside') ); - ok( !cell, 'getParentCell( notCell ) not ok' ); - index = utils.indexOf( flkty.cells, cell ); - equal( index, -1, 'not cell is index -1' ); + assert.ok( !cell, 'getParentCell( notCell ) not ok' ); + index = flkty.cells.indexOf( cell ); + assert.equal( index, -1, 'not cell is index -1' ); }); diff --git a/test/unit/get-wrap-cells.js b/test/unit/get-wrap-cells.js index 39ddf54..adda707 100644 --- a/test/unit/get-wrap-cells.js +++ b/test/unit/get-wrap-cells.js @@ -1,26 +1,24 @@ -test( 'getWrapCells', function() { - +QUnit.test( 'getWrapCells', function( assert ) { 'use strict'; - var flkty = new Flickity( '#get-wrap-cells', { wrapAround: true }); // cells are 25% width // center align, 2 cells on each side - equal( flkty.beforeShiftCells.length, 2, 'center align, 2 before shift cells' ); - equal( flkty.afterShiftCells.length, 2, 'center align, 2 after shift cells' ); + assert.equal( flkty.beforeShiftCells.length, 2, 'center align, 2 before shift cells' ); + assert.equal( flkty.afterShiftCells.length, 2, 'center align, 2 after shift cells' ); flkty.options.cellAlign = 'left'; flkty.resize(); // left align, 0, 4 - equal( flkty.beforeShiftCells.length, 0, 'left align, 1 before shift cells' ); - equal( flkty.afterShiftCells.length, 4, 'left align, 4 after shift cells' ); + assert.equal( flkty.beforeShiftCells.length, 0, 'left align, 1 before shift cells' ); + assert.equal( flkty.afterShiftCells.length, 4, 'left align, 4 after shift cells' ); flkty.options.cellAlign = 'right'; flkty.resize(); // right align, 4, 0 - equal( flkty.beforeShiftCells.length, 4, 'right align, 4 before shift cells' ); - equal( flkty.afterShiftCells.length, 0, 'right align, 0 after shift cells' ); + assert.equal( flkty.beforeShiftCells.length, 4, 'right align, 4 before shift cells' ); + assert.equal( flkty.afterShiftCells.length, 0, 'right align, 0 after shift cells' ); }); diff --git a/test/unit/group-cells.js b/test/unit/group-cells.js new file mode 100644 index 0000000..84dbb0e --- /dev/null +++ b/test/unit/group-cells.js @@ -0,0 +1,39 @@ +QUnit.test( 'groupCells', function( assert ) { + 'use strict'; + + var flkty = new Flickity( '#group-cells', { + groupCells: true + }); + + function getSlideCellsCount() { + var counts = flkty.slides.map( function( slide ) { + return slide.cells.length; + }); + return counts.join(','); + } + + assert.equal( getSlideCellsCount(), '3,2,2,1,1,3,2', 'groupCells: true' ); + var targets = flkty.slides.map( function( slide ) { + return slide.target; + }); + assert.deepEqual( targets, [200, 600, 1000, 1300, 1600, 2000, 2300], 'targets' ); + + flkty.selectCell( 6 ); + assert.equal( flkty.selectedIndex, 2, 'selectCell(6) selects 3rd slide' ); + flkty.selectCell( flkty.cells[2].element ); + assert.equal( flkty.selectedIndex, 0, 'selectCell(3rd elem) selects 1st slide' ); + + flkty.options.groupCells = 2; + flkty.reposition(); + assert.equal( getSlideCellsCount(), '2,2,2,2,2,2,2', 'groupCells: 2' ); + + flkty.options.groupCells = '75%'; + flkty.reposition(); + assert.equal( getSlideCellsCount(), '2,1,1,2,1,1,1,2,2,1', 'groupCells: 75%' ); + + flkty.element.classList.add('is-expanded'); // 600px wide + flkty.options.groupCells = true; + flkty.resize(); + assert.equal( getSlideCellsCount(), '3,3,2,3,3', 'groupCells: true, container @ 600px' ); + +}); diff --git a/test/unit/init.js b/test/unit/init.js index eb8f0ff..34b84d1 100644 --- a/test/unit/init.js +++ b/test/unit/init.js @@ -2,35 +2,35 @@ 'use strict'; -module('Flickity'); +QUnit.module('Flickity'); var utils = window.fizzyUIUtils; -test( 'init', function() { +QUnit.test( 'init', function( assert ) { var elem = document.querySelector('#init'); var flkty = new Flickity( elem ); for ( var prop in Flickity.defaults ) { - equal( flkty.options[ prop ], Flickity.defaults[ prop ], prop + ' option matches default' ); + assert.equal( flkty.options[ prop ], Flickity.defaults[ prop ], prop + ' option matches default' ); } - equal( flkty.element, elem, '.element is proper element' ); + assert.equal( flkty.element, elem, '.element is proper element' ); var children = utils.makeArray( flkty.element.children ); - notEqual( utils.indexOf( children, flkty.viewport ), -1, 'viewport element is a child element' ); - equal( flkty.viewport.children[0], flkty.slider, 'slider is in viewport' ); - equal( flkty.viewport.style.height, '100px', 'viewport height set' ); + assert.notEqual( children.indexOf( flkty.viewport ), -1, 'viewport element is a child element' ); + assert.equal( flkty.viewport.children[0], flkty.slider, 'slider is in viewport' ); + assert.equal( flkty.viewport.style.height, '100px', 'viewport height set' ); - ok( flkty.isActive, 'isActive' ); - ok( matchesSelector( elem, '.flickity-enabled' ), 'flickity-enabled class added' ); + assert.ok( flkty.isActive, 'isActive' ); + assert.ok( matchesSelector( elem, '.flickity-enabled' ), 'flickity-enabled class added' ); - equal( flkty.cells.length, 6, 'has 6 cells' ); - equal( flkty.cells[0].element.style.left, '0%', 'first cell left: 0%' ); - equal( flkty.cells[5].element.style.left, '500%', '6th cell left: 500%' ); + assert.equal( flkty.cells.length, 6, 'has 6 cells' ); + assert.equal( flkty.cells[0].element.style.left, '0%', 'first cell left: 0%' ); + assert.equal( flkty.cells[5].element.style.left, '500%', '6th cell left: 500%' ); - equal( flkty.selectedIndex, 0, 'selectedIndex = 0' ); - equal( flkty.cursorPosition, 200, 'cursorPosition = 200' ); - equal( flkty.x + flkty.cursorPosition, 0, 'x + cursorPosition = 0' ); + assert.equal( flkty.selectedIndex, 0, 'selectedIndex = 0' ); + assert.equal( flkty.cursorPosition, 200, 'cursorPosition = 200' ); + assert.equal( flkty.x + flkty.cursorPosition, 0, 'x + cursorPosition = 0' ); }); diff --git a/test/unit/lazyload.js b/test/unit/lazyload.js index 058decb..7091928 100644 --- a/test/unit/lazyload.js +++ b/test/unit/lazyload.js @@ -1,4 +1,4 @@ -test( 'lazyload', function( assert ) { +QUnit.test( 'lazyload', function( assert ) { 'use strict'; var done = assert.async(); @@ -12,9 +12,9 @@ test( 'lazyload', function( assert ) { flkty.on( 'lazyLoad', function( event, cellElem ) { loadCount++; - equal( event.type, 'load', 'event.type == load' ); - ok( event.target.complete, 'img ' + loadCount + ' is complete' ); - ok( cellElem, 'cellElement argument there' ); + assert.equal( event.type, 'load', 'event.type == load' ); + assert.ok( event.target.complete, 'img ' + loadCount + ' is complete' ); + assert.ok( cellElem, 'cellElement argument there' ); // after first 2 have loaded, select 7th cell if ( loadCount == 2 ) { @@ -22,7 +22,7 @@ test( 'lazyload', function( assert ) { } if ( loadCount == 5 ) { var loadedImgs = gallery.querySelectorAll('.flickity-lazyloaded'); - equal( loadedImgs.length, '5', 'only 5 images loaded' ); + assert.equal( loadedImgs.length, '5', 'only 5 images loaded' ); done(); } }); diff --git a/test/unit/page-dots.js b/test/unit/page-dots.js index a92f8a3..53e6fae 100644 --- a/test/unit/page-dots.js +++ b/test/unit/page-dots.js @@ -1,5 +1,4 @@ -test( 'pageDots', function() { - +QUnit.test( 'pageDots', function( assert ) { 'use strict'; var elem = document.querySelector('#page-dots'); @@ -8,9 +7,9 @@ test( 'pageDots', function() { var dotsHolder = elem.querySelector('.flickity-page-dots'); var dotsElems = dotsHolder.querySelectorAll('.dot'); - ok( dotsHolder, 'dots holder in DOM' ); - equal( flkty.pageDots.holder, dotsHolder, 'dots holder element matches flkty.pageDots.holder' ); - equal( dotsElems.length, flkty.cells.length, 'number of dots matches number of cells' ); + assert.ok( dotsHolder, 'dots holder in DOM' ); + assert.equal( flkty.pageDots.holder, dotsHolder, 'dots holder element matches flkty.pageDots.holder' ); + assert.equal( dotsElems.length, flkty.cells.length, 'number of dots matches number of cells' ); function getSelectedDotIndex() { var selectedDot = dotsHolder.querySelector('.is-selected'); @@ -23,12 +22,12 @@ test( 'pageDots', function() { return -1; } - equal( getSelectedDotIndex(), 0, 'first dot is selected' ); + assert.equal( getSelectedDotIndex(), 0, 'first dot is selected' ); flkty.select( 2 ); - equal( getSelectedDotIndex(), 2, '3rd dot is selected' ); + assert.equal( getSelectedDotIndex(), 2, '3rd dot is selected' ); // fake tap flkty.pageDots.onTap( { target: dotsElems[4] } ); - equal( flkty.selectedIndex, 4, 'tap dot selects cell' ); + assert.equal( flkty.selectedIndex, 4, 'tap dot selects cell' ); }); diff --git a/test/unit/position-cells.js b/test/unit/position-cells.js index 348a30d..63aed0f 100644 --- a/test/unit/position-cells.js +++ b/test/unit/position-cells.js @@ -27,24 +27,24 @@ function checkCellPositions( flkty, expecteds ) { return isOK; } -test( 'position cells', function() { +QUnit.test( 'position cells', function( assert ) { var flkty = new Flickity('#position-cells'); - ok( checkCellPositions( flkty, [ 0, 40, 65, 125, 165, 225 ] ), 'percent cell position' ); + assert.ok( checkCellPositions( flkty, [ 0, 40, 65, 125, 165, 225 ] ), 'percent cell position' ); // .cell { margin: 0 2%; } - classie.add( flkty.element, 'percent-margin' ); + flkty.element.classList.add('percent-margin'); flkty.positionCells(); - ok( checkCellPositions( flkty, [ 0, 44, 73, 137, 181, 245 ] ), 'percent cell position with margin' ); - classie.remove( flkty.element, 'percent-margin' ); + assert.ok( checkCellPositions( flkty, [ 0, 44, 73, 137, 181, 245 ] ), 'percent cell position with margin' ); + flkty.element.classList.remove('percent-margin'); // pixel-based position flkty.options.percentPosition = false; flkty.positionCells(); - ok( checkCellPositions( flkty, [ 0, 160, 260, 500, 660, 900 ] ), 'pixel cell position' ); + assert.ok( checkCellPositions( flkty, [ 0, 160, 260, 500, 660, 900 ] ), 'pixel cell position' ); // pixel margin, { margin: 0 10px; } - classie.add( flkty.element, 'pixel-margin' ); + flkty.element.classList.add('pixel-margin'); flkty.positionCells(); - ok( checkCellPositions( flkty, [ 0, 180, 300, 560, 740, 1000 ] ), 'pixel cell position with margin' ); + assert.ok( checkCellPositions( flkty, [ 0, 180, 300, 560, 740, 1000 ] ), 'pixel cell position with margin' ); }); diff --git a/test/unit/prev-next-buttons.js b/test/unit/prev-next-buttons.js index 57991f2..261df2f 100644 --- a/test/unit/prev-next-buttons.js +++ b/test/unit/prev-next-buttons.js @@ -1,4 +1,4 @@ -test( 'prev-next-buttons', function() { +QUnit.test( 'prev-next-buttons', function( assert ) { 'use strict'; var elem = document.querySelector('#prev-next-buttons'); @@ -6,27 +6,22 @@ test( 'prev-next-buttons', function() { var prevElem = elem.querySelector('.flickity-prev-next-button.previous'); var nextElem = elem.querySelector('.flickity-prev-next-button.next'); - ok( prevElem, 'previous button in DOM' ); - ok( nextElem, 'next button in DOM' ); - equal( flkty.prevButton.element, prevElem, 'previous button element matches prevButton.element' ); - equal( flkty.nextButton.element, nextElem, 'next button element matches nextButton.element' ); - ok( prevElem.disabled, 'previous button is disabled at first index' ); + assert.ok( prevElem, 'previous button in DOM' ); + assert.ok( nextElem, 'next button in DOM' ); + assert.equal( flkty.prevButton.element, prevElem, 'previous button element matches prevButton.element' ); + assert.equal( flkty.nextButton.element, nextElem, 'next button element matches nextButton.element' ); + assert.ok( prevElem.disabled, 'previous button is disabled at first index' ); - var isIE8 = 'attachEvent' in window; - // cannot focus disabled button in IE8 - if ( isIE8 ) { - prevElem.disabled = false; - } prevElem.focus(); prevElem.click(); - equal( flkty.selectedIndex, 0, 'selectedIndex still at 0' ); + assert.equal( flkty.selectedIndex, 0, 'selectedIndex still at 0' ); nextElem.focus(); nextElem.click(); - equal( flkty.selectedIndex, 1, 'next button clicked, selectedIndex at 1' ); + assert.equal( flkty.selectedIndex, 1, 'next button clicked, selectedIndex at 1' ); prevElem.focus(); prevElem.click(); - equal( flkty.selectedIndex, 0, 'previous button clicked, selectedIndex back at 0' ); + assert.equal( flkty.selectedIndex, 0, 'previous button clicked, selectedIndex back at 0' ); flkty.select( 5 ); - ok( nextElem.disabled, 'next button disabled when at last cell' ); + assert.ok( nextElem.disabled, 'next button disabled when at last cell' ); }); diff --git a/test/unit/resize.js b/test/unit/resize.js index b99e4d8..2f4dd7a 100644 --- a/test/unit/resize.js +++ b/test/unit/resize.js @@ -1,4 +1,4 @@ -test( 'resize', function() { +QUnit.test( 'resize', function( assert ) { 'use strict'; @@ -9,8 +9,8 @@ test( 'resize', function() { elem.style.width = '500px'; flkty.resize(); - equal( flkty.selectedIndex, 2, 'selectedIndex = 2' ); - equal( flkty.cursorPosition, 250, 'cursorPosition = 250' ); - equal( flkty.x + flkty.cursorPosition, -1000, 'x + cursorPosition = -1000' ); + assert.equal( flkty.selectedIndex, 2, 'selectedIndex = 2' ); + assert.equal( flkty.cursorPosition, 250, 'cursorPosition = 250' ); + assert.equal( flkty.x + flkty.cursorPosition, -1000, 'x + cursorPosition = -1000' ); }); diff --git a/test/unit/select-cell.js b/test/unit/select-cell.js new file mode 100644 index 0000000..28ae4b5 --- /dev/null +++ b/test/unit/select-cell.js @@ -0,0 +1,18 @@ +QUnit.test( 'selectCell', function( assert ) { + 'use strict'; + + var gallery = document.querySelector('#select-cell'); + var cellElems = gallery.querySelectorAll('.cell'); + var flkty = new Flickity( gallery, { + groupCells: true, // groups of 3 + }); + + flkty.selectCell( 3 ); + assert.equal( flkty.selectedIndex, 1, 'selectCell number' ); + flkty.selectCell( cellElems[1] ); + assert.equal( flkty.selectedIndex, 0, 'selectCell element' ); + flkty.selectCell('.select-cell__6'); + assert.equal( flkty.selectedIndex, 2, 'selectCell selector string' ); + flkty.selectCell('none'); + assert.equal( flkty.selectedIndex, 2, 'selectCell bad string is okay' ); +}); diff --git a/test/unit/watch.js b/test/unit/watch.js index 3283d8c..14cd8fd 100644 --- a/test/unit/watch.js +++ b/test/unit/watch.js @@ -1,38 +1,10 @@ -docReady( function() { - +QUnit.test( 'watch fallback', function( assert ) { 'use strict'; - if ( Flickity.supportsConditionalCSS() ) { - - test( 'watch', function() { - - var elem = document.querySelector('#watch'); - var flkty = new Flickity( elem, { - watchCSS: true - }); - - ok( !flkty.isActive, 'not active without :after' ); - // add :after via CSS class - classie.add( elem, 'has-after' ); - flkty.watchCSS(); - ok( flkty.isActive, 'active with :after' ); - }); - - } else { - - test( 'watch fallback', function() { - - var elem = document.querySelector('#watch'); - var flkty = new Flickity( elem, { - watchCSS: true - }); - - ok( !flkty.isActive, 'fallback not active, watchCSS: true' ); - flkty.options.watchCSS = 'fallbackOn'; - flkty.watchCSS(); - ok( flkty.isActive, 'active with watchCSS: "fallbackOn" '); - }); - - } + var elem = document.querySelector('#watch'); + var flkty = new Flickity( elem, { + watchCSS: true + }); + assert.ok( !flkty.isActive, 'fallback not active, watchCSS: true' ); }); |