يوم جيد يا اصدقاء! قررت العودة إلى موضوع المنزلق. هذه المقالة بمثابة الإلهام . توجد مقالة حول منشئ معرض الصور مع شريط تمرير مضمن هنا .يعمل شريط التمرير الذي نكتبه على مبدأ مجموعة بطاقات لا نهاية لها أو مجموعة من الصور. يتم تجاهل الصورة العلوية في أحد الاتجاهات الثلاثة - يسارًا أو يمينًا أو لأعلى. يتم استبدال الصورة المهملة بما يلي ، وهكذا إلى ما لا نهاية. يمكنك تحميل صورك أو استخدام الصور الافتراضية.لتسجيل الإيماءات (اللمسات) والتحريك (السحب والإسقاط) يستخدم مطرقة js . تتيح لك هذه المكتبة اكتشاف كل من نقرات الماوس ولمسات الأصابع.إذن هيا بنا نذهب.يبدو الترميز كالتالي:<input type="file" multiple>
<button>build carousel</button>
<div></div>
لدينا "إدخال" لتحميل الصور وزر لإنشاء رف دائري وحاوية للبطاقات.أضف بعض الأنماط: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);
}
لا يوجد شيء مميز هنا: الصور بعرض 320 بكسل ، تتمركز فوق بعضها البعض.ننتقل إلى شبيبة. سوف أعطي الرمز بالكامل. لا تخف من عدد الخطوط ، كل شيء بسيط للغاية ، ربما باستثناء حساب المواضع والإحداثيات. تقريبا كل سطر لديه تعليق.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)
}
}
}
→ جيثبشكرا لكم على اهتمامكم.