I'm trying to create a mobile experience for editing images, imagine a photoshop for mobile, one of the features is zoom & pan, which works except for one thing.
I'm trying to prevent the user from scrolling the image outside the screen boundaries, if he does I simply want to animate the stage back into position
this is the function I use to detect if the image is getting cropped on a border
function getImageBordersCropping(stage, image) {
const stageScale = stage.scale()
const stagePosition = stage.position()
const imgSize = image.size()
const stageWidth = stage.width()
const stageHeight = stage.height()
const imgTopLeft = {
x: stagePosition.x,
y: stagePosition.y,
}
const imgBottomRight = {
x: imgTopLeft.x + imgSize.width * stageScale.x,
y: imgTopLeft.y + imgSize.height * stageScale.y,
}
// Create an object for the borders
let borders = {
top: false,
right: false,
bottom: false,
left: false,
}
// Check each border
if (imgTopLeft.x < 0) borders.left = true // Image extends beyond the left border of the stage
if (imgTopLeft.y < 0) borders.top = true // Image extends beyond the top border of the stage
if (imgBottomRight.x > stageWidth) borders.right = true // Image extends beyond the right border of the stage
if (imgBottomRight.y > stageHeight) borders.bottom = true // Image extends beyond the bottom border of the stage
return borders
}
my pan & zoom feature is totally based of: https://konvajs.org/docs/sandbox/Multi-touch_Scale_Stage.html
my dragEnd:
const onDragEnd = e => {
const stage = e.target.getStage()!
const { left, top, bottom, right } = getImageBordersCropping(
stage,
stage.findOne('.imageElement')!
)
let newX = stage.x()
let newY = stage.y()
if (right) newX = stage.width() - window.innerWidth
else if (left) newX = 0
if (top) newY = 0
else if (bottom) {
newY = stage.height() - canvasDimensions.height / ratio
}
if (top || right || bottom || left) {
// Animate the stage back to the center within the defined scope
const tween = new Konva.Tween({
node: stage!,
duration: 1, // Animation duration in seconds
easing: Konva.Easings.EaseInOut,
x: newX,
y: newY,
onFinish: function () {
// isAnimating = false // Reset the animation flag
},
})
// isAnimating = true; // Set the animation flag
tween.play()
}
}
so far everything is working as expected before zooming in, but when i zoom in things start to break, panning always to the side even though I'm within the boundaries