zcreativelabs / react-simple-maps

Beautiful React SVG maps with d3-geo and topojson using a declarative api.
https://www.react-simple-maps.io/
MIT License
3.06k stars 424 forks source link

New feature: Zoom and Pan two finger alert on touch screens #47

Open oktalk opened 6 years ago

oktalk commented 6 years ago

Going off of your example for zooming and panning (https://www.react-simple-maps.io/zoom-pan), on a touch screen panning with one finger does nothing. As this is not an expected behavior a good solution would be to fire an alert warning the user that they must use two fingers to pan.

Edit: Added in a better description

oktalk commented 6 years ago

Looking through the past issues I was able to find references to this issue: #33 #25 #26

Am I missing something? Is this map able to be panned on a mobile device or touch screen? Is there some setting I need to turn on or enable?

zimrick commented 6 years ago

Hi @oktalk,

Panning should work on touch screens, but you have to currently use two fingers to drag it. There were issues where the panning interfered with scroll, so we opted for this method, but I could add an option to enable this with one finger as well.

oktalk commented 6 years ago

@zimrick THANK YOU!! I was so worried that I had done something wrong.

Two finger panning is a great UI feature. However, the map should still recognize a one finger attempt at panning. But instead of triggering a pan, a message should appear stating that you need to use two fingers -- I believe Google Maps does this.

In my project, I'll implement a warning message from an outer div wrapped around the map.

zimrick commented 6 years ago

Ok, yeah, it would probably be good for the map to do this out of the box. Will have a look at putting this in. Thanks for flagging.

pronebird commented 6 years ago

Please if you're going to implement this, add a prop so developer could decide what to do, do not fire an alert().

oktalk commented 6 years ago

@pronebird In my implementation I add a onTouchMove listener to the containing element. Then fire something like this to essentially hide/show the warning:

  touchWarning = (event) => {
    if (event.touches.length === 1) {
      this.setState({
        touchError: true
      });
      setTimeout(() => {
        this.setState({
          touchError: false
        });
      }, 2000);
    }
  }

The result:

nimbus-record-video-2018-02-26-09-20-40- 1

runofthemill commented 6 years ago

hey @oktalk - this looks like a great solution, but I'm having trouble getting it working. I can't even get this to work:

    constructor() {
    ...
        this.handleTouchStart = this.handleTouchStart.bind(this)
    }
    ...
    handleTouchStart(event) {
      alert("Anything?")
    }
         <ZoomableGroup
            ...
            onTouchStart={this.handleTouchStart}
          >

Any help would be greatly appreciated!

oktalk commented 6 years ago

So, I think the ZoomableGroup may only have onMoveStart... I actually attached my touchWarning() function to a div wrapped around the whole map. There I have access to React's ontouchStart() event.

What you're are trying to do in your code probably wouldn't work since the core library doesn't have an onTouchStart callback function... I think. I'm going off of memory here.

DominikHoffendahl commented 4 years ago

Is this issue still up to date for the v1.0.0-beta.0?

For me one-finger panning works fine on Chrome, it does not work on Safari though. Two-finger zoom on touch screens does not work at all for me, as it either zooms into the page or does nothing when page scaling is disabled in meta tags.

Edit: Keep up the great work! I'm heavily using this library for my current project.