Update #2 Wow, transition was stuck at .35s. My CSS just wasn't updating properly :(
UPDATE: Anyone know if requestAnimationFrame could help with this?
I've got a rotating image reel and I want users to be able to swipe left or right to switch to the next or previous image (rotating through all images in the set).
To achieve this, I'm using the touchmove
event and the css property transform: translate
to move the image, making the swiping action responsive to touch.
Specifically, between the firing of touchstart
and touchend
, the touchmove
event is used to visually move the image so that users can see it responding. However, it's moving pretty slowly. How can I make it more responsive?
Here's my code snippet:
!(function () {
"use strict"
window.addEventListener('load', function (event) {
var modules = document.querySelectorAll('a.module')
var interval
// This function rotates the modules every 7500 milliseconds.
function initiateInterval () {
interval = setInterval(function () {
modules.forEach(function (module) {
rotateToNext(module)
})
}, 2500)
}
initiateInterval() // Kick things off on page load.
//Be ready to manually switch things on click.
modules.forEach(function (module) {
module.addEventListener('click', (event) => switchToManual(module) )
})
// Disable clicking while adjusting manually.
// Then reinitiate the iterval and enable clicking again.
function switchToManual (module) {
disableButtons()
clearInterval(interval)
cycleTargetToCenter(module, function () {
initiateInterval()
enableButtons()
})
}
// Rotate on swipe left or right.
modules.forEach(function (module) {
var startPoint
var endPoint
module.addEventListener('touchstart', function (event) {
disableButtons()
clearInterval(interval)
return startPoint = event.changedTouches[0].screenX
})
module.addEventListener('touchmove', function (event) {
module.style.transform = `translate(${(event.changedTouches[0].screenX - startPoint)}px ,0px)`
})
module.addEventListener('touchend', function (event) {
module.style.transform = ''
endPoint = event.changedTouches[0].screenX
if (endPoint > startPoint + 70) modules.forEach( (mod) => rotateToNext(mod) )
if (endPoint < startPoint - 70) modules.forEach( (mod) => rotateToPrevious(mod) )
initiateInterval()
enableButtons()
})
})
function disableButtons () {
modules.forEach(function (module) {
module.setAttribute('disabled', 'disabled')
})
}
function enableButtons () {
modules.forEach(function (module) {
module.removeAttribute('disabled')
})
}
function cycleTargetToCenter (module, func) {
var currentPosition = decernCurrentPosition(module)
if (currentPosition === 'position3') {
return func()
} else {
var spins = decernNumberOfNeededRotations(module)
for (let i = 0; i < spins; i += 1) {
modules.forEach( (mod) => rotateToNext(mod) )
}
return func()
}
}
function rotateToNext (module) {
var currentPosition = decernCurrentPosition(module)
var nextPosition = decernNextPosition(module)
module.classList.remove(currentPosition)
module.classList.add(nextPosition)
}
function rotateToPrevious (module) {
var currentPosition = decernCurrentPosition(module)
var previousPosition = decernPreviousPosition(module)
module.classList.remove(currentPosition)
module.classList.add(previousPosition)
}
function decernCurrentPosition (module) {
if (module.classList.contains('position1')) return 'position1'
if (module.classList.contains('position2')) return 'position2'
if (module.classList.contains('position3')) return 'position3'
if (module.classList.contains('position4')) return 'position4'
if (module.classList.contains('position5')) return 'position5'
}
function decernNextPosition (module) {
if (module.classList.contains('position1')) return 'position2'
if (module.classList.contains('position2')) return 'position3'
if (module.classList.contains('position3')) return 'position4'
if (module.classList.contains('position4')) return 'position5'
if (module.classList.contains('position5')) return 'position1'
}
function decernPreviousPosition (module) {
if (module.classList.contains('position1')) return 'position5'
if (module.classList.contains('position2')) return 'position1'
if (module.classList.contains('position3')) return 'position2'
if (module.classList.contains('position4')) return 'position3'
if (module.classList.contains('position5')) return 'position4'
}
function decernNumberOfNeededRotations (module) {
if (module.classList.contains('position1')) return 2
if (module.classList.contains('position2')) return 1
if (module.classList.contains('position4')) return 4
if (module.classList.contains('position5')) return 3
}
})
}());
.modules {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
overflow-x: hidden;
height: 500px;
}
.module {
font-weight: normal;
position: absolute;
top: 5em;
display: flex;
justify-content: center;
text-align: center;
width: 295px;
height: 295px;
flex-shrink: 0;
margin: 1em;
transition: 1s;
}
.module div.icon {
position: absolute;
left: 50%;
margin-left: -45px;
top: -45px;
display: flex;
justify-content: center;
align-items: center;
width: 90px;
height: 90px;
flex-shrink: 0;
background: #fff;
border-radius: 50%;
}
.module div.copy {
padding: 42px 2em 2em 2em;
background: #fff;
border-radius: 1em;
}
.module div.copy h2 {
font-size: 2em;
margin: 0;
}
.module div.copy h2 p.subtitle {
font-size: 0.65em;
}
.module.position1 {
z-index: 1;
transform: scale(0.6) translate(-270px, -90px);
filter: drop-shadow(0 0 8px #bababa);
}
.module.position2 {
z-index: 3;
transform: scale(0.8) translate(-400px, -10px);
filter: drop-shadow(0 0 12px #bababa);
}
.module.position3 {
z-index: 3;
transform: scale(1);
filter: drop-shadow(0 0 18px #bababa);
}
.module.position4 {
z-index: 2;
transform: scale(0.8) translate(400px, -10px);
filter: drop-shadow(0 0 12px #bababa);
}
.module.position5 {
z-index: 1;
transform: scale(0.6) translate(270px, -90px);
filter: drop-shadow(0 0 8px #bababa);
}
<section class="modules"><a class="module module1 position1">
<div class="icon">
<h2>๐ก</h2>
</div>
<div class="copy">
<h2>Bulbs
<p class="subtitle">How many light bulbs?</p>
</h2>
<p>La la la...</p>
</div></a><a class="module module2 position2">
<div class="icon">
<h2>๐จ๏ธ</h2>
</div>
<div class="copy">
<h2>Words
<p class="subtitle">How many words?</p>
</h2>
<p>La la la</p>
</div></a><a class="module module3 position3">
<div class="icon">
<h2>๐ค</h2>
</div>
<div class="copy">
<h2>Queries
<p class="subtitle">How many queries?</p>
</h2>
<p>La la la...</p>
</div></a><a class="module module4 position4">
<div class="icon">
<h2>๐งช</h2>
</div>
<div class="copy">
<h2>Tubes
<p class="subtitle">Quantas Tubes?</p>
</h2>
<p>La la la...</p>
</div></a><a class="module module5 position5">
<div class="icon">
<h2>๐คธ</h2>
</div>
<div class="copy">
<h2>Actions
<p class="subtitle">And this too...?</p>
</h2>
<p>La la la...</p>
</div></a></section>
The touch events are really sluggish โ you slide your finger and the object seems to lag behind rather than follow smoothly. What could be causing this delay?