react-image-gallery
Advanced tools
Comparing version 0.6.10 to 0.7.0
@@ -77,2 +77,4 @@ 'use strict'; | ||
var screenChangeEvents = ['fullscreenchange', 'msfullscreenchange', 'mozfullscreenchange', 'webkitfullscreenchange']; | ||
var ImageGallery = function (_React$Component) { | ||
@@ -91,3 +93,5 @@ _inherits(ImageGallery, _React$Component); | ||
galleryWidth: 0, | ||
thumbnailWidth: 0 | ||
thumbnailWidth: 0, | ||
isFullscreen: false, | ||
isPlaying: false | ||
}; | ||
@@ -128,2 +132,3 @@ return _this; | ||
value: function componentWillMount() { | ||
this._slideLeft = debounceEventHandler(this._slideLeft.bind(this), MIN_INTERVAL, true); | ||
@@ -134,2 +139,3 @@ | ||
this._handleResize = this._handleResize.bind(this); | ||
this._handleScreenChange = this._handleScreenChange.bind(this); | ||
this._handleKeyDown = this._handleKeyDown.bind(this); | ||
@@ -155,2 +161,3 @@ this._thumbnailDelay = 300; | ||
window.addEventListener('resize', this._handleResize); | ||
this._onScreenChangeEvent(); | ||
} | ||
@@ -164,2 +171,4 @@ }, { | ||
window.removeEventListener('resize', this._handleResize); | ||
this._offScreenChangeEvent(); | ||
if (this._intervalId) { | ||
@@ -177,19 +186,19 @@ window.clearInterval(this._intervalId); | ||
if (this._intervalId) { | ||
return; | ||
} | ||
var slideInterval = this.props.slideInterval; | ||
if (!this._intervalId) { | ||
this.setState({ isPlaying: true }); | ||
var slideInterval = this.props.slideInterval; | ||
this._intervalId = window.setInterval(function () { | ||
if (!_this3.state.hovering) { | ||
if (!_this3.props.infinite && !_this3._canSlideRight()) { | ||
_this3.pause(); | ||
} else { | ||
_this3.slideToIndex(_this3.state.currentIndex + 1); | ||
this._intervalId = window.setInterval(function () { | ||
if (!_this3.state.hovering) { | ||
if (!_this3.props.infinite && !_this3._canSlideRight()) { | ||
_this3.pause(); | ||
} else { | ||
_this3.slideToIndex(_this3.state.currentIndex + 1); | ||
} | ||
} | ||
}, slideInterval > MIN_INTERVAL ? slideInterval : MIN_INTERVAL); | ||
if (this.props.onPlay && callback) { | ||
this.props.onPlay(this.state.currentIndex); | ||
} | ||
}, slideInterval > MIN_INTERVAL ? slideInterval : MIN_INTERVAL); | ||
if (this.props.onPlay && callback) { | ||
this.props.onPlay(this.state.currentIndex); | ||
} | ||
@@ -205,6 +214,7 @@ } | ||
this._intervalId = null; | ||
} | ||
this.setState({ isPlaying: false }); | ||
if (this.props.onPause && callback) { | ||
this.props.onPause(this.state.currentIndex); | ||
if (this.props.onPause && callback) { | ||
this.props.onPause(this.state.currentIndex); | ||
} | ||
} | ||
@@ -225,5 +235,30 @@ } | ||
gallery.webkitRequestFullscreen(); | ||
} else { | ||
// fallback to modal for unsupported browsers | ||
this.setState({ modalFullscreen: true }); | ||
} | ||
this.setState({ isFullscreen: true }); | ||
} | ||
}, { | ||
key: 'exitFullScreen', | ||
value: function exitFullScreen() { | ||
if (this.state.isFullscreen) { | ||
if (document.exitFullscreen) { | ||
document.exitFullscreen(); | ||
} else if (document.webkitExitFullscreen) { | ||
document.webkitExitFullscreen(); | ||
} else if (document.mozCancelFullScreen) { | ||
document.mozCancelFullScreen(); | ||
} else if (document.msExitFullscreen) { | ||
document.msExitFullscreen(); | ||
} else { | ||
// fallback to modal for unsupported browsers | ||
this.setState({ modalFullscreen: false }); | ||
} | ||
this.setState({ isFullscreen: false }); | ||
} | ||
} | ||
}, { | ||
key: 'slideToIndex', | ||
@@ -264,2 +299,38 @@ value: function slideToIndex(index, event) { | ||
}, { | ||
key: '_onScreenChangeEvent', | ||
value: function _onScreenChangeEvent() { | ||
var _this4 = this; | ||
screenChangeEvents.map(function (eventName) { | ||
document.addEventListener(eventName, _this4._handleScreenChange); | ||
}); | ||
} | ||
}, { | ||
key: '_offScreenChangeEvent', | ||
value: function _offScreenChangeEvent() { | ||
var _this5 = this; | ||
screenChangeEvents.map(function (eventName) { | ||
document.removeEventListener(eventName, _this5._handleScreenChange); | ||
}); | ||
} | ||
}, { | ||
key: '_togglePlay', | ||
value: function _togglePlay() { | ||
if (this._intervalId) { | ||
this.pause(); | ||
} else { | ||
this.play(); | ||
} | ||
} | ||
}, { | ||
key: '_toggleFullScreen', | ||
value: function _toggleFullScreen() { | ||
if (this.state.isFullscreen) { | ||
this.exitFullScreen(); | ||
} else { | ||
this.fullScreen(); | ||
} | ||
} | ||
}, { | ||
key: '_handleResize', | ||
@@ -276,2 +347,9 @@ value: function _handleResize() { | ||
}, { | ||
key: '_handleScreenChange', | ||
value: function _handleScreenChange() { | ||
var fullScreenElement = document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; | ||
this.setState({ isFullscreen: !!fullScreenElement }); | ||
} | ||
}, { | ||
key: '_handleKeyDown', | ||
@@ -299,3 +377,3 @@ value: function _handleKeyDown(event) { | ||
value: function _handleMouseOverThumbnails(index) { | ||
var _this4 = this; | ||
var _this6 = this; | ||
@@ -309,3 +387,3 @@ if (this.props.slideOnThumbnailHover) { | ||
this._thumbnailTimer = window.setTimeout(function () { | ||
_this4.slideToIndex(index); | ||
_this6.slideToIndex(index); | ||
}, this._thumbnailDelay); | ||
@@ -327,12 +405,2 @@ } | ||
}, { | ||
key: '_handleMouseOver', | ||
value: function _handleMouseOver() { | ||
this.setState({ hovering: true }); | ||
} | ||
}, { | ||
key: '_handleMouseLeave', | ||
value: function _handleMouseLeave() { | ||
this.setState({ hovering: false }); | ||
} | ||
}, { | ||
key: '_handleImageError', | ||
@@ -626,6 +694,11 @@ value: function _handleImageError(event) { | ||
value: function render() { | ||
var _this5 = this; | ||
var _this7 = this; | ||
var currentIndex = this.state.currentIndex; | ||
var _state3 = this.state; | ||
var currentIndex = _state3.currentIndex; | ||
var isFullscreen = _state3.isFullscreen; | ||
var modalFullscreen = _state3.modalFullscreen; | ||
var isPlaying = _state3.isPlaying; | ||
var thumbnailStyle = this._getThumbnailStyle(); | ||
@@ -641,7 +714,7 @@ | ||
this.props.items.map(function (item, index) { | ||
var alignment = _this5._getAlignmentClassName(index); | ||
var alignment = _this7._getAlignmentClassName(index); | ||
var originalClass = item.originalClass ? ' ' + item.originalClass : ''; | ||
var thumbnailClass = item.thumbnailClass ? ' ' + item.thumbnailClass : ''; | ||
var renderItem = item.renderItem || _this5.props.renderItem || _this5._renderItem.bind(_this5); | ||
var renderItem = item.renderItem || _this7.props.renderItem || _this7._renderItem.bind(_this7); | ||
@@ -653,4 +726,4 @@ var slide = _react2.default.createElement( | ||
className: 'image-gallery-slide' + alignment + originalClass, | ||
style: _extends(_this5._getSlideStyle(index), _this5.state.style), | ||
onClick: _this5.props.onClick | ||
style: _extends(_this7._getSlideStyle(index), _this7.state.style), | ||
onClick: _this7.props.onClick | ||
}, | ||
@@ -660,3 +733,3 @@ renderItem(item) | ||
if (_this5.props.lazyLoad) { | ||
if (_this7.props.lazyLoad) { | ||
if (alignment) { | ||
@@ -669,13 +742,13 @@ slides.push(slide); | ||
var onThumbnailError = _this5._handleImageError; | ||
if (_this5.props.onThumbnailError) { | ||
onThumbnailError = _this5.props.onThumbnailError; | ||
var onThumbnailError = _this7._handleImageError; | ||
if (_this7.props.onThumbnailError) { | ||
onThumbnailError = _this7.props.onThumbnailError; | ||
} | ||
if (_this5.props.showThumbnails) { | ||
if (_this7.props.showThumbnails) { | ||
thumbnails.push(_react2.default.createElement( | ||
'a', | ||
{ | ||
onMouseOver: _this5._handleMouseOverThumbnails.bind(_this5, index), | ||
onMouseLeave: _this5._handleMouseLeaveThumbnails.bind(_this5, index), | ||
onMouseOver: _this7._handleMouseOverThumbnails.bind(_this7, index), | ||
onMouseLeave: _this7._handleMouseLeaveThumbnails.bind(_this7, index), | ||
key: index, | ||
@@ -685,6 +758,6 @@ className: 'image-gallery-thumbnail' + (currentIndex === index ? ' active' : '') + thumbnailClass, | ||
onTouchStart: function onTouchStart(event) { | ||
return _this5.slideToIndex.call(_this5, index, event); | ||
return _this7.slideToIndex.call(_this7, index, event); | ||
}, | ||
onClick: function onClick(event) { | ||
return _this5.slideToIndex.call(_this5, index, event); | ||
return _this7.slideToIndex.call(_this7, index, event); | ||
} }, | ||
@@ -694,3 +767,3 @@ _react2.default.createElement('img', { | ||
alt: item.thumbnailAlt, | ||
onError: onThumbnailError.bind(_this5) }), | ||
onError: onThumbnailError.bind(_this7) }), | ||
_react2.default.createElement( | ||
@@ -704,3 +777,3 @@ 'div', | ||
if (_this5.props.showBullets) { | ||
if (_this7.props.showBullets) { | ||
bullets.push(_react2.default.createElement('li', { | ||
@@ -711,6 +784,6 @@ key: index, | ||
onTouchStart: function onTouchStart(event) { | ||
return _this5.slideToIndex.call(_this5, index, event); | ||
return _this7.slideToIndex.call(_this7, index, event); | ||
}, | ||
onClick: function onClick(event) { | ||
return _this5.slideToIndex.call(_this5, index, event); | ||
return _this7.slideToIndex.call(_this7, index, event); | ||
} })); | ||
@@ -722,91 +795,106 @@ } | ||
'section', | ||
{ ref: function ref(i) { | ||
return _this5._imageGallery = i; | ||
}, className: 'image-gallery' }, | ||
{ | ||
ref: function ref(i) { | ||
return _this7._imageGallery = i; | ||
}, | ||
className: 'image-gallery' + (modalFullscreen ? ' fullscreen-modal' : '') }, | ||
_react2.default.createElement( | ||
'div', | ||
{ | ||
onMouseOver: this._handleMouseOver.bind(this), | ||
onMouseLeave: this._handleMouseLeave.bind(this), | ||
className: 'image-gallery-content' }, | ||
this._canNavigate() ? [this.props.showNav && _react2.default.createElement( | ||
'span', | ||
{ key: 'navigation' }, | ||
this._canSlideLeft() && _react2.default.createElement('a', { | ||
className: 'image-gallery-left-nav', | ||
onTouchStart: slideLeft, | ||
onClick: slideLeft }), | ||
this._canSlideRight() && _react2.default.createElement('a', { | ||
className: 'image-gallery-right-nav', | ||
onTouchStart: slideRight, | ||
onClick: slideRight }) | ||
), _react2.default.createElement( | ||
_reactSwipeable2.default, | ||
{ className: 'image-gallery-content' }, | ||
_react2.default.createElement( | ||
'div', | ||
{ | ||
className: 'image-gallery-swipe', | ||
key: 'swipeable', | ||
delta: 1, | ||
onSwipingLeft: this._handleSwiping.bind(this, -1), | ||
onSwipingRight: this._handleSwiping.bind(this, 1), | ||
onSwiped: this._handleOnSwiped.bind(this), | ||
onSwipedLeft: this._handleOnSwipedTo.bind(this, 1), | ||
onSwipedRight: this._handleOnSwipedTo.bind(this, -1) | ||
}, | ||
_react2.default.createElement( | ||
className: 'image-gallery-slide-wrapper' }, | ||
this.props.showFullscreenButton && _react2.default.createElement('a', { | ||
className: 'image-gallery-fullscreen-button' + (isFullscreen ? ' active' : ''), | ||
onClick: this._toggleFullScreen.bind(this) }), | ||
this.props.showPlayButton && _react2.default.createElement('a', { | ||
ref: function ref(p) { | ||
return _this7._playButton = p; | ||
}, | ||
className: 'image-gallery-play-button' + (isPlaying ? ' active' : ''), | ||
onClick: this._togglePlay.bind(this) }), | ||
this._canNavigate() ? [this.props.showNav && _react2.default.createElement( | ||
'span', | ||
{ key: 'navigation' }, | ||
_react2.default.createElement('a', { | ||
className: 'image-gallery-left-nav', | ||
disabled: !this._canSlideLeft(), | ||
onTouchStart: slideLeft, | ||
onClick: slideLeft }), | ||
_react2.default.createElement('a', { | ||
className: 'image-gallery-right-nav', | ||
disabled: !this._canSlideRight(), | ||
onTouchStart: slideRight, | ||
onClick: slideRight }) | ||
), _react2.default.createElement( | ||
_reactSwipeable2.default, | ||
{ | ||
className: 'image-gallery-swipe', | ||
key: 'swipeable', | ||
delta: 1, | ||
onSwipingLeft: this._handleSwiping.bind(this, -1), | ||
onSwipingRight: this._handleSwiping.bind(this, 1), | ||
onSwiped: this._handleOnSwiped.bind(this), | ||
onSwipedLeft: this._handleOnSwipedTo.bind(this, 1), | ||
onSwipedRight: this._handleOnSwipedTo.bind(this, -1) | ||
}, | ||
_react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-slides' }, | ||
slides | ||
) | ||
)] : _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-slides' }, | ||
slides | ||
), | ||
this.props.showBullets && _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-bullets' }, | ||
_react2.default.createElement( | ||
'ul', | ||
{ className: 'image-gallery-bullets-container' }, | ||
bullets | ||
) | ||
), | ||
this.props.showIndex && _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-index' }, | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-current' }, | ||
this.state.currentIndex + 1 | ||
), | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-separator' }, | ||
this.props.indexSeparator | ||
), | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-total' }, | ||
this.props.items.length | ||
) | ||
) | ||
)] : _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-slides' }, | ||
slides | ||
), | ||
this.props.showBullets && _react2.default.createElement( | ||
this.props.showThumbnails && _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-bullets' }, | ||
{ | ||
className: 'image-gallery-thumbnails' + (isFullscreen ? ' fullscreen' : ''), | ||
ref: function ref(i) { | ||
return _this7._imageGalleryThumbnail = i; | ||
} | ||
}, | ||
_react2.default.createElement( | ||
'ul', | ||
{ className: 'image-gallery-bullets-container' }, | ||
bullets | ||
'div', | ||
{ | ||
ref: function ref(t) { | ||
return _this7._thumbnails = t; | ||
}, | ||
className: 'image-gallery-thumbnails-container', | ||
style: thumbnailStyle }, | ||
thumbnails | ||
) | ||
), | ||
this.props.showIndex && _react2.default.createElement( | ||
'div', | ||
{ className: 'image-gallery-index' }, | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-current' }, | ||
this.state.currentIndex + 1 | ||
), | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-separator' }, | ||
this.props.indexSeparator | ||
), | ||
_react2.default.createElement( | ||
'span', | ||
{ className: 'image-gallery-index-total' }, | ||
this.props.items.length | ||
) | ||
) | ||
), | ||
this.props.showThumbnails && _react2.default.createElement( | ||
'div', | ||
{ | ||
className: 'image-gallery-thumbnails', | ||
ref: function ref(i) { | ||
return _this5._imageGalleryThumbnail = i; | ||
} | ||
}, | ||
_react2.default.createElement( | ||
'div', | ||
{ | ||
ref: function ref(t) { | ||
return _this5._thumbnails = t; | ||
}, | ||
className: 'image-gallery-thumbnails-container', | ||
style: thumbnailStyle }, | ||
thumbnails | ||
) | ||
) | ||
@@ -832,2 +920,4 @@ ); | ||
showThumbnails: _react2.default.PropTypes.bool, | ||
showPlayButton: _react2.default.PropTypes.bool, | ||
showFullscreenButton: _react2.default.PropTypes.bool, | ||
slideOnThumbnailHover: _react2.default.PropTypes.bool, | ||
@@ -859,2 +949,4 @@ disableThumbnailScroll: _react2.default.PropTypes.bool, | ||
showThumbnails: true, | ||
showPlayButton: true, | ||
showFullscreenButton: true, | ||
slideOnThumbnailHover: false, | ||
@@ -861,0 +953,0 @@ disableThumbnailScroll: false, |
@@ -1,13 +0,14 @@ | ||
var babel = require('gulp-babel') | ||
var browserify = require('browserify') | ||
var concat = require('gulp-concat') | ||
var connect = require('gulp-connect') | ||
var gulp = require('gulp') | ||
var livereload = require('gulp-livereload') | ||
var rename = require('gulp-rename') | ||
var sass = require('gulp-sass') | ||
var uglify = require('gulp-uglify') | ||
var source = require('vinyl-source-stream') | ||
var buffer = require('vinyl-buffer') | ||
var watchify = require('watchify') | ||
var babel = require('gulp-babel'); | ||
var browserify = require('browserify'); | ||
var concat = require('gulp-concat'); | ||
var connect = require('gulp-connect'); | ||
var gulp = require('gulp'); | ||
var livereload = require('gulp-livereload'); | ||
var rename = require('gulp-rename'); | ||
var sass = require('gulp-sass'); | ||
var uglify = require('gulp-uglify'); | ||
var cleanCSS = require('gulp-clean-css'); | ||
var source = require('vinyl-source-stream'); | ||
var buffer = require('vinyl-buffer'); | ||
var watchify = require('watchify'); | ||
@@ -17,15 +18,15 @@ gulp.task('server', function () { | ||
host: '0.0.0.0', | ||
root: ['example', 'build'], | ||
root: ['example', 'build', 'styles'], | ||
port: 8001, | ||
livereload: true | ||
}) | ||
}) | ||
}); | ||
}); | ||
gulp.task('sass', function () { | ||
gulp.src('./src/image-gallery.scss') | ||
gulp.src('./styles/scss/image-gallery.scss') | ||
.pipe(sass()) | ||
.pipe(rename('image-gallery.css')) | ||
.pipe(gulp.dest('./build/')) | ||
.pipe(livereload()) | ||
}) | ||
.pipe(gulp.dest('./styles/css/')) | ||
.pipe(livereload()); | ||
}); | ||
@@ -45,7 +46,7 @@ gulp.task('scripts', function() { | ||
.pipe(gulp.dest('./example/')) | ||
.pipe(livereload()) | ||
}) | ||
.pipe(livereload()); | ||
}); | ||
gulp.task('demo-js', function() { | ||
process.env.NODE_ENV = 'production' | ||
gulp.task('demo-src', function() { | ||
process.env.NODE_ENV = 'production'; | ||
browserify({ | ||
@@ -63,5 +64,10 @@ entries: './example/app.js', | ||
.pipe(uglify()) | ||
.pipe(gulp.dest('./demo/')) | ||
}) | ||
.pipe(gulp.dest('./demo/')); | ||
gulp.src(['./styles/css/image-gallery.css', './example/app.css']) | ||
.pipe(concat('demo.css')) | ||
.pipe(cleanCSS({keepSpecialComments: false})) | ||
.pipe(gulp.dest('./demo/')); | ||
}); | ||
gulp.task('source-js', function () { | ||
@@ -74,13 +80,13 @@ return gulp.src('./src/ImageGallery.jsx') | ||
})) | ||
.pipe(gulp.dest('./build')) | ||
}) | ||
.pipe(gulp.dest('./build')); | ||
}); | ||
gulp.task('watch', function() { | ||
livereload.listen() | ||
gulp.watch(['src/*.scss'], ['sass']) | ||
gulp.watch(['src/*.jsx', 'example/app.js'], ['scripts']) | ||
}) | ||
livereload.listen(); | ||
gulp.watch(['styles/**/*.scss'], ['sass']); | ||
gulp.watch(['src/*.jsx', 'example/app.js'], ['scripts']); | ||
}); | ||
gulp.task('dev', ['watch', 'scripts', 'sass', 'server']) | ||
gulp.task('build', ['source-js', 'sass']) | ||
gulp.task('demo', ['demo-js']) | ||
gulp.task('dev', ['watch', 'scripts', 'sass', 'server']); | ||
gulp.task('build', ['source-js', 'sass']); | ||
gulp.task('demo', ['demo-src']); |
{ | ||
"name": "react-image-gallery", | ||
"version": "0.6.10", | ||
"version": "0.7.0", | ||
"description": "React Carousel, React Image gallery, React Slide Show component", | ||
@@ -48,2 +48,3 @@ "main": "./build/image-gallery", | ||
"gulp-babel": "^6.1.2", | ||
"gulp-clean-css": "^2.0.12", | ||
"gulp-concat": "^2.6.0", | ||
@@ -50,0 +51,0 @@ "gulp-connect": "^2.2.0", |
@@ -14,2 +14,3 @@ React Image Gallery | ||
* Thumbnail navigation | ||
* Custom slides (video slides) | ||
* Responsive design | ||
@@ -29,3 +30,3 @@ | ||
``` | ||
@import "../node_modules/react-image-gallery/src/image-gallery"; | ||
@import "../node_modules/react-image-gallery/styles/scss/image-gallery.scss"; | ||
``` | ||
@@ -36,7 +37,7 @@ | ||
``` | ||
build/image-gallery.css | ||
@import "../node_modules/react-image-gallery/styles/css/image-gallery.css"; | ||
``` | ||
### EXAMPLE | ||
Need more example? See example/app.js | ||
### Example | ||
Need more example? See [`example/app.js`](https://github.com/xiaolin/react-image-gallery/blob/master/example/app.js) | ||
```js | ||
@@ -70,5 +71,5 @@ import ImageGallery from 'react-image-gallery'; | ||
thumbnailLabel: 'Optional', | ||
description: 'Optional description...' | ||
srcSet: 'Optional srcset (responsive images src)' | ||
size: 'Optional size (image size relative to the breakpoint)' | ||
description: 'Optional description...', | ||
srcSet: 'Optional srcset (responsive images src)', | ||
sizes: 'Optional sizes (image sizes relative to the breakpoint)' | ||
}, | ||
@@ -109,2 +110,4 @@ { | ||
* `showThumbnails`: Boolean, default `true` | ||
* `showFullscreenButton`: Boolean, default `true` | ||
* `showPlayButton`: Boolean, default `true` | ||
* `showBullets`: Boolean, default `false` | ||
@@ -162,3 +165,3 @@ * `showIndex`: Boolean, default `false` | ||
# functions | ||
# Functions | ||
@@ -168,2 +171,3 @@ * `play()`: continuous plays if image is not hovered | ||
* `fullScreen()`: activates full screen | ||
* `exitFullScreen()`: deactivates full screen | ||
* `slideToIndex(index)`: slides to a specific index | ||
@@ -176,3 +180,3 @@ * `getCurrentIndex()`: returns the current index | ||
# To build the example locally | ||
# Build the example locally | ||
@@ -179,0 +183,0 @@ ``` |
@@ -53,3 +53,10 @@ import React from 'react'; | ||
const screenChangeEvents = [ | ||
'fullscreenchange', | ||
'msfullscreenchange', | ||
'mozfullscreenchange', | ||
'webkitfullscreenchange' | ||
]; | ||
export default class ImageGallery extends React.Component { | ||
@@ -64,3 +71,5 @@ | ||
galleryWidth: 0, | ||
thumbnailWidth: 0 | ||
thumbnailWidth: 0, | ||
isFullscreen: false, | ||
isPlaying: false | ||
}; | ||
@@ -100,2 +109,3 @@ } | ||
componentWillMount() { | ||
this._slideLeft = debounceEventHandler( | ||
@@ -108,2 +118,3 @@ this._slideLeft.bind(this), MIN_INTERVAL, true); | ||
this._handleResize = this._handleResize.bind(this); | ||
this._handleScreenChange = this._handleScreenChange.bind(this); | ||
this._handleKeyDown = this._handleKeyDown.bind(this); | ||
@@ -124,2 +135,3 @@ this._thumbnailDelay = 300; | ||
window.addEventListener('resize', this._handleResize); | ||
this._onScreenChangeEvent(); | ||
} | ||
@@ -132,2 +144,4 @@ | ||
window.removeEventListener('resize', this._handleResize); | ||
this._offScreenChangeEvent(); | ||
if (this._intervalId) { | ||
@@ -140,18 +154,18 @@ window.clearInterval(this._intervalId); | ||
play(callback = true) { | ||
if (this._intervalId) { | ||
return; | ||
} | ||
const {slideInterval} = this.props; | ||
this._intervalId = window.setInterval(() => { | ||
if (!this.state.hovering) { | ||
if (!this.props.infinite && !this._canSlideRight()) { | ||
this.pause(); | ||
} else { | ||
this.slideToIndex(this.state.currentIndex + 1); | ||
if (!this._intervalId) { | ||
this.setState({isPlaying: true}); | ||
const {slideInterval} = this.props; | ||
this._intervalId = window.setInterval(() => { | ||
if (!this.state.hovering) { | ||
if (!this.props.infinite && !this._canSlideRight()) { | ||
this.pause(); | ||
} else { | ||
this.slideToIndex(this.state.currentIndex + 1); | ||
} | ||
} | ||
}, slideInterval > MIN_INTERVAL ? slideInterval : MIN_INTERVAL); | ||
if (this.props.onPlay && callback) { | ||
this.props.onPlay(this.state.currentIndex); | ||
} | ||
}, slideInterval > MIN_INTERVAL ? slideInterval : MIN_INTERVAL); | ||
if (this.props.onPlay && callback) { | ||
this.props.onPlay(this.state.currentIndex); | ||
} | ||
@@ -165,6 +179,7 @@ | ||
this._intervalId = null; | ||
} | ||
this.setState({isPlaying: false}); | ||
if (this.props.onPause && callback) { | ||
this.props.onPause(this.state.currentIndex); | ||
if (this.props.onPause && callback) { | ||
this.props.onPause(this.state.currentIndex); | ||
} | ||
} | ||
@@ -184,5 +199,29 @@ } | ||
gallery.webkitRequestFullscreen(); | ||
} else { | ||
// fallback to modal for unsupported browsers | ||
this.setState({modalFullscreen: true}); | ||
} | ||
this.setState({isFullscreen: true}); | ||
} | ||
exitFullScreen() { | ||
if (this.state.isFullscreen) { | ||
if (document.exitFullscreen) { | ||
document.exitFullscreen(); | ||
} else if (document.webkitExitFullscreen) { | ||
document.webkitExitFullscreen(); | ||
} else if (document.mozCancelFullScreen) { | ||
document.mozCancelFullScreen(); | ||
} else if (document.msExitFullscreen) { | ||
document.msExitFullscreen(); | ||
} else { | ||
// fallback to modal for unsupported browsers | ||
this.setState({modalFullscreen: false}); | ||
} | ||
this.setState({isFullscreen: false}); | ||
} | ||
} | ||
slideToIndex(index, event) { | ||
@@ -221,2 +260,30 @@ if (event) { | ||
_onScreenChangeEvent() { | ||
screenChangeEvents.map(eventName => { | ||
document.addEventListener(eventName, this._handleScreenChange); | ||
}); | ||
} | ||
_offScreenChangeEvent() { | ||
screenChangeEvents.map(eventName => { | ||
document.removeEventListener(eventName, this._handleScreenChange); | ||
}); | ||
} | ||
_togglePlay() { | ||
if (this._intervalId) { | ||
this.pause(); | ||
} else { | ||
this.play(); | ||
} | ||
} | ||
_toggleFullScreen() { | ||
if (this.state.isFullscreen) { | ||
this.exitFullScreen(); | ||
} else { | ||
this.fullScreen(); | ||
} | ||
} | ||
_handleResize() { | ||
@@ -232,2 +299,11 @@ if (this._imageGallery) { | ||
_handleScreenChange() { | ||
const fullScreenElement = document.fullscreenElement || | ||
document.msFullscreenElement || | ||
document.mozFullScreenElement || | ||
document.webkitFullscreenElement; | ||
this.setState({isFullscreen: !!fullScreenElement}); | ||
} | ||
_handleKeyDown(event) { | ||
@@ -276,10 +352,2 @@ const LEFT_ARROW = 37; | ||
_handleMouseOver() { | ||
this.setState({hovering: true}); | ||
} | ||
_handleMouseLeave() { | ||
this.setState({hovering: false}); | ||
} | ||
_handleImageError(event) { | ||
@@ -554,3 +622,9 @@ if (this.props.defaultImage && | ||
render() { | ||
const {currentIndex} = this.state; | ||
const { | ||
currentIndex, | ||
isFullscreen, | ||
modalFullscreen, | ||
isPlaying | ||
} = this.state; | ||
const thumbnailStyle = this._getThumbnailStyle(); | ||
@@ -640,87 +714,108 @@ | ||
return ( | ||
<section ref={i => this._imageGallery = i} className='image-gallery'> | ||
<div | ||
onMouseOver={this._handleMouseOver.bind(this)} | ||
onMouseLeave={this._handleMouseLeave.bind(this)} | ||
className='image-gallery-content'> | ||
{ | ||
this._canNavigate() ? | ||
[ | ||
this.props.showNav && | ||
<span key='navigation'> | ||
{ | ||
this._canSlideLeft() && | ||
<a | ||
className='image-gallery-left-nav' | ||
onTouchStart={slideLeft} | ||
onClick={slideLeft}/> | ||
<section | ||
ref={i => this._imageGallery = i} | ||
className={ | ||
`image-gallery${modalFullscreen ? ' fullscreen-modal' : ''}`}> | ||
} | ||
{ | ||
this._canSlideRight() && | ||
<a | ||
className='image-gallery-right-nav' | ||
onTouchStart={slideRight} | ||
onClick={slideRight}/> | ||
} | ||
</span>, | ||
<div className='image-gallery-content'> | ||
<div | ||
className='image-gallery-slide-wrapper'> | ||
<Swipeable | ||
className='image-gallery-swipe' | ||
key='swipeable' | ||
delta={1} | ||
onSwipingLeft={this._handleSwiping.bind(this, -1)} | ||
onSwipingRight={this._handleSwiping.bind(this, 1)} | ||
onSwiped={this._handleOnSwiped.bind(this)} | ||
onSwipedLeft={this._handleOnSwipedTo.bind(this, 1)} | ||
onSwipedRight={this._handleOnSwipedTo.bind(this, -1)} | ||
> | ||
<div className='image-gallery-slides'> | ||
{slides} | ||
</div> | ||
</Swipeable> | ||
] | ||
: | ||
<div className='image-gallery-slides'> | ||
{slides} | ||
</div> | ||
} | ||
{ | ||
this.props.showFullscreenButton && | ||
<a | ||
className={ | ||
`image-gallery-fullscreen-button${isFullscreen ? ' active' : ''}`} | ||
onClick={this._toggleFullScreen.bind(this)}/> | ||
} | ||
{ | ||
this.props.showPlayButton && | ||
<a | ||
ref={p => this._playButton = p} | ||
className={ | ||
`image-gallery-play-button${isPlaying ? ' active' : ''}`} | ||
onClick={this._togglePlay.bind(this)}/> | ||
} | ||
{ | ||
this._canNavigate() ? | ||
[ | ||
this.props.showNav && | ||
<span key='navigation'> | ||
<a | ||
className='image-gallery-left-nav' | ||
disabled={!this._canSlideLeft()} | ||
onTouchStart={slideLeft} | ||
onClick={slideLeft}/> | ||
<a | ||
className='image-gallery-right-nav' | ||
disabled={!this._canSlideRight()} | ||
onTouchStart={slideRight} | ||
onClick={slideRight}/> | ||
</span>, | ||
<Swipeable | ||
className='image-gallery-swipe' | ||
key='swipeable' | ||
delta={1} | ||
onSwipingLeft={this._handleSwiping.bind(this, -1)} | ||
onSwipingRight={this._handleSwiping.bind(this, 1)} | ||
onSwiped={this._handleOnSwiped.bind(this)} | ||
onSwipedLeft={this._handleOnSwipedTo.bind(this, 1)} | ||
onSwipedRight={this._handleOnSwipedTo.bind(this, -1)} | ||
> | ||
<div className='image-gallery-slides'> | ||
{slides} | ||
</div> | ||
</Swipeable> | ||
] | ||
: | ||
<div className='image-gallery-slides'> | ||
{slides} | ||
</div> | ||
} | ||
{ | ||
this.props.showBullets && | ||
<div className='image-gallery-bullets'> | ||
<ul className='image-gallery-bullets-container'> | ||
{bullets} | ||
</ul> | ||
</div> | ||
} | ||
{ | ||
this.props.showIndex && | ||
<div className='image-gallery-index'> | ||
<span className='image-gallery-index-current'> | ||
{this.state.currentIndex + 1} | ||
</span> | ||
<span className='image-gallery-index-separator'> | ||
{this.props.indexSeparator} | ||
</span> | ||
<span className='image-gallery-index-total'> | ||
{this.props.items.length} | ||
</span> | ||
</div> | ||
} | ||
</div> | ||
{ | ||
this.props.showBullets && | ||
<div className='image-gallery-bullets'> | ||
<ul className='image-gallery-bullets-container'> | ||
{bullets} | ||
</ul> | ||
this.props.showThumbnails && | ||
<div | ||
className={ | ||
`image-gallery-thumbnails${isFullscreen ? ' fullscreen' : ''}`} | ||
ref={i => this._imageGalleryThumbnail = i} | ||
> | ||
<div | ||
ref={t => this._thumbnails = t} | ||
className='image-gallery-thumbnails-container' | ||
style={thumbnailStyle}> | ||
{thumbnails} | ||
</div> | ||
</div> | ||
} | ||
{ | ||
this.props.showIndex && | ||
<div className='image-gallery-index'> | ||
<span className='image-gallery-index-current'> | ||
{this.state.currentIndex + 1} | ||
</span> | ||
<span className='image-gallery-index-separator'> | ||
{this.props.indexSeparator} | ||
</span> | ||
<span className='image-gallery-index-total'> | ||
{this.props.items.length} | ||
</span> | ||
</div> | ||
} | ||
</div> | ||
{ | ||
this.props.showThumbnails && | ||
<div | ||
className='image-gallery-thumbnails' | ||
ref={i => this._imageGalleryThumbnail = i} | ||
> | ||
<div | ||
ref={t => this._thumbnails = t} | ||
className='image-gallery-thumbnails-container' | ||
style={thumbnailStyle}> | ||
{thumbnails} | ||
</div> | ||
</div> | ||
} | ||
</section> | ||
@@ -741,2 +836,4 @@ ); | ||
showThumbnails: React.PropTypes.bool, | ||
showPlayButton: React.PropTypes.bool, | ||
showFullscreenButton: React.PropTypes.bool, | ||
slideOnThumbnailHover: React.PropTypes.bool, | ||
@@ -768,2 +865,4 @@ disableThumbnailScroll: React.PropTypes.bool, | ||
showThumbnails: true, | ||
showPlayButton: true, | ||
showFullscreenButton: true, | ||
slideOnThumbnailHover: false, | ||
@@ -770,0 +869,0 @@ disableThumbnailScroll: false, |
Sorry, the diff of this file is too big to display
296220
14
2656
187
22