js扑克堆叠式卡片轮播图插件

当前位置:主页 > jQuery库 > 幻灯片和轮播图 > js扑克堆叠式卡片轮播图插件
js扑克堆叠式卡片轮播图插件
分享:

    插件介绍

    这是一款js扑克堆叠式卡片轮播图插件。高轮播图的所有图片像扑克牌一样堆叠在一起,通过鼠标拖拽最上面的一张图片,就可以显示出下一张图片来。

    浏览器兼容性

    浏览器兼容性
    时间:10-30
    阅读:
简要教程

这是一款js扑克堆叠式卡片轮播图插件。高轮播图的所有图片像扑克牌一样堆叠在一起,通过鼠标拖拽最上面的一张图片,就可以显示出下一张图片来。

使用方法

在HTML文件中引入。

  
<script src="//code.jquery.com/hammer.min.js"></script>  
                
HTML结构
<div id="board"></div>
                
初始化插件

然后通过下面的代码来初始化插件。

class Carousel {
  
  constructor(element) {
    
    this.board = element
    
    // add first two cards programmatically
    this.push()
    this.push()
    
    // handle gestures
    this.handle()
    
  }
  
  handle() {
    
    // list all cards
    this.cards = this.board.querySelectorAll('.card')
    
    // get top card
    this.topCard = this.cards[this.cards.length-1]
    
    // get next card
    this.nextCard = this.cards[this.cards.length-2]
    
    // if at least one card is present
    if (this.cards.length > 0) {
      
      // set default top card position and scale
      this.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(1)'
      
      // destroy previous Hammer instance, if present
      if (this.hammer) this.hammer.destroy()
      
      // listen for tap and pan gestures on top card
      this.hammer = new Hammer(this.topCard)
      this.hammer.add(new Hammer.Tap())
      this.hammer.add(new Hammer.Pan({ position: Hammer.position_ALL, threshold: 0 }))
      
      // pass events data to custom callbacks
      this.hammer.on('tap', (e) => { this.onTap(e) })
      this.hammer.on('pan', (e) => { this.onPan(e) })
      
    }
    
  }
  
  onTap(e) {
    
    // get finger position on top card
    let propX = (e.center.x - e.target.getBoundingClientRect().left) / e.target.clientWidth
    
    // get degree of Y rotation (+/-15 degrees)
    let rotateY = 15 * (propX < 0.05 ? -1 : 1)
    
    // change the transition property
    this.topCard.style.transition = 'transform 100ms ease-out'
    
    // rotate
    this.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(' + rotateY + 'deg) scale(1)'
    
    // wait transition end
    setTimeout(() => {
      // reset transform properties
      this.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(1)'
    }, 100)
    
  }
  
  onPan(e) {
    
    if (!this.isPanning) {
      
      this.isPanning = true
      
      // remove transition properties
      this.topCard.style.transition = null
      if (this.nextCard) this.nextCard.style.transition = null
      
      // get top card coordinates in pixels
      let style = window.getComputedStyle(this.topCard)
      let mx = style.transform.match(/^matrix\((.+)\)$/)
      this.startPosX = mx ? parseFloat(mx[1].split(', ')[4]) : 0
      this.startPosY = mx ? parseFloat(mx[1].split(', ')[5]) : 0
      
      // get top card bounds
      let bounds = this.topCard.getBoundingClientRect()
      
      // get finger position on top card, top (1) or bottom (-1)
      this.isDraggingFrom = (e.center.y - bounds.top) > this.topCard.clientHeight / 2 ? -1 : 1
      
    }
    
    // calculate new coordinates
    let posX = e.deltaX + this.startPosX
    let posY = e.deltaY + this.startPosY
    
    // get ratio between swiped pixels and the axes
    let propX = e.deltaX / this.board.clientWidth
    let propY = e.deltaY / this.board.clientHeight
    
    // get swipe direction, left (-1) or right (1)
    let dirX = e.deltaX < 0 ? -1 : 1
    
    // calculate rotation, between 0 and +/- 45 deg
    let deg = this.isDraggingFrom * dirX * Math.abs(propX) * 45
    
    // calculate scale ratio, between 95 and 100 %
    let scale = (95 + (5 * Math.abs(propX))) / 100
    
    // move top card
    this.topCard.style.transform = 'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg) rotateY(0deg) scale(1)'
    
    // scale next card
    if (this.nextCard) this.nextCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(' + scale + ')'
    
    if (e.isFinal) {
      
      this.isPanning = false
      
      let successful = false
      
      // set back transition properties
      this.topCard.style.transition = 'transform 200ms ease-out'
      if (this.nextCard) this.nextCard.style.transition = 'transform 100ms linear'
      
      // check threshold
      if (propX > 0.25 && e.direction == Hammer.DIRECTION_RIGHT) {
    
        successful = true
        // get right border position
        posX = this.board.clientWidth
     
      } else if (propX < -0.25 && e.direction == Hammer.DIRECTION_LEFT) {
    
        successful = true
        // get left border position
        posX = - (this.board.clientWidth + this.topCard.clientWidth)
     
      } else if (propY < -0.25 && e.direction == Hammer.DIRECTION_UP) {
    
        successful = true
        // get top border position
        posY = - (this.board.clientHeight + this.topCard.clientHeight)
    
      }
      
      if (successful) {
  
        // throw card in the chosen direction
        this.topCard.style.transform = 'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg)'
      
        // wait transition end
        setTimeout(() => {
          // remove swiped card
          this.board.removeChild(this.topCard)
          // add new card
          this.push()
          // handle gestures on new top card
          this.handle()
        }, 200)
      
      } else {
    
        // reset cards position
        this.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(1)'
        if (this.nextCard) this.nextCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(0.95)'
    
      }
  
    }
    
  }
  
  push() {
    
    let card = document.createElement('div')
    
    card.classList.add('card')

    // add you own content to the cards
    
    if (this.board.firstChild) {
      this.board.insertBefore(card, this.board.firstChild)
    } else {
      this.board.append(card)
    }
    
  }
  
}
                

该js扑克堆叠式卡片轮播图插件的github网址为:https://github.com/simonepm/likecarousel