JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<img id="test" src="https://images.unsplash.com/photo-1624268450274-84f420bc9e70?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=934&q=80">
CSS
#test {
position: absolute;
transform-origin: 0 0;
transition: transform 330ms ease-in-out;
}
JavaScript
const img = document.getElementById("test");
let currentScale = 1;
let translateX = 0
let translateY = 0
const factor = 1
const zoom = (nextScale, event) => {
const ratio = 1 - nextScale / currentScale
const {
clientX,
clientY
} = event
translateX += (clientX - translateX) * ratio
translateY += (clientY - translateY) * ratio
img.style.transform = `translate(${translateX}px, ${translateY}px) scale(${nextScale})`
currentScale = nextScale
}
const zoomDebounce = _.debounce(zoom, 30)
const onWheel = e => {
e.preventDefault()
const delta = e.deltaY / 5
const nextScale = currentScale + delta * factor
zoomDebounce(nextScale, e)
}
window.addEventListener('wheel', onWheel, {
passive: false
})