Touch to Zoom
Working on a Linux t-shirts e-commerce, I added a simple "hover-to-zoom" feature on the main image displayed in each product's page (this one, for example): it is possible to just hover the mouse cursor to obtain a larger image, which moves accordingly to the mouse movements. Nothing new, here: it is a quite common behavior in many stores.
The problem arises on mobile, where no hover
event is triggered by any mouse cursor. But after some experiment, I ended up to implement mostly the same effect using the pressed finger as a cursor: while you touch the image, a larger version is displayed (as when hovered); when you move the finger (keeping it touched), the alternative larger image moves accordingly.
Probably this is not the best solution possible, as it is barely discoverable by the user, but I like it and want to share here the proper code to reproduce.
In HTML:
<figure class="zoom" style="background-image: url(/images/larger.png)">
<img class="shirt-cover" src="/images/normal.png">
</figure>
In SCSS:
figure.zoom {
position: relative;
overflow: hidden;
cursor: zoom-in;
img {
transition: opacity 0.5s;
display: block;
width: 100%;
&:hover {
opacity: 0;
}
}
}
In JS:
/***********************************************************************
Desktop
*/
$('.zoom').on('mousemove', (e) => {
e.preventDefault();
let zoomer = e.currentTarget;
let offsetX = e.offsetX ? e.offsetX : e.touches[0].pageX;
let offsetY = e.offsetY ? e.offsetY : e.touches[0].pageX;
let x = offsetX / zoomer.offsetWidth * 100;
let y = offsetY / zoomer.offsetHeight * 100;
zoomer.style.backgroundPosition = x + '% ' + y + '%';
});
/***********************************************************************
Mobile
*/
$('.zoom').on('touchmove', (e) => {
e.preventDefault();
let zoomer = e.currentTarget;
let offsetX = e.offsetX ? e.offsetX : e.touches[0].pageX;
let offsetY = e.offsetY ? e.offsetY : e.touches[0].pageY;
let x = offsetX / zoomer.offsetWidth * 100;
let y = offsetY / zoomer.offsetHeight * 100;
zoomer.style.backgroundPosition = x + '% ' + y + '%';
});
$('.zoom').on('touchstart', (e) => {
$(e.currentTarget).find('img').css('opacity', 0);
});
$('.zoom').on('touchend', (e) => {
$(e.currentTarget).find('img').css('opacity', 1);
});
When on desktop, the "normal" image is properly hidden by the native :hover
modifier in CSS and the mousemove
JS event provides the figure
background movements. When on mobile, the "normal" image is hidden or displayed due JS events of touch
start and end and the rest of interaction happens on touchmove
events.