Selamat siang teman! Saya memutuskan untuk kembali ke topik slider. Artikel ini menjadi inspirasi . Artikel tentang generator galeri gambar dengan bilah geser internal ada di sini .Slider yang akan kita tulis bekerja berdasarkan prinsip tumpukan kartu tanpa akhir atau setumpuk gambar. Gambar atas dibuang di salah satu dari tiga arah - kiri, kanan, atau atas. Gambar yang dibuang diganti dengan yang berikut, dan seterusnya hingga tak terbatas. Anda dapat mengunggah gambar Anda atau menggunakan gambar default.Untuk mendaftarkan gerakan (menyentuh) dan bergerak (seret dan lepaskan) hammer.js digunakan . Perpustakaan ini memungkinkan Anda untuk mendeteksi klik mouse dan sentuhan jari.Jadi ayo pergi.Markupnya terlihat seperti ini:<input type="file" multiple>
<button>build carousel</button>
<div></div>
Kami memiliki "input" untuk memuat gambar, tombol untuk membuat korsel dan wadah untuk kartu.Tambahkan beberapa gaya:body {
margin: 0;
overflow: hidden;
}
div {
width: 100%;
height: 100vh;
position: relative;
}
img {
width: 320px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.95);
box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1);
}
Tidak ada yang istimewa di sini: gambar berukuran 320px lebar, berpusat di atas satu sama lain.Kami lolos ke JS. Saya akan memberikan seluruh kode. Jangan takut dengan jumlah garis, semuanya cukup sederhana, kecuali, mungkin, menghitung posisi dan koordinat. Hampir setiap baris memiliki komentar.let button = document.querySelector('button')
let input = document.querySelector('input')
let files
let i = 0
button.addEventListener('click', () => {
files = input.files
document.body.removeChild(input)
document.body.removeChild(button)
let board = document.querySelector('div')
let carousel = new Carousel(board)
})
class Carousel {
constructor(element) {
this.board = element
this.push()
i++
this.push()
this.handle()
}
handle() {
this.cards = this.board.querySelectorAll('img')
this.topCard = this.cards[this.cards.length - 1]
this.nextCard = this.cards[this.cards.length - 2]
if (this.cards.length > 0) {
this.topCard.style.transform =
'translate(-50%, -50%) rotate(0deg) scale(1)'
this.hammer = new Hammer(this.topCard)
this.hammer.add(new Hammer.Tap())
this.hammer.add(new Hammer.Pan({
position: Hammer.position_ALL,
threshold: 0
}))
this.hammer.on('tap', (e) => {
this.onTap(e)
})
this.hammer.on('pan', (e) => {
this.onPan(e)
})
}
}
onTap(e) {
let propX = (e.center.x - e.target.getBoundingClientRect().left) / e.target.clientWidth
let rotateY = 15 * (propX < 0.05 ? -1 : 1)
this.topCard.style.transition = 'transform 100ms ease-out'
this.topCard.style.transform =
'translate(-50%, -50%) rotateX(0deg) rotateY(' + rotateY + 'deg) scale(1)'
setTimeout(() => {
this.topCard.style.transform =
'translate(-50%, -50%) rotate(0deg) scale(1)'
}, 100)
}
onPan(e) {
if (!this.isPanning) {
this.isPanning = true
this.topCard.style.transition = null
if (this.nextCard) this.nextCard.style.transition = null
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
let bounds = this.topCard.getBoundingClientRect()
this.isDraggingFrom =
(e.center.y - bounds.top) > this.topCard.clientHeight / 2 ? -1 : 1
}
let posX = e.deltaX + this.startPosX
let posY = e.deltaY + this.startPosY
let propX = e.deltaX / this.board.clientWidth
let propY = e.deltaY / this.board.clientHeight
let dirX = e.deltaX < 0 ? -1 : 1
let deg = this.isDraggingFrom * dirX * Math.abs(propX) * 45
let scale = (95 + (5 * Math.abs(propX))) / 100
this.topCard.style.transform =
'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg) scale(1)'
if (this.nextCard) this.nextCard.style.transform =
'translate(-50%, -50%) rotate(0deg) scale(' + scale + ')'
if (e.isFinal) {
this.isPanning = false
let successful = false
this.topCard.style.transition = 'transform 200ms ease-out'
if (this.nextCard) this.nextCard.style.transition = 'transform 100ms linear'
if (propX > 0.25 && e.direction == Hammer.DIRECTION_RIGHT) {
successful = true
posX = this.board.clientWidth
} else if (propX < -0.25 && e.direction == Hammer.DIRECTION_LEFT) {
successful = true
posX = -(this.board.clientWidth + this.topCard.clientWidth)
} else if (propY < -0.25 && e.direction == Hammer.DIRECTION_UP) {
successful = true
posY = -(this.board.clientHeight + this.topCard.clientHeight)
}
if (successful) {
this.topCard.style.transform =
'translateX(' + posX + 'px) translateY(' + posY + 'px) rotate(' + deg + 'deg)'
setTimeout(() => {
this.board.removeChild(this.topCard)
i++
if (i === files.length) i = 0
this.push()
this.handle()
}, 200)
} else {
this.topCard.style.transform =
'translate(-50%, -50%) rotate(0deg) scale(1)'
if (this.nextCard) this.nextCard.style.transform =
'translate(-50%, -50%) rotate(0deg) scale(0.95)'
}
}
}
push() {
let card = document.createElement('img')
if (files.length === 0) {
card.src = 'https://picsum.photos/320/320/?random=' +
Math.round(Math.random() * 1000000) +
')'
} else {
card.src = URL.createObjectURL(files[i])
}
if (this.board.firstChild) {
this.board.insertBefore(card, this.board.firstChild)
} else {
this.board.append(card)
}
}
}
β GithubTerima kasih atas perhatian Anda.