A Pen by Teja Babu S on CodePen.
Created
January 22, 2019 19:11
-
-
Save mightyteja/e511650e792fd30913af83aa9038878e to your computer and use it in GitHub Desktop.
Hammer JS Pinch Pan Zoom Image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="imageContainer"></div> | |
<div id="hud"></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const imageUrl = 'https://source.unsplash.com/random'; | |
const imageContainer = document.querySelector('.imageContainer'); | |
const hud = document.querySelector('#hud'); | |
let minScale = 1; | |
let maxScale = 4; | |
let imageWidth; | |
let imageHeight; | |
let containerWidth; | |
let containerHeight; | |
let displayImageX = 0; | |
let displayImageY = 0; | |
let displayImageScale = 1; | |
let displayDefaultWidth; | |
let displayDefaultHeight; | |
let rangeX = 0; | |
let rangeMaxX = 0; | |
let rangeMinX = 0; | |
let rangeY = 0; | |
let rangeMaxY = 0; | |
let rangeMinY = 0; | |
let displayImageRangeY = 0; | |
let displayImageCurrentX = 0; | |
let displayImageCurrentY = 0; | |
let displayImageCurrentScale = 1; | |
function resizeContainer() { | |
containerWidth = imageContainer.offsetWidth; | |
containerHeight = imageContainer.offsetHeight; | |
if (displayDefaultWidth !== undefined && displayDefaultHeight !== undefined) { | |
displayDefaultWidth = displayImage.offsetWidth; | |
displayDefaultHeight = displayImage.offsetHeight; | |
updateRange(); | |
displayImageCurrentX = clamp( displayImageX, rangeMinX, rangeMaxX ); | |
displayImageCurrentY = clamp( displayImageY, rangeMinY, rangeMaxY ); | |
updateDisplayImage( | |
displayImageCurrentX, | |
displayImageCurrentY, | |
displayImageCurrentScale ); | |
} | |
} | |
resizeContainer(); | |
function clamp(value, min, max) { | |
return Math.min(Math.max(min, value), max); | |
} | |
function clampScale(newScale) { | |
return clamp(newScale, minScale, maxScale); | |
} | |
window.addEventListener('resize', resizeContainer, true); | |
const displayImage = new Image(); | |
displayImage.src = imageUrl; | |
displayImage.onload = function(){ | |
imageWidth = displayImage.width; | |
imageHeight = displayImage.height; | |
imageContainer.appendChild(displayImage); | |
displayImage.addEventListener('mousedown', e => e.preventDefault(), false); | |
displayDefaultWidth = displayImage.offsetWidth; | |
displayDefaultHeight = displayImage.offsetHeight; | |
rangeX = Math.max(0, displayDefaultWidth - containerWidth); | |
rangeY = Math.max(0, displayDefaultHeight - containerHeight); | |
} | |
imageContainer.addEventListener('wheel', e => { | |
displayImageScale = displayImageCurrentScale = clampScale(displayImageScale + (e.wheelDelta / 800)); | |
updateRange(); | |
displayImageCurrentX = clamp(displayImageCurrentX, rangeMinX, rangeMaxX) | |
displayImageCurrentY = clamp(displayImageCurrentY, rangeMinY, rangeMaxY) | |
updateDisplayImage(displayImageCurrentX, displayImageCurrentY, displayImageScale); | |
}, false); | |
function updateDisplayImage(x, y, scale) { | |
const transform = 'translateX(' + x + 'px) translateY(' + y + 'px) translateZ(0px) scale(' + scale + ',' + scale + ')'; | |
displayImage.style.transform = transform; | |
displayImage.style.WebkitTransform = transform; | |
displayImage.style.msTransform = transform; | |
updateHud(); | |
} | |
function updateRange() { | |
rangeX = Math.max(0, Math.round(displayDefaultWidth * displayImageCurrentScale) - containerWidth); | |
rangeY = Math.max(0, Math.round(displayDefaultHeight * displayImageCurrentScale) - containerHeight); | |
rangeMaxX = Math.round(rangeX / 2); | |
rangeMinX = 0 - rangeMaxX; | |
rangeMaxY = Math.round(rangeY / 2); | |
rangeMinY = 0 - rangeMaxY; | |
} | |
function updateHud() { | |
let hudText = `<pre> | |
<b>Current</b> | |
<b>Scale:</b> ${displayImageCurrentScale.toFixed(4)} | |
<b>X:</b> ${displayImageCurrentX} | |
<b>Y:</b> ${displayImageCurrentY} | |
<b>Range</b> | |
<b>rangeX:</b> ${rangeX} | |
<b>rangeMinX:</b> ${rangeMinX} | |
<b>rangeMaxX:</b> ${rangeMaxX} | |
<b>rangeY:</b> ${rangeY} | |
<b>rangeMinY:</b> ${rangeMinY} | |
<b>rangeMaxY:</b> ${rangeMaxY} | |
<b>Updated</b> | |
<b>Scale:</b> ${displayImageScale.toFixed(4)} | |
<b>X:</b> ${displayImageX} | |
<b>Y:</b> ${displayImageY} | |
</pre>`; | |
hud.innerHTML = hudText; | |
} | |
const hammertime = new Hammer(imageContainer); | |
hammertime.get('pinch').set({ enable: true }); | |
hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL }); | |
hammertime.on('pan', ev => { | |
displayImageCurrentX = clamp(displayImageX + ev.deltaX, rangeMinX, rangeMaxX); | |
displayImageCurrentY = clamp(displayImageY + ev.deltaY, rangeMinY, rangeMaxY); | |
updateDisplayImage(displayImageCurrentX, displayImageCurrentY, displayImageScale); | |
}); | |
hammertime.on('pinch pinchmove', ev => { | |
displayImageCurrentScale = clampScale(ev.scale * displayImageScale); | |
updateRange(); | |
displayImageCurrentX = clamp(displayImageX + ev.deltaX, rangeMinX, rangeMaxX); | |
displayImageCurrentY = clamp(displayImageY + ev.deltaY, rangeMinY, rangeMaxY); | |
updateDisplayImage(displayImageCurrentX, displayImageCurrentY, displayImageCurrentScale); | |
}); | |
hammertime.on('panend pancancel pinchend pinchcancel', () => { | |
displayImageScale = displayImageCurrentScale; | |
displayImageX = displayImageCurrentX; | |
displayImageY = displayImageCurrentY; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.imageContainer { | |
width: 96%; | |
height: 96%; | |
max-width: 800px; | |
max-height: 600px; | |
position: absolute; | |
overflow: hidden; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
margin: auto; | |
background: #2b2b2c; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
} | |
.imageContainer > img { | |
display: block; | |
max-width:100%; | |
max-height:100%; | |
cursor: move; | |
touch-action: none; | |
} | |
#hud { | |
background: rgba(0,0,0,0.6); | |
position: absolute; | |
padding: 10px 20px; | |
color: #FFF; | |
font-family: sans-serif; | |
font-size: 1.2em; | |
pointer-events: none; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment