github.com/wanliu/go-oauth2-server@v0.0.0-20180817021415-f928fa1580df/public/js/main.js (about)

     1  {
     2  	class Details {
     3  		constructor() {
     4  			this.DOM = {};
     5  
     6  			const detailsTmpl = `
     7  			<div class="details__bg details__bg--down">
     8  				<button class="details__close"><i class="fas fa-2x fa-times icon--cross tm-fa-close"></i></button>
     9  				<div class="details__description"></div>
    10  			</div>
    11  			`;
    12  
    13  			this.DOM.details = document.createElement('div');
    14  			this.DOM.details.className = 'details';
    15  			this.DOM.details.innerHTML = detailsTmpl;
    16  			// DOM.content.appendChild(this.DOM.details);
    17  			document.getElementById('tm-wrap').appendChild(this.DOM.details);
    18  			this.init();
    19  		}
    20  		init() {
    21  			this.DOM.bgDown = this.DOM.details.querySelector('.details__bg--down');
    22  			this.DOM.description = this.DOM.details.querySelector('.details__description');
    23  			this.DOM.close = this.DOM.details.querySelector('.details__close');
    24  
    25  			this.initEvents();
    26  		}
    27  		initEvents() {
    28  			// close page when outside of page is clicked.
    29  			document.body.addEventListener('click', () => this.close());
    30  			// prevent close page when inside of page is clicked.
    31  			this.DOM.bgDown.addEventListener('click', function(event) {
    32  							event.stopPropagation();
    33  						});
    34  			// close page when cross button is clicked.
    35  			this.DOM.close.addEventListener('click', () => this.close());
    36  		}
    37  		fill(info) {
    38  			// fill current page info
    39  			this.DOM.description.innerHTML = info.description;
    40  		}
    41  		getProductDetailsRect(){
    42  			var p = 0;
    43  			var d = 0;
    44  
    45  			try {
    46  				p = this.DOM.productBg.getBoundingClientRect();
    47  				d = this.DOM.bgDown.getBoundingClientRect();
    48  			}
    49  			catch(e){}
    50  
    51  			return {
    52  				productBgRect: p,
    53  				detailsBgRect: d
    54  			};
    55  		}
    56  		open(data) {
    57  			if(this.isAnimating) return false;
    58  			this.isAnimating = true;
    59  
    60  			this.DOM.details.style.display = 'block';
    61  
    62  			this.DOM.details.classList.add('details--open');
    63  
    64  			this.DOM.productBg = data.productBg;
    65  
    66  			this.DOM.productBg.style.opacity = 0;
    67  
    68  			const rect = this.getProductDetailsRect();
    69  
    70  			this.DOM.bgDown.style.transform = `translateX(${rect.productBgRect.left-rect.detailsBgRect.left}px) translateY(${rect.productBgRect.top-rect.detailsBgRect.top}px) scaleX(${rect.productBgRect.width/rect.detailsBgRect.width}) scaleY(${rect.productBgRect.height/rect.detailsBgRect.height})`;
    71              this.DOM.bgDown.style.opacity = 1;
    72  
    73              // animate background
    74              anime({
    75                  targets: [this.DOM.bgDown],
    76                  duration: (target, index) => index ? 800 : 250,
    77                  easing: (target, index) => index ? 'easeOutElastic' : 'easeOutSine',
    78                  elasticity: 250,
    79                  translateX: 0,
    80                  translateY: 0,
    81                  scaleX: 1,
    82                  scaleY: 1,
    83                  complete: () => this.isAnimating = false
    84              });
    85  
    86              // animate content
    87              anime({
    88                  targets: [this.DOM.description],
    89                  duration: 1000,
    90                  easing: 'easeOutExpo',
    91                  translateY: ['100%',0],
    92                  opacity: 1
    93              });
    94  
    95              // animate close button
    96              anime({
    97                  targets: this.DOM.close,
    98                  duration: 250,
    99                  easing: 'easeOutSine',
   100                  translateY: ['100%',0],
   101                  opacity: 1
   102              });
   103  
   104              this.setCarousel();
   105  
   106              window.addEventListener("resize", this.setCarousel);
   107  		}
   108  		close() {
   109  			if(this.isAnimating) return false;
   110  			this.isAnimating = true;
   111  
   112  			this.DOM.details.classList.remove('details--open');
   113  
   114  			anime({
   115                  targets: this.DOM.close,
   116                  duration: 250,
   117                  easing: 'easeOutSine',
   118                  translateY: '100%',
   119                  opacity: 0
   120              });
   121  
   122              anime({
   123                  targets: [this.DOM.description],
   124                  duration: 20,
   125                  easing: 'linear',
   126                  opacity: 0
   127              });
   128  
   129              const rect = this.getProductDetailsRect();
   130              anime({
   131                  targets: [this.DOM.bgDown],
   132                  duration: 250,
   133                  easing: 'easeOutSine',
   134                  translateX: (target, index) => {
   135                      return index ? rect.productImgRect.left-rect.detailsImgRect.left : rect.productBgRect.left-rect.detailsBgRect.left;
   136                  },
   137                  translateY: (target, index) => {
   138                      return index ? rect.productImgRect.top-rect.detailsImgRect.top : rect.productBgRect.top-rect.detailsBgRect.top;
   139                  },
   140                  scaleX: (target, index) => {
   141                      return index ? rect.productImgRect.width/rect.detailsImgRect.width : rect.productBgRect.width/rect.detailsBgRect.width;
   142                  },
   143                  scaleY: (target, index) => {
   144                      return index ? rect.productImgRect.height/rect.detailsImgRect.height : rect.productBgRect.height/rect.detailsBgRect.height;
   145                  },
   146                  complete: () => {
   147                      this.DOM.bgDown.style.opacity = 0;
   148                      this.DOM.bgDown.style.transform = 'none';
   149                      this.DOM.productBg.style.opacity = 1;
   150                      this.DOM.details.style.display = 'none';
   151                      this.isAnimating = false;
   152                  }
   153              });
   154  		}
   155  		// Slick Carousel
   156          setCarousel() {
   157  
   158  	        var slider = $('.details .tm-img-slider');
   159  
   160  	        if(slider.length) { // check if slider exist
   161  
   162  		        if (slider.hasClass('slick-initialized')) {
   163  		            slider.slick('destroy');
   164  		        }
   165  
   166  		        if($(window).width() > 767){
   167  		            // Slick carousel
   168  		            slider.slick({
   169  		                dots: true,
   170  		                infinite: true,
   171  		                slidesToShow: 4,
   172  		                slidesToScroll: 3
   173  		            });
   174  		        }
   175  		        else {
   176  		            slider.slick({
   177  			            dots: true,
   178  			            infinite: true,
   179  			            slidesToShow: 2,
   180  			            slidesToScroll: 1
   181  		        	});
   182  		     	}
   183  	        }
   184          }
   185  	}; // class Details
   186  
   187  	class Item {
   188  		constructor(el) {
   189  			this.DOM = {};
   190  			this.DOM.el = el;
   191  			this.DOM.product = this.DOM.el.querySelector('.product');
   192  			this.DOM.productBg = this.DOM.product.querySelector('.product__bg');
   193  
   194  			this.info = {
   195  				description: this.DOM.product.querySelector('.product__description').innerHTML
   196  			};
   197  
   198  			this.initEvents();
   199  		}
   200  		initEvents() {
   201  			this.DOM.product.addEventListener('click', () => this.open());
   202  		}
   203  		open() {
   204  			DOM.details.fill(this.info);
   205  			DOM.details.open({
   206  				productBg: this.DOM.productBg
   207  			});
   208  		}
   209  	}; // class Item
   210  
   211  	const DOM = {};
   212  	DOM.grid = document.querySelector('.grid');
   213  	DOM.content = DOM.grid.parentNode;
   214  	DOM.gridItems = Array.from(DOM.grid.querySelectorAll('.grid__item'));
   215  	let items = [];
   216  	DOM.gridItems.forEach(item => items.push(new Item(item)));
   217  
   218  	DOM.details = new Details();
   219  };
   220  
   221