I have the following code which can swipe child element left and right. This works well.
Is there a way I could implement snap effect with this somehow with pointermove? So it behaves like CSS snap scroll (you drag slightly and you can see next / previous item entering, before swipe actually happens).
I dont want to use CSS snap scroll because I cannot detect scrollend event (on Safari for start) so I cannot detect on which child I am currenty (I need this so I can show / hide previous / next buttons, numbering etc)
var wrap = document.querySelector('.wrap'),
touchstartX,
touchendX
wrap.addEventListener('pointerdown', startHorizSwipeDirection);
document.addEventListener('pointerup', endHorizSwipeDirection);
function startHorizSwipeDirection(e) {
touchstartX = e.clientX;
}
function endHorizSwipeDirection(e) {
touchendX = e.clientX;
checkHorizSwipeDirection()
}
function checkHorizSwipeDirection() {
if (touchendX < touchstartX - 100) {
//left
nextHorizMedia();
}
if (touchendX > touchstartX + 100) {
//right
previousHorizMedia();
}
}
function nextHorizMedia() {
var active_id = parseInt(wrap.getAttribute('data-active-id'), 10),
len = wrap.querySelectorAll('.child').length
if (active_id >= len - 1) {
console.log('end')
return false;
}
var width = wrap.querySelector('.child').offsetWidth
var transform = wrap.style.transform.replace(/[^-?d.]/g, '')
var value
if (transform) value = parseInt(transform, 10)
else value = 0;
value -= width;
active_id++;
wrap.setAttribute('data-active-id', active_id)
wrap.style.transform = "translateX(" + value + "px)";
}
function previousHorizMedia() {
var active_id = parseInt(wrap.getAttribute('data-active-id'), 10),
len = wrap.querySelectorAll('.child').length
if (active_id <= 0) {
return false;
}
var width = wrap.querySelector('.child').offsetWidth
var transform = wrap.style.transform.replace(/[^-?d.]/g, '')
var value
if (transform) value = parseInt(transform, 10)
else value = 0;
value += width;
active_id--;
wrap.setAttribute('data-active-id', active_id)
wrap.style.transform = "translateX(" + value + "px)";
}
.parent {
width: 300px;
height: 100px;
overflow: hidden;
}
.wrap {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
transition: transform 0.3s;
}
.child {
width: 300px;
height: 100px;
font-size: 30px;
color: #fff;
background: #ccc;
flex-shrink: 0;
text-align: center;
user-select: none;
}
.child[data-id="0"] {
background: red;
}
.child[data-id="1"] {
background: blue;
}
.child[data-id="2"] {
background: green;
}
.child[data-id="3"] {
background: #ccc;
}
<div class="parent">
<div class="wrap" data-active-id="0">
<div class="child" data-id="0">0</div>
<div class="child" data-id="1">1</div>
<div class="child" data-id="2">2</div>
<div class="child" data-id="3">3</div>
</div>
</div>