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

<script src="//code.jquery.com/hammer.min.js"></script>
<div id="board"></div>
然后通过下面的代码来初始化插件。
class Carousel {
constructor(element) {
this.board = element
// add first two cards programmaticallythis.push()
this.push()
// handle gesturesthis.handle()
}handle() {
// list all cardsthis.cards = this.board.querySelectorAll('.card')
// get top cardthis.topCard = this.cards[this.cards.length-1]
// get next cardthis.nextCard = this.cards[this.cards.length-2]
// if at least one card is presentif (this.cards.length > 0) {
// set default top card position and scalethis.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(1)'
// destroy previous Hammer instance, if presentif (this.hammer) this.hammer.destroy()
// listen for tap and pan gestures on top cardthis.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 callbacksthis.hammer.on('tap', (e) => { this.onTap(e) })
this.hammer.on('pan', (e) => { this.onPan(e) })
} }onTap(e) {
// get finger position on top cardlet 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 propertythis.topCard.style.transition = 'transform 100ms ease-out'
// rotatethis.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(' + rotateY + 'deg) scale(1)'
// wait transition endsetTimeout(() => {
// reset transform propertiesthis.topCard.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg) rotateY(0deg) scale(1)'
}, 100)
}onPan(e) {
if (!this.isPanning) {
this.isPanning = true
// remove transition propertiesthis.topCard.style.transition = null
if (this.nextCard) this.nextCard.style.transition = null
// get top card coordinates in pixelslet 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 boundslet 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 coordinateslet posX = e.deltaX + this.startPosX
let posY = e.deltaY + this.startPosY
// get ratio between swiped pixels and the axeslet 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 deglet 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 cardthis.topCard.style.transform = 'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg) rotateY(0deg) scale(1)'
// scale next cardif (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 propertiesthis.topCard.style.transition = 'transform 200ms ease-out'
if (this.nextCard) this.nextCard.style.transition = 'transform 100ms linear'
// check thresholdif (propX > 0.25 && e.direction == Hammer.DIRECTION_RIGHT) {
successful = true
// get right border positionposX = this.board.clientWidth
} else if (propX < -0.25 && e.direction == Hammer.DIRECTION_LEFT) {
successful = true
// get left border positionposX = - (this.board.clientWidth + this.topCard.clientWidth)
} else if (propY < -0.25 && e.direction == Hammer.DIRECTION_UP) {
successful = true
// get top border positionposY = - (this.board.clientHeight + this.topCard.clientHeight)
}if (successful) {
// throw card in the chosen directionthis.topCard.style.transform = 'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg)'
// wait transition endsetTimeout(() => {
// remove swiped cardthis.board.removeChild(this.topCard)
// add new cardthis.push()
// handle gestures on new top cardthis.handle()
}, 200)
} else {
// reset cards positionthis.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 cardsif (this.board.firstChild) {
this.board.insertBefore(card, this.board.firstChild)
} else {
this.board.append(card)
} }}Github 网址:https://github.com/simonepm/likecarousel
| 演示地址 | 下载地址 |
专业提供WordPress主题安装、深度汉化、加速优化等各类网站建设服务,详询在线客服!
