123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /**
- * The component for playing slides automatically.
- *
- * @author Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
- import { applyStyle, subscribe } from '../../utils/dom';
- import { createInterval } from '../../utils/time';
- /**
- * Set of pause flags.
- */
- const PAUSE_FLAGS = {
- HOVER : 1,
- FOCUS : 2,
- MANUAL: 3,
- };
- /**
- * The component for playing slides automatically.
- *
- * @param {Splide} Splide - A Splide instance.
- * @param {Object} Components - An object containing components.
- * @param {string} name - A component name as a lowercase string.
- *
- * @return {Object} - The component object.
- */
- export default ( Splide, Components, name ) => {
- /**
- * Store pause flags.
- *
- * @type {Array}
- */
- let flags = [];
- /**
- * Store an interval object.
- *
- * @type {Object};
- */
- let interval;
- /**
- * Autoplay component object.
- *
- * @type {Object}
- */
- const Autoplay = {
- /**
- * Required only when the autoplay option is true.
- *
- * @type {boolean}
- */
- required: Splide.options.autoplay,
- /**
- * Called when the component is mounted.
- * Note that autoplay starts only if there are slides over perView number.
- */
- mount() {
- const options = Splide.options;
- const { slides, bar } = Components.Elements;
- if ( slides.length > options.perView ) {
- interval = createInterval( () => { Splide.go( '>' ) }, options.interval, rate => {
- Splide.emit( `${ name }:playing`, rate );
- bar && applyStyle( bar, { width: `${ rate * 100 }%` } );
- } );
- bind();
- this.play();
- }
- },
- /**
- * Start autoplay.
- *
- * @param {number} flag - A pause flag to be removed.
- */
- play( flag = 0 ) {
- flags = flags.filter( f => f !== flag );
- if ( ! flags.length ) {
- Splide.emit( `${ name }:play` );
- interval.play();
- }
- },
- /**
- * Pause autoplay.
- * Note that Array.includes is not supported by IE.
- *
- * @param {number} flag - A pause flag to be added.
- */
- pause( flag = 0 ) {
- interval.pause();
- if ( flags.indexOf( flag ) === -1 ) {
- flags.push( flag );
- }
- if ( flags.length === 1 ) {
- Splide.emit( `${ name }:pause` );
- }
- },
- };
- /**
- * Listen some events.
- */
- function bind() {
- const options = Splide.options;
- const Elements = Components.Elements;
- const sub = Splide.sub;
- const elms = [ Splide.root, sub ? sub.root : null ];
- if ( options.pauseOnHover ) {
- switchOn( elms, 'mouseleave', PAUSE_FLAGS.HOVER, true );
- switchOn( elms, 'mouseenter', PAUSE_FLAGS.HOVER, false );
- }
- if ( options.pauseOnFocus ) {
- switchOn( elms, 'focusout', PAUSE_FLAGS.FOCUS, true );
- switchOn( elms, 'focusin', PAUSE_FLAGS.FOCUS, false );
- }
- subscribe( Elements.play, 'click', () => {
- // Need to be removed a focus flag at first.
- Autoplay.play( PAUSE_FLAGS.FOCUS );
- Autoplay.play( PAUSE_FLAGS.MANUAL );
- } );
- switchOn( [ Elements.pause ], 'click', PAUSE_FLAGS.MANUAL, false );
- // Rewind the timer when others move the slide.
- Splide.on( 'move', () => { Autoplay.play() } );
- }
- /**
- * Play or pause on the given event.
- *
- * @param {Element[]} elms - Elements.
- * @param {string} event - An event name or names.
- * @param {number} flag - A pause flag defined on the top.
- * @param {boolean} play - Determine whether to play or pause.
- */
- function switchOn( elms, event, flag, play ) {
- for ( let i in elms ) {
- subscribe( elms[ i ], event, () => { Autoplay[ play ? 'play' : 'pause' ]( flag ) } );
- }
- }
- return Autoplay;
- }
|