Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting bounds #1

Open
kenchris opened this issue Nov 29, 2018 · 4 comments
Open

Allow setting bounds #1

kenchris opened this issue Nov 29, 2018 · 4 comments

Comments

@kenchris
Copy link
Contributor

kenchris commented Nov 29, 2018

I admit that I didn't look at the code in detail to see if this is already possible, but I know from having implemented this on mobile platforms before that it is common that you have a max and min scale, and still allow pinching beyond that, but then when letting go, it would just bounce back with a nice animation.

It might make sense doing something similar.

The Safari browser on iOS does this (or used to, as I don't use any iOS devices for a while)

There are some CSS properties for overscroll scrolling, so might make sense to minic that for this as well

https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior
https://developers.google.com/web/updates/2017/11/overscroll-behavior

@jakearchibald
Copy link
Contributor

Yeah, this is a good idea.

@valpet
Copy link

valpet commented Mar 28, 2019

It's not only a good idea, it's an excellent idea. I miss this function very much.

@WernerRaath
Copy link

@kenchris did you ever find a fix for this? Or should one search for alternatives?

@streamtw
Copy link

streamtw commented Mar 5, 2021

Bounds can be achieved by adding custom event listeners:

HTML:

<pinch-zoom class="my-pinch-zoom">
  <img>
</pinch-zoom>

Javascript:

const pinchZoom = document.querySelector('.my-pinch-zoom')
pinchZoom.addEventListener('touchend', moveToSafeArea)
pinchZoom.addEventListener('wheel', moveToSafeArea)

Event listener moveToSafeArea will calculate proper position for content, according to width and height of both wrapper and content:

const moveToSafeArea = function () {
  const wrapper = document.querySelector('.my-pinch-zoom')
  const wrapperWidth = wrapper.clientWidth
  const wrapperHeight = wrapper.clientHeight

  const content = wrapper.children[0]
  const contentWidth = content.clientWidth * wrapper.scale
  const contentHeight = content.clientHeight * wrapper.scale

  content.classList.add('moving')

  let safeX
  let safeY

  const safeRangeX = wrapperWidth - contentWidth
  if (safeRangeX > 0) {
    safeX = Math.min(Math.max(wrapper.x, 0), safeRangeX)
  } else {
    safeX = Math.max(Math.min(wrapper.x, 0), safeRangeX)
  }

  const safeRangeY = wrapperHeight - contentHeight
  if (safeRangeY > 0) {
    safeY = Math.min(Math.max(wrapper.y, 0), safeRangeY)
  } else {
    safeY = Math.max(Math.min(wrapper.y, 0), safeRangeY)
  }

  wrapper.setTransform({
    scale: wrapper.scale,
    x: safeX,
    y: safeY
  })

  setTimeout(() => {
    content.classList.remove('moving')
  }, 250)
}

And remember to add a nice bounce animation:

.my-pinch-zoom > .moving {
  transition: all .25s;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants