Этого можно добиться, используя события mouseover и mouseout вместе с несколькими атрибутами данных.
const cycleRate = 0.5 // 500ms
let processId = null
const handleStart = e => {
const carousel = document.querySelector('.carousel')
const img = carousel.querySelector('img')
const defaultImage = e.target.getAttribute('src')
const images = JSON.parse(e.target.dataset.hoverImages)
let currentId = parseInt(e.target.dataset.hoverId, 10)
images.unshift(defaultImage) // Add target src to front
carousel.classList.toggle('carousel-hidden', false)
carousel.style.left = e.clientX + 'px'
carousel.style.top = e.clientY + 'px'
img.setAttribute('src', images[currentId])
currentId = (currentId + 1) % images.length
processId = setInterval(() => {
img.setAttribute('src', images[currentId])
currentId = (currentId + 1) % images.length
// Save the current image id
e.target.dataset.hoverId = currentId
}, Math.max(cycleRate * 1000, 1))
}
const handleEnd = e => {
const carousel = document.querySelector('.carousel')
carousel.classList.toggle('carousel-hidden', true)
clearInterval(processId)
processId = null
}
const responsiveImages = document.querySelectorAll('.responsive-img')
Array.from(responsiveImages).forEach(responsiveImage => {
responsiveImage.addEventListener('mouseover', handleStart)
responsiveImage.addEventListener('mouseout', handleEnd)
})
.carousel {
position: absolute;
top: 0;
left: 0;
z-index: 100;
background: white;
border: thin solid grey;
padding: 4px;
}
.carousel-hidden {
display: none;
}
<div class="card-image" id="thumb_image">
<a href="watch.php?v=158">
<img id="mainthumb" src="https://via.placeholder.com/160.png/09f/fff?text=Main"
class="responsive-img"
data-hover-images='[
"https://via.placeholder.com/160.png/f90/fff?text=Alt+1",
"https://via.placeholder.com/160.png/ff0/000?text=Alt+2",
"https://via.placeholder.com/160.png/0f9/000?text=Alt+3"
]'
data-hover-id="0">
<div id="duration">
<span class="white-text">00:04</span>
</div>
</a>
</div>
<div class="carousel carousel-hidden"><img /></div>