diff --git a/README.md b/README.md index 5338fd6dc..c6e316dce 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,9 @@ | [artplayer-plugin-gif](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-gif) | Gif plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-gif.js&example=gif) | | [artplayer-plugin-backlight](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-backlight) | Backlight plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-backlight.js&example=backlight) | | [artplayer-plugin-playlist](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-playlist) | Playlist plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-playlist.js%0A.%2Funcompiled%2Fartplayer-plugin-playlist.css&example=playlist) | +| [artplayer-plugin-blur](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-blur) | Blur plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-blur.js&example=blur) | | [artplayer-tool-thumbnail](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-tool-thumbnail) | Thumbnail tool for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-tool-thumbnail.js&example=thumbnail) | -| [artplayer-tool-github](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-tool-github) | Github api tool for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-tool-github.js%0A.%2Funcompiled%2Fartplayer-plugin-danmuku.js&example=github) | +| [artplayer-tool-github](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-tool-github) | Github api tool for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-tool-github.js%0A.%2Funcompiled%2Fartplayer-plugin-danmuku.js&example=github) | | | [artplayer-react](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-react) | React Component for Artplayer | [demo](https://codesandbox.io/s/n74859y9rl) | | [artplayer-vue](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-vue) | Vue Component for Artplayer | [demo](https://codesandbox.io/s/6z76lm109n) | diff --git a/docs/assets/example/blur.js b/docs/assets/example/blur.js new file mode 100644 index 000000000..b20bbbe03 --- /dev/null +++ b/docs/assets/example/blur.js @@ -0,0 +1,25 @@ +var url = 'https://zhw2590582.github.io/assets-cdn'; +var art = new Artplayer({ + container: '.artplayer-app', + url: url + '/video/you-name.mp4', + autoSize: true, + moreVideoAttr: { + crossOrigin: 'anonymous', + }, + layers: [ + { + style: { + position: 'absolute', + top: '50%', + left: '50%', + width: '200px', + height: '200px', + margin: '-100px 0 0 -100px', + }, + mounted($layer) { + art.plugins.artplayerPluginBlur.attach($layer); + }, + }, + ], + plugins: [artplayerPluginBlur], +}); diff --git a/docs/index.html b/docs/index.html index 35c076383..366b52511 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,101 +1,120 @@ + + + Artplayer.js + + + + + + + + + + + + - - - Artplayer.js - - - - - - - - - - - - - - -
-
-
- -
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
- -
-
-
- - - - - - - - + + + + + + + diff --git a/docs/uncompiled/artplayer-plugin-blur.js b/docs/uncompiled/artplayer-plugin-blur.js new file mode 100644 index 000000000..0f46ea70c --- /dev/null +++ b/docs/uncompiled/artplayer-plugin-blur.js @@ -0,0 +1,101 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.artplayerPluginBlur = factory()); +}(this, function () { 'use strict'; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var blurImageUrl = createCommonjsModule(function (module, exports) { + (function(window, factory) { + { + module.exports = factory(); + } + })(commonjsGlobal, function() { + return function blurImageUrl(url, radius) { + return new Promise(function(resolve) { + var img = new Image(); + img.onload = function() { + var w = img.naturalWidth; + var h = img.naturalHeight; + var canvas = document.createElement('canvas'); + canvas.style.width = w + 'px'; + canvas.style.height = h + 'px'; + canvas.width = w; + canvas.height = h; + var context = canvas.getContext('2d'); + context.filter = `blur(${radius}px)`; + context.drawImage( + img, + -radius, + -radius, + w + radius * 2, + h + radius * 2 + ); + canvas.toBlob(function(blob) { + resolve(URL.createObjectURL(blob)); + img.onload = null; + }); + }; + img.src = url; + }); + }; + }); + }); + + function artplayerPluginBlur(art) { + var _art$constructor$util = art.constructor.utils, + errorHandle = _art$constructor$util.errorHandle, + clamp = _art$constructor$util.clamp; + var player = art.player; + return { + name: 'artplayerPluginBlur', + attach: function attach($ref) { + var radius = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 15; + errorHandle($ref instanceof Element, 'The attach element is not a dom element'); + $ref.style.backgroundRepeat = 'no-repeat'; + $ref.style.transition = 'all .2s ease'; + + function show() { + var _$ref$getBoundingClie = $ref.getBoundingClientRect(), + left = _$ref$getBoundingClie.left, + top = _$ref$getBoundingClie.top; + + $ref.style.backgroundImage = 'none'; + $ref.style.backgroundSize = "".concat(player.width, "px ").concat(player.height, "px"); + $ref.style.backgroundPosition = "".concat(player.left - left, "px ").concat(player.top - top, "px"); + player.getScreenshotBlobUrl().then(function (url) { + blurImageUrl(url, clamp(radius, 0, 50)).then(function (img) { + $ref.style.backgroundImage = "url(".concat(img, ")"); + $ref.style.visibility = 'visible'; + $ref.style.opacity = '1'; + $ref.style.pointerEvents = 'all'; + }); + }); + } + + function hide() { + $ref.style.visibility = 'hidden'; + $ref.style.opacity = '0'; + $ref.style.pointerEvents = 'none'; + $ref.style.backgroundImage = 'none'; + } + + hide(); + art.on('video:pause', show); + art.on('video:ended', show); + art.on('video:seeked', show); + art.on('video:playing', hide); + art.on('video:timeupdate', hide); + } + }; + } + + return artplayerPluginBlur; + +})); +//# sourceMappingURL=artplayer-plugin-blur.js.map diff --git a/docs/uncompiled/artplayer-plugin-blur.js.map b/docs/uncompiled/artplayer-plugin-blur.js.map new file mode 100644 index 000000000..8e4149f9d --- /dev/null +++ b/docs/uncompiled/artplayer-plugin-blur.js.map @@ -0,0 +1 @@ +{"version":3,"file":"artplayer-plugin-blur.js","sources":["../../packages/artplayer-plugin-blur/node_modules/blur-image-url/index.js","../../packages/artplayer-plugin-blur/src/index.js"],"sourcesContent":["(function(window, factory) {\n if (typeof exports === 'object') {\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n define(factory);\n } else {\n window.blurImageUrl = factory();\n }\n})(this, function() {\n return function blurImageUrl(url, radius) {\n return new Promise(function(resolve) {\n var img = new Image();\n img.onload = function() {\n var w = img.naturalWidth;\n var h = img.naturalHeight;\n var canvas = document.createElement('canvas');\n canvas.style.width = w + 'px';\n canvas.style.height = h + 'px';\n canvas.width = w;\n canvas.height = h;\n var context = canvas.getContext('2d');\n context.filter = `blur(${radius}px)`;\n context.drawImage(\n img,\n -radius,\n -radius,\n w + radius * 2,\n h + radius * 2\n );\n canvas.toBlob(function(blob) {\n resolve(URL.createObjectURL(blob));\n img.onload = null;\n });\n };\n img.src = url;\n });\n };\n});\n","import blurImageUrl from '../node_modules/blur-image-url';\n\nfunction artplayerPluginBlur(art) {\n const { errorHandle, clamp } = art.constructor.utils;\n const { player } = art;\n return {\n name: 'artplayerPluginBlur',\n attach($ref, radius = 15) {\n errorHandle($ref instanceof Element, 'The attach element is not a dom element');\n $ref.style.backgroundRepeat = 'no-repeat';\n $ref.style.transition = 'all .2s ease';\n\n function show() {\n const { left, top } = $ref.getBoundingClientRect();\n $ref.style.backgroundImage = 'none';\n $ref.style.backgroundSize = `${player.width}px ${player.height}px`;\n $ref.style.backgroundPosition = `${player.left - left}px ${player.top - top}px`;\n player.getScreenshotBlobUrl().then(url => {\n blurImageUrl(url, clamp(radius, 0, 50)).then(img => {\n $ref.style.backgroundImage = `url(${img})`;\n $ref.style.visibility = 'visible';\n $ref.style.opacity = '1';\n $ref.style.pointerEvents = 'all';\n });\n });\n }\n\n function hide() {\n $ref.style.visibility = 'hidden';\n $ref.style.opacity = '0';\n $ref.style.pointerEvents = 'none';\n $ref.style.backgroundImage = 'none';\n }\n\n hide();\n art.on('video:pause', show);\n art.on('video:ended', show);\n art.on('video:seeked', show);\n art.on('video:playing', hide);\n art.on('video:timeupdate', hide);\n },\n };\n}\n\nexport default artplayerPluginBlur;\n"],"names":["this","artplayerPluginBlur","art","constructor","utils","errorHandle","clamp","player","name","attach","$ref","radius","Element","style","backgroundRepeat","transition","show","getBoundingClientRect","left","top","backgroundImage","backgroundSize","width","height","backgroundPosition","getScreenshotBlobUrl","then","url","blurImageUrl","img","visibility","opacity","pointerEvents","hide","on"],"mappings":"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"} \ No newline at end of file diff --git a/docs/uncompiled/artplayer.js b/docs/uncompiled/artplayer.js index 2ce0a726d..b621f0c64 100644 --- a/docs/uncompiled/artplayer.js +++ b/docs/uncompiled/artplayer.js @@ -189,6 +189,1327 @@ var TinyEmitter = E; tinyEmitter.TinyEmitter = TinyEmitter; + var getSize = createCommonjsModule(function (module) { + /*! + * getSize v2.0.3 + * measure size of elements + * MIT license + */ + + /* jshint browser: true, strict: true, undef: true, unused: true */ + /* globals console: false */ + + ( function( window, factory ) { + /* jshint strict: false */ /* globals define, module */ + if ( module.exports ) { + // CommonJS + module.exports = factory(); + } else { + // browser global + window.getSize = factory(); + } + + })( window, function factory() { + + // -------------------------- helpers -------------------------- // + + // get a number from a string, not a percentage + function getStyleSize( value ) { + var num = parseFloat( value ); + // not a percent like '100%', and a number + var isValid = value.indexOf('%') == -1 && !isNaN( num ); + return isValid && num; + } + + function noop() {} + + var logError = typeof console == 'undefined' ? noop : + function( message ) { + console.error( message ); + }; + + // -------------------------- measurements -------------------------- // + + var measurements = [ + 'paddingLeft', + 'paddingRight', + 'paddingTop', + 'paddingBottom', + 'marginLeft', + 'marginRight', + 'marginTop', + 'marginBottom', + 'borderLeftWidth', + 'borderRightWidth', + 'borderTopWidth', + 'borderBottomWidth' + ]; + + var measurementsLength = measurements.length; + + function getZeroSize() { + var size = { + width: 0, + height: 0, + innerWidth: 0, + innerHeight: 0, + outerWidth: 0, + outerHeight: 0 + }; + for ( var i=0; i < measurementsLength; i++ ) { + var measurement = measurements[i]; + size[ measurement ] = 0; + } + return size; + } + + // -------------------------- getStyle -------------------------- // + + /** + * getStyle, get style of element, check for Firefox bug + * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 + */ + function getStyle( elem ) { + var style = getComputedStyle( elem ); + if ( !style ) { + logError( 'Style returned ' + style + + '. Are you running this code in a hidden iframe on Firefox? ' + + 'See https://bit.ly/getsizebug1' ); + } + return style; + } + + // -------------------------- setup -------------------------- // + + var isSetup = false; + + var isBoxSizeOuter; + + /** + * setup + * check isBoxSizerOuter + * do on first getSize() rather than on page load for Firefox bug + */ + function setup() { + // setup once + if ( isSetup ) { + return; + } + isSetup = true; + + // -------------------------- box sizing -------------------------- // + + /** + * Chrome & Safari measure the outer-width on style.width on border-box elems + * IE11 & Firefox<29 measures the inner-width + */ + var div = document.createElement('div'); + div.style.width = '200px'; + div.style.padding = '1px 2px 3px 4px'; + div.style.borderStyle = 'solid'; + div.style.borderWidth = '1px 2px 3px 4px'; + div.style.boxSizing = 'border-box'; + + var body = document.body || document.documentElement; + body.appendChild( div ); + var style = getStyle( div ); + // round value for browser zoom. desandro/masonry#928 + isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; + getSize.isBoxSizeOuter = isBoxSizeOuter; + + body.removeChild( div ); + } + + // -------------------------- getSize -------------------------- // + + function getSize( elem ) { + setup(); + + // use querySeletor if elem is string + if ( typeof elem == 'string' ) { + elem = document.querySelector( elem ); + } + + // do not proceed on non-objects + if ( !elem || typeof elem != 'object' || !elem.nodeType ) { + return; + } + + var style = getStyle( elem ); + + // if hidden, everything is 0 + if ( style.display == 'none' ) { + return getZeroSize(); + } + + var size = {}; + size.width = elem.offsetWidth; + size.height = elem.offsetHeight; + + var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; + + // get all measurements + for ( var i=0; i < measurementsLength; i++ ) { + var measurement = measurements[i]; + var value = style[ measurement ]; + var num = parseFloat( value ); + // any 'auto', 'medium' value will be 0 + size[ measurement ] = !isNaN( num ) ? num : 0; + } + + var paddingWidth = size.paddingLeft + size.paddingRight; + var paddingHeight = size.paddingTop + size.paddingBottom; + var marginWidth = size.marginLeft + size.marginRight; + var marginHeight = size.marginTop + size.marginBottom; + var borderWidth = size.borderLeftWidth + size.borderRightWidth; + var borderHeight = size.borderTopWidth + size.borderBottomWidth; + + var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; + + // overwrite width and height if we can get it from style + var styleWidth = getStyleSize( style.width ); + if ( styleWidth !== false ) { + size.width = styleWidth + + // add padding and border unless it's already including it + ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); + } + + var styleHeight = getStyleSize( style.height ); + if ( styleHeight !== false ) { + size.height = styleHeight + + // add padding and border unless it's already including it + ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); + } + + size.innerWidth = size.width - ( paddingWidth + borderWidth ); + size.innerHeight = size.height - ( paddingHeight + borderHeight ); + + size.outerWidth = size.width + marginWidth; + size.outerHeight = size.height + marginHeight; + + return size; + } + + return getSize; + + }); + }); + + var evEmitter = createCommonjsModule(function (module) { + /** + * EvEmitter v1.1.0 + * Lil' event emitter + * MIT License + */ + + /* jshint unused: true, undef: true, strict: true */ + + ( function( global, factory ) { + // universal module definition + /* jshint strict: false */ /* globals define, module, window */ + if ( module.exports ) { + // CommonJS - Browserify, Webpack + module.exports = factory(); + } else { + // Browser globals + global.EvEmitter = factory(); + } + + }( typeof window != 'undefined' ? window : commonjsGlobal, function() { + + function EvEmitter() {} + + var proto = EvEmitter.prototype; + + proto.on = function( eventName, listener ) { + if ( !eventName || !listener ) { + return; + } + // set events hash + var events = this._events = this._events || {}; + // set listeners array + var listeners = events[ eventName ] = events[ eventName ] || []; + // only add once + if ( listeners.indexOf( listener ) == -1 ) { + listeners.push( listener ); + } + + return this; + }; + + proto.once = function( eventName, listener ) { + if ( !eventName || !listener ) { + return; + } + // add event + this.on( eventName, listener ); + // set once flag + // set onceEvents hash + var onceEvents = this._onceEvents = this._onceEvents || {}; + // set onceListeners object + var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; + // set flag + onceListeners[ listener ] = true; + + return this; + }; + + proto.off = function( eventName, listener ) { + var listeners = this._events && this._events[ eventName ]; + if ( !listeners || !listeners.length ) { + return; + } + var index = listeners.indexOf( listener ); + if ( index != -1 ) { + listeners.splice( index, 1 ); + } + + return this; + }; + + proto.emitEvent = function( eventName, args ) { + var listeners = this._events && this._events[ eventName ]; + if ( !listeners || !listeners.length ) { + return; + } + // copy over to avoid interference if .off() in listener + listeners = listeners.slice(0); + args = args || []; + // once stuff + var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; + + for ( var i=0; i < listeners.length; i++ ) { + var listener = listeners[i]; + var isOnce = onceListeners && onceListeners[ listener ]; + if ( isOnce ) { + // remove listener + // remove before trigger to prevent recursion + this.off( eventName, listener ); + // unset once flag + delete onceListeners[ listener ]; + } + // trigger listener + listener.apply( this, args ); + } + + return this; + }; + + proto.allOff = function() { + delete this._events; + delete this._onceEvents; + }; + + return EvEmitter; + + })); + }); + + var unipointer = createCommonjsModule(function (module) { + /*! + * Unipointer v2.3.0 + * base class for doing one thing with pointer event + * MIT license + */ + + /*jshint browser: true, undef: true, unused: true, strict: true */ + + ( function( window, factory ) { + // universal module definition + /* jshint strict: false */ /*global define, module, require */ + if ( module.exports ) { + // CommonJS + module.exports = factory( + window, + evEmitter + ); + } else { + // browser global + window.Unipointer = factory( + window, + window.EvEmitter + ); + } + + }( window, function factory( window, EvEmitter ) { + + function noop() {} + + function Unipointer() {} + + // inherit EvEmitter + var proto = Unipointer.prototype = Object.create( EvEmitter.prototype ); + + proto.bindStartEvent = function( elem ) { + this._bindStartEvent( elem, true ); + }; + + proto.unbindStartEvent = function( elem ) { + this._bindStartEvent( elem, false ); + }; + + /** + * Add or remove start event + * @param {Boolean} isAdd - remove if falsey + */ + proto._bindStartEvent = function( elem, isAdd ) { + // munge isAdd, default to true + isAdd = isAdd === undefined ? true : isAdd; + var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; + + // default to mouse events + var startEvent = 'mousedown'; + if ( window.PointerEvent ) { + // Pointer Events + startEvent = 'pointerdown'; + } else if ( 'ontouchstart' in window ) { + // Touch Events. iOS Safari + startEvent = 'touchstart'; + } + elem[ bindMethod ]( startEvent, this ); + }; + + // trigger handler methods for events + proto.handleEvent = function( event ) { + var method = 'on' + event.type; + if ( this[ method ] ) { + this[ method ]( event ); + } + }; + + // returns the touch that we're keeping track of + proto.getTouch = function( touches ) { + for ( var i=0; i < touches.length; i++ ) { + var touch = touches[i]; + if ( touch.identifier == this.pointerIdentifier ) { + return touch; + } + } + }; + + // ----- start event ----- // + + proto.onmousedown = function( event ) { + // dismiss clicks from right or middle buttons + var button = event.button; + if ( button && ( button !== 0 && button !== 1 ) ) { + return; + } + this._pointerDown( event, event ); + }; + + proto.ontouchstart = function( event ) { + this._pointerDown( event, event.changedTouches[0] ); + }; + + proto.onpointerdown = function( event ) { + this._pointerDown( event, event ); + }; + + /** + * pointer start + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto._pointerDown = function( event, pointer ) { + // dismiss right click and other pointers + // button = 0 is okay, 1-4 not + if ( event.button || this.isPointerDown ) { + return; + } + + this.isPointerDown = true; + // save pointer identifier to match up touch events + this.pointerIdentifier = pointer.pointerId !== undefined ? + // pointerId for pointer events, touch.indentifier for touch events + pointer.pointerId : pointer.identifier; + + this.pointerDown( event, pointer ); + }; + + proto.pointerDown = function( event, pointer ) { + this._bindPostStartEvents( event ); + this.emitEvent( 'pointerDown', [ event, pointer ] ); + }; + + // hash of events to be bound after start event + var postStartEvents = { + mousedown: [ 'mousemove', 'mouseup' ], + touchstart: [ 'touchmove', 'touchend', 'touchcancel' ], + pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ], + }; + + proto._bindPostStartEvents = function( event ) { + if ( !event ) { + return; + } + // get proper events to match start event + var events = postStartEvents[ event.type ]; + // bind events to node + events.forEach( function( eventName ) { + window.addEventListener( eventName, this ); + }, this ); + // save these arguments + this._boundPointerEvents = events; + }; + + proto._unbindPostStartEvents = function() { + // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug) + if ( !this._boundPointerEvents ) { + return; + } + this._boundPointerEvents.forEach( function( eventName ) { + window.removeEventListener( eventName, this ); + }, this ); + + delete this._boundPointerEvents; + }; + + // ----- move event ----- // + + proto.onmousemove = function( event ) { + this._pointerMove( event, event ); + }; + + proto.onpointermove = function( event ) { + if ( event.pointerId == this.pointerIdentifier ) { + this._pointerMove( event, event ); + } + }; + + proto.ontouchmove = function( event ) { + var touch = this.getTouch( event.changedTouches ); + if ( touch ) { + this._pointerMove( event, touch ); + } + }; + + /** + * pointer move + * @param {Event} event + * @param {Event or Touch} pointer + * @private + */ + proto._pointerMove = function( event, pointer ) { + this.pointerMove( event, pointer ); + }; + + // public + proto.pointerMove = function( event, pointer ) { + this.emitEvent( 'pointerMove', [ event, pointer ] ); + }; + + // ----- end event ----- // + + + proto.onmouseup = function( event ) { + this._pointerUp( event, event ); + }; + + proto.onpointerup = function( event ) { + if ( event.pointerId == this.pointerIdentifier ) { + this._pointerUp( event, event ); + } + }; + + proto.ontouchend = function( event ) { + var touch = this.getTouch( event.changedTouches ); + if ( touch ) { + this._pointerUp( event, touch ); + } + }; + + /** + * pointer up + * @param {Event} event + * @param {Event or Touch} pointer + * @private + */ + proto._pointerUp = function( event, pointer ) { + this._pointerDone(); + this.pointerUp( event, pointer ); + }; + + // public + proto.pointerUp = function( event, pointer ) { + this.emitEvent( 'pointerUp', [ event, pointer ] ); + }; + + // ----- pointer done ----- // + + // triggered on pointer up & pointer cancel + proto._pointerDone = function() { + this._pointerReset(); + this._unbindPostStartEvents(); + this.pointerDone(); + }; + + proto._pointerReset = function() { + // reset properties + this.isPointerDown = false; + delete this.pointerIdentifier; + }; + + proto.pointerDone = noop; + + // ----- pointer cancel ----- // + + proto.onpointercancel = function( event ) { + if ( event.pointerId == this.pointerIdentifier ) { + this._pointerCancel( event, event ); + } + }; + + proto.ontouchcancel = function( event ) { + var touch = this.getTouch( event.changedTouches ); + if ( touch ) { + this._pointerCancel( event, touch ); + } + }; + + /** + * pointer cancel + * @param {Event} event + * @param {Event or Touch} pointer + * @private + */ + proto._pointerCancel = function( event, pointer ) { + this._pointerDone(); + this.pointerCancel( event, pointer ); + }; + + // public + proto.pointerCancel = function( event, pointer ) { + this.emitEvent( 'pointerCancel', [ event, pointer ] ); + }; + + // ----- ----- // + + // utility function for getting x/y coords from event + Unipointer.getPointerPoint = function( pointer ) { + return { + x: pointer.pageX, + y: pointer.pageY + }; + }; + + // ----- ----- // + + return Unipointer; + + })); + }); + + var unidragger = createCommonjsModule(function (module) { + /*! + * Unidragger v2.3.0 + * Draggable base class + * MIT license + */ + + /*jshint browser: true, unused: true, undef: true, strict: true */ + + ( function( window, factory ) { + // universal module definition + /*jshint strict: false */ /*globals define, module, require */ + + if ( module.exports ) { + // CommonJS + module.exports = factory( + window, + unipointer + ); + } else { + // browser global + window.Unidragger = factory( + window, + window.Unipointer + ); + } + + }( window, function factory( window, Unipointer ) { + + // -------------------------- Unidragger -------------------------- // + + function Unidragger() {} + + // inherit Unipointer & EvEmitter + var proto = Unidragger.prototype = Object.create( Unipointer.prototype ); + + // ----- bind start ----- // + + proto.bindHandles = function() { + this._bindHandles( true ); + }; + + proto.unbindHandles = function() { + this._bindHandles( false ); + }; + + /** + * Add or remove start event + * @param {Boolean} isAdd + */ + proto._bindHandles = function( isAdd ) { + // munge isAdd, default to true + isAdd = isAdd === undefined ? true : isAdd; + // bind each handle + var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; + var touchAction = isAdd ? this._touchActionValue : ''; + for ( var i=0; i < this.handles.length; i++ ) { + var handle = this.handles[i]; + this._bindStartEvent( handle, isAdd ); + handle[ bindMethod ]( 'click', this ); + // touch-action: none to override browser touch gestures. metafizzy/flickity#540 + if ( window.PointerEvent ) { + handle.style.touchAction = touchAction; + } + } + }; + + // prototype so it can be overwriteable by Flickity + proto._touchActionValue = 'none'; + + // ----- start event ----- // + + /** + * pointer start + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.pointerDown = function( event, pointer ) { + var isOkay = this.okayPointerDown( event ); + if ( !isOkay ) { + return; + } + // track start event position + this.pointerDownPointer = pointer; + + event.preventDefault(); + this.pointerDownBlur(); + // bind move and end events + this._bindPostStartEvents( event ); + this.emitEvent( 'pointerDown', [ event, pointer ] ); + }; + + // nodes that have text fields + var cursorNodes = { + TEXTAREA: true, + INPUT: true, + SELECT: true, + OPTION: true, + }; + + // input types that do not have text fields + var clickTypes = { + radio: true, + checkbox: true, + button: true, + submit: true, + image: true, + file: true, + }; + + // dismiss inputs with text fields. flickity#403, flickity#404 + proto.okayPointerDown = function( event ) { + var isCursorNode = cursorNodes[ event.target.nodeName ]; + var isClickType = clickTypes[ event.target.type ]; + var isOkay = !isCursorNode || isClickType; + if ( !isOkay ) { + this._pointerReset(); + } + return isOkay; + }; + + // kludge to blur previously focused input + proto.pointerDownBlur = function() { + var focused = document.activeElement; + // do not blur body for IE10, metafizzy/flickity#117 + var canBlur = focused && focused.blur && focused != document.body; + if ( canBlur ) { + focused.blur(); + } + }; + + // ----- move event ----- // + + /** + * drag move + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.pointerMove = function( event, pointer ) { + var moveVector = this._dragPointerMove( event, pointer ); + this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] ); + this._dragMove( event, pointer, moveVector ); + }; + + // base pointer move logic + proto._dragPointerMove = function( event, pointer ) { + var moveVector = { + x: pointer.pageX - this.pointerDownPointer.pageX, + y: pointer.pageY - this.pointerDownPointer.pageY + }; + // start drag if pointer has moved far enough to start drag + if ( !this.isDragging && this.hasDragStarted( moveVector ) ) { + this._dragStart( event, pointer ); + } + return moveVector; + }; + + // condition if pointer has moved far enough to start drag + proto.hasDragStarted = function( moveVector ) { + return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3; + }; + + // ----- end event ----- // + + /** + * pointer up + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.pointerUp = function( event, pointer ) { + this.emitEvent( 'pointerUp', [ event, pointer ] ); + this._dragPointerUp( event, pointer ); + }; + + proto._dragPointerUp = function( event, pointer ) { + if ( this.isDragging ) { + this._dragEnd( event, pointer ); + } else { + // pointer didn't move enough for drag to start + this._staticClick( event, pointer ); + } + }; + + // -------------------------- drag -------------------------- // + + // dragStart + proto._dragStart = function( event, pointer ) { + this.isDragging = true; + // prevent clicks + this.isPreventingClicks = true; + this.dragStart( event, pointer ); + }; + + proto.dragStart = function( event, pointer ) { + this.emitEvent( 'dragStart', [ event, pointer ] ); + }; + + // dragMove + proto._dragMove = function( event, pointer, moveVector ) { + // do not drag if not dragging yet + if ( !this.isDragging ) { + return; + } + + this.dragMove( event, pointer, moveVector ); + }; + + proto.dragMove = function( event, pointer, moveVector ) { + event.preventDefault(); + this.emitEvent( 'dragMove', [ event, pointer, moveVector ] ); + }; + + // dragEnd + proto._dragEnd = function( event, pointer ) { + // set flags + this.isDragging = false; + // re-enable clicking async + setTimeout( function() { + delete this.isPreventingClicks; + }.bind( this ) ); + + this.dragEnd( event, pointer ); + }; + + proto.dragEnd = function( event, pointer ) { + this.emitEvent( 'dragEnd', [ event, pointer ] ); + }; + + // ----- onclick ----- // + + // handle all clicks and prevent clicks when dragging + proto.onclick = function( event ) { + if ( this.isPreventingClicks ) { + event.preventDefault(); + } + }; + + // ----- staticClick ----- // + + // triggered after pointer down & up with no/tiny movement + proto._staticClick = function( event, pointer ) { + // ignore emulated mouse up clicks + if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { + return; + } + + this.staticClick( event, pointer ); + + // set flag for emulated clicks 300ms after touchend + if ( event.type != 'mouseup' ) { + this.isIgnoringMouseUp = true; + // reset flag after 300ms + setTimeout( function() { + delete this.isIgnoringMouseUp; + }.bind( this ), 400 ); + } + }; + + proto.staticClick = function( event, pointer ) { + this.emitEvent( 'staticClick', [ event, pointer ] ); + }; + + // ----- utils ----- // + + Unidragger.getPointerPoint = Unipointer.getPointerPoint; + + // ----- ----- // + + return Unidragger; + + })); + }); + + var draggabilly = createCommonjsModule(function (module) { + /*! + * Draggabilly v2.2.0 + * Make that shiz draggable + * https://draggabilly.desandro.com + * MIT license + */ + + /*jshint browser: true, strict: true, undef: true, unused: true */ + + ( function( window, factory ) { + // universal module definition + /* jshint strict: false */ /*globals define, module, require */ + if ( module.exports ) { + // CommonJS + module.exports = factory( + window, + getSize, + unidragger + ); + } else { + // browser global + window.Draggabilly = factory( + window, + window.getSize, + window.Unidragger + ); + } + + }( window, function factory( window, getSize, Unidragger ) { + + // -------------------------- helpers & variables -------------------------- // + + // extend objects + function extend( a, b ) { + for ( var prop in b ) { + a[ prop ] = b[ prop ]; + } + return a; + } + + function noop() {} + + var jQuery = window.jQuery; + + // -------------------------- -------------------------- // + + function Draggabilly( element, options ) { + // querySelector if string + this.element = typeof element == 'string' ? + document.querySelector( element ) : element; + + if ( jQuery ) { + this.$element = jQuery( this.element ); + } + + // options + this.options = extend( {}, this.constructor.defaults ); + this.option( options ); + + this._create(); + } + + // inherit Unidragger methods + var proto = Draggabilly.prototype = Object.create( Unidragger.prototype ); + + Draggabilly.defaults = { + }; + + /** + * set options + * @param {Object} opts + */ + proto.option = function( opts ) { + extend( this.options, opts ); + }; + + // css position values that don't need to be set + var positionValues = { + relative: true, + absolute: true, + fixed: true + }; + + proto._create = function() { + // properties + this.position = {}; + this._getPosition(); + + this.startPoint = { x: 0, y: 0 }; + this.dragPoint = { x: 0, y: 0 }; + + this.startPosition = extend( {}, this.position ); + + // set relative positioning + var style = getComputedStyle( this.element ); + if ( !positionValues[ style.position ] ) { + this.element.style.position = 'relative'; + } + + // events, bridge jQuery events from vanilla + this.on( 'pointerDown', this.onPointerDown ); + this.on( 'pointerMove', this.onPointerMove ); + this.on( 'pointerUp', this.onPointerUp ); + + this.enable(); + this.setHandles(); + }; + + /** + * set this.handles and bind start events to 'em + */ + proto.setHandles = function() { + this.handles = this.options.handle ? + this.element.querySelectorAll( this.options.handle ) : [ this.element ]; + + this.bindHandles(); + }; + + /** + * emits events via EvEmitter and jQuery events + * @param {String} type - name of event + * @param {Event} event - original event + * @param {Array} args - extra arguments + */ + proto.dispatchEvent = function( type, event, args ) { + var emitArgs = [ event ].concat( args ); + this.emitEvent( type, emitArgs ); + this.dispatchJQueryEvent( type, event, args ); + }; + + proto.dispatchJQueryEvent = function( type, event, args ) { + var jQuery = window.jQuery; + // trigger jQuery event + if ( !jQuery || !this.$element ) { + return; + } + // create jQuery event + var $event = jQuery.Event( event ); + $event.type = type; + this.$element.trigger( $event, args ); + }; + + // -------------------------- position -------------------------- // + + // get x/y position from style + proto._getPosition = function() { + var style = getComputedStyle( this.element ); + var x = this._getPositionCoord( style.left, 'width' ); + var y = this._getPositionCoord( style.top, 'height' ); + // clean up 'auto' or other non-integer values + this.position.x = isNaN( x ) ? 0 : x; + this.position.y = isNaN( y ) ? 0 : y; + + this._addTransformPosition( style ); + }; + + proto._getPositionCoord = function( styleSide, measure ) { + if ( styleSide.indexOf('%') != -1 ) { + // convert percent into pixel for Safari, #75 + var parentSize = getSize( this.element.parentNode ); + // prevent not-in-DOM element throwing bug, #131 + return !parentSize ? 0 : + ( parseFloat( styleSide ) / 100 ) * parentSize[ measure ]; + } + return parseInt( styleSide, 10 ); + }; + + // add transform: translate( x, y ) to position + proto._addTransformPosition = function( style ) { + var transform = style.transform; + // bail out if value is 'none' + if ( transform.indexOf('matrix') !== 0 ) { + return; + } + // split matrix(1, 0, 0, 1, x, y) + var matrixValues = transform.split(','); + // translate X value is in 12th or 4th position + var xIndex = transform.indexOf('matrix3d') === 0 ? 12 : 4; + var translateX = parseInt( matrixValues[ xIndex ], 10 ); + // translate Y value is in 13th or 5th position + var translateY = parseInt( matrixValues[ xIndex + 1 ], 10 ); + this.position.x += translateX; + this.position.y += translateY; + }; + + // -------------------------- events -------------------------- // + + proto.onPointerDown = function( event, pointer ) { + this.element.classList.add('is-pointer-down'); + this.dispatchJQueryEvent( 'pointerDown', event, [ pointer ] ); + }; + + /** + * drag start + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.dragStart = function( event, pointer ) { + if ( !this.isEnabled ) { + return; + } + this._getPosition(); + this.measureContainment(); + // position _when_ drag began + this.startPosition.x = this.position.x; + this.startPosition.y = this.position.y; + // reset left/top style + this.setLeftTop(); + + this.dragPoint.x = 0; + this.dragPoint.y = 0; + + this.element.classList.add('is-dragging'); + this.dispatchEvent( 'dragStart', event, [ pointer ] ); + // start animation + this.animate(); + }; + + proto.measureContainment = function() { + var container = this.getContainer(); + if ( !container ) { + return; + } + + var elemSize = getSize( this.element ); + var containerSize = getSize( container ); + var elemRect = this.element.getBoundingClientRect(); + var containerRect = container.getBoundingClientRect(); + + var borderSizeX = containerSize.borderLeftWidth + containerSize.borderRightWidth; + var borderSizeY = containerSize.borderTopWidth + containerSize.borderBottomWidth; + + var position = this.relativeStartPosition = { + x: elemRect.left - ( containerRect.left + containerSize.borderLeftWidth ), + y: elemRect.top - ( containerRect.top + containerSize.borderTopWidth ) + }; + + this.containSize = { + width: ( containerSize.width - borderSizeX ) - position.x - elemSize.width, + height: ( containerSize.height - borderSizeY ) - position.y - elemSize.height + }; + }; + + proto.getContainer = function() { + var containment = this.options.containment; + if ( !containment ) { + return; + } + var isElement = containment instanceof HTMLElement; + // use as element + if ( isElement ) { + return containment; + } + // querySelector if string + if ( typeof containment == 'string' ) { + return document.querySelector( containment ); + } + // fallback to parent element + return this.element.parentNode; + }; + + // ----- move event ----- // + + proto.onPointerMove = function( event, pointer, moveVector ) { + this.dispatchJQueryEvent( 'pointerMove', event, [ pointer, moveVector ] ); + }; + + /** + * drag move + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.dragMove = function( event, pointer, moveVector ) { + if ( !this.isEnabled ) { + return; + } + var dragX = moveVector.x; + var dragY = moveVector.y; + + var grid = this.options.grid; + var gridX = grid && grid[0]; + var gridY = grid && grid[1]; + + dragX = applyGrid( dragX, gridX ); + dragY = applyGrid( dragY, gridY ); + + dragX = this.containDrag( 'x', dragX, gridX ); + dragY = this.containDrag( 'y', dragY, gridY ); + + // constrain to axis + dragX = this.options.axis == 'y' ? 0 : dragX; + dragY = this.options.axis == 'x' ? 0 : dragY; + + this.position.x = this.startPosition.x + dragX; + this.position.y = this.startPosition.y + dragY; + // set dragPoint properties + this.dragPoint.x = dragX; + this.dragPoint.y = dragY; + + this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] ); + }; + + function applyGrid( value, grid, method ) { + method = method || 'round'; + return grid ? Math[ method ]( value / grid ) * grid : value; + } + + proto.containDrag = function( axis, drag, grid ) { + if ( !this.options.containment ) { + return drag; + } + var measure = axis == 'x' ? 'width' : 'height'; + + var rel = this.relativeStartPosition[ axis ]; + var min = applyGrid( -rel, grid, 'ceil' ); + var max = this.containSize[ measure ]; + max = applyGrid( max, grid, 'floor' ); + return Math.max( min, Math.min( max, drag ) ); + }; + + // ----- end event ----- // + + /** + * pointer up + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.onPointerUp = function( event, pointer ) { + this.element.classList.remove('is-pointer-down'); + this.dispatchJQueryEvent( 'pointerUp', event, [ pointer ] ); + }; + + /** + * drag end + * @param {Event} event + * @param {Event or Touch} pointer + */ + proto.dragEnd = function( event, pointer ) { + if ( !this.isEnabled ) { + return; + } + // use top left position when complete + this.element.style.transform = ''; + this.setLeftTop(); + this.element.classList.remove('is-dragging'); + this.dispatchEvent( 'dragEnd', event, [ pointer ] ); + }; + + // -------------------------- animation -------------------------- // + + proto.animate = function() { + // only render and animate if dragging + if ( !this.isDragging ) { + return; + } + + this.positionDrag(); + + var _this = this; + requestAnimationFrame( function animateFrame() { + _this.animate(); + }); + + }; + + // left/top positioning + proto.setLeftTop = function() { + this.element.style.left = this.position.x + 'px'; + this.element.style.top = this.position.y + 'px'; + }; + + proto.positionDrag = function() { + this.element.style.transform = 'translate3d( ' + this.dragPoint.x + + 'px, ' + this.dragPoint.y + 'px, 0)'; + }; + + // ----- staticClick ----- // + + proto.staticClick = function( event, pointer ) { + this.dispatchEvent( 'staticClick', event, [ pointer ] ); + }; + + // ----- methods ----- // + + /** + * @param {Number} x + * @param {Number} y + */ + proto.setPosition = function( x, y ) { + this.position.x = x; + this.position.y = y; + this.setLeftTop(); + }; + + proto.enable = function() { + this.isEnabled = true; + }; + + proto.disable = function() { + this.isEnabled = false; + if ( this.isDragging ) { + this.dragEnd(); + } + }; + + proto.destroy = function() { + this.disable(); + // reset styles + this.element.style.transform = ''; + this.element.style.left = ''; + this.element.style.top = ''; + this.element.style.position = ''; + // unbind handles + this.unbindHandles(); + // remove jQuery data + if ( this.$element ) { + this.$element.removeData('draggabilly'); + } + }; + + // ----- jQuery bridget ----- // + + // required for jQuery bridget + proto._init = noop; + + if ( jQuery && jQuery.bridget ) { + jQuery.bridget( 'draggabilly', Draggabilly ); + } + + // ----- ----- // + + return Draggabilly; + + })); + }); + var optionValidator = createCommonjsModule(function (module, exports) { !function(r,t){module.exports=t();}(commonjsGlobal,function(){function c(r){return (c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r})(r)}var u=Object.prototype.toString,i=function(r){if(void 0===r)return "undefined";if(null===r)return "null";var t,e,n,o,a,i=c(r);if("boolean"===i)return "boolean";if("string"===i)return "string";if("number"===i)return "number";if("symbol"===i)return "symbol";if("function"===i)return "GeneratorFunction"===f(r)?"generatorfunction":"function";if(t=r,Array.isArray?Array.isArray(t):t instanceof Array)return "array";if(function(r){if(r.constructor&&"function"==typeof r.constructor.isBuffer)return r.constructor.isBuffer(r);return !1}(r))return "buffer";if(function(r){try{if("number"==typeof r.length&&"function"==typeof r.callee)return !0}catch(r){if(-1!==r.message.indexOf("callee"))return !0}return !1}(r))return "arguments";if((e=r)instanceof Date||"function"==typeof e.toDateString&&"function"==typeof e.getDate&&"function"==typeof e.setDate)return "date";if((n=r)instanceof Error||"string"==typeof n.message&&n.constructor&&"number"==typeof n.constructor.stackTraceLimit)return "error";if((o=r)instanceof RegExp||"string"==typeof o.flags&&"boolean"==typeof o.ignoreCase&&"boolean"==typeof o.multiline&&"boolean"==typeof o.global)return "regexp";switch(f(r)){case"Symbol":return "symbol";case"Promise":return "promise";case"WeakMap":return "weakmap";case"WeakSet":return "weakset";case"Map":return "map";case"Set":return "set";case"Int8Array":return "int8array";case"Uint8Array":return "uint8array";case"Uint8ClampedArray":return "uint8clampedarray";case"Int16Array":return "int16array";case"Uint16Array":return "uint16array";case"Int32Array":return "int32array";case"Uint32Array":return "uint32array";case"Float32Array":return "float32array";case"Float64Array":return "float64array"}if("function"==typeof(a=r).throw&&"function"==typeof a.return&&"function"==typeof a.next)return "generator";switch(i=u.call(r)){case"[object Object]":return "object";case"[object Map Iterator]":return "mapiterator";case"[object Set Iterator]":return "setiterator";case"[object String Iterator]":return "stringiterator";case"[object Array Iterator]":return "arrayiterator"}return i.slice(8,-1).toLowerCase().replace(/\s/g,"")};function f(r){return r.constructor?r.constructor.name:null}function a(r,t){var e=2