GithubHelp home page GithubHelp logo

bettertyped / react-zoom-pan-pinch Goto Github PK

View Code? Open in Web Editor NEW
1.3K 8.0 256.0 14.1 MB

🖼 React library to support easy zoom, pan, pinch on various html dom elements like <img> and <div>

License: MIT License

HTML 0.13% JavaScript 1.14% CSS 1.17% TypeScript 83.50% MDX 14.06%
pan zoomin zoomout pinch react gesture zoom svg figma html-manipulation

react-zoom-pan-pinch's People

Contributors

27pchrisl avatar abe27342 avatar alexlande avatar allcontributors[bot] avatar arooba-git avatar assash17 avatar atomnp avatar baileyfirman avatar bencefr avatar codewithleader avatar cretezy avatar daustin-scottlogic avatar davidlky avatar dependabot[bot] avatar dimensi avatar eduplessis avatar eewing avatar ethaizone avatar git9am avatar hueyyeng avatar imtrent avatar joshuaknauber avatar kentaigaibe avatar mateuswolkmer avatar matthiasschwarz avatar miboruch avatar mindouro avatar mpyrc avatar ossan-engineer avatar prc5 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-zoom-pan-pinch's Issues

Troubles with big images

So if I load a big image (like 2000x2000) into TransformWrapper it doesn't work as expected. Slow zoom, incorrect pan. I tried use minScale or put it into overflow: auto and it doesn't help. Any ideas?

Error while calling zoomIn/zoomOut/resetTransform

Sometimes when using zoomIn/zoomOut/resetTransform app crashes. Noticed it when updating version 1.4.5 to 1.5.5

TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function.

  this.animation = () => {
    if (!this.animation || !this.mounted) return;
    const frameTime = new Date().getTime() - startTime;
    const animationProgress = frameTime / animationTime;
    const animationType = availableAnimations[animationName];

    const step = animationType(animationProgress);

    if (frameTime >= animationTime) {
      callback(lastStep);
      this.animation = null;
    } else {
      callback(step);
      requestAnimationFrame(this.animation); << CRASHES HERE
    }
  };

Zooming issues when TransformComponent larger than TransformWrapper

I am working on a project where I would like to provide zooming and panning for images that could be of any size. I have set a size on a div inside of the TransformWrapper to restrict the zooming and panning area to within the width and height of the screen. However, sometimes the images inside the TransformComponent can be larger than the screen. In this scenario, it seems to center the images within the larger element rather than the smaller one, causing parts of the image to not be reachable within the zooming area.

It is important for me to initially show the user the image at the original size so scaling them down is not really an option.

Below is an example using divs that reproduces the error. See the issue in code sandbox

import React from 'react';

import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";

export default function Example(){
  return (
    <TransformWrapper 
      defaultScale={0.3} 
      options={{
        minScale: 0.1, 
        // false for centerContent does not seem to work except at initial render?
        // centerContent: false
        // true seems to center it with the TransformComponent-module_container__XXX 
        // which causes it to be off-center
        centerContent: true 
      }}>
      {({ zoomIn, zoomOut, resetTransform, ...rest }) => (
        <React.Fragment>
          <div style={{textAlign: 'left'}}>
            <div>Orange = Zooming Area; Blue = Object being zoomed</div>
            <button onClick={zoomIn}>+</button>
            <button onClick={zoomOut}>-</button>
            <button onClick={resetTransform}>x</button>
          </div>
          {/* Set zooming area size. Tried with sizing div outside/inside/inside and outside of TransformComponent */}
          <div style={{height: 510, width: 510, backgroundColor: 'orange', border: '10px solid green'}}> 
            <TransformComponent>
              {/* Thing I am actualy trying to zoom. Potentially bigger than TransformComponent parent */}
              <div style={{height: 1000, width: 1000, backgroundColor: 'blue', border: '50px solid'}} />  
            </TransformComponent>
          </div>
        </React.Fragment>
      )}
    </TransformWrapper>
  );
}

Changing the height/width properties for TransformComponent-module_container__XXX in the browser from fit-content to 100% seems to make the issue a little better, but it is still not perfectly centered and I'm not sure of the implications of this.

Here is what is rendered after zooming out some.

image

After setting the TransformComponent-module_container__XXX div to have a 100% size:

image

TypeError: Cannot read property 'offsetWidth' of null

After upgrading from version 1.0.0 to 1.6.1 I get the following error:

TypeError: Cannot read property 'offsetWidth' of null
getComponentsSizes
node_modules/react-zoom-pan-pinch/dist/index.es.js:484
  481 | }
  482 | 
  483 | function getComponentsSizes(wrapperComponent, contentComponent, newScale) {
> 484 |   var wrapperWidth = wrapperComponent.offsetWidth;
  485 |   var wrapperHeight = wrapperComponent.offsetHeight;
  486 |   var contentWidth = contentComponent.offsetWidth;
  487 |   var contentHeight = contentComponent.offsetHeight;

just using the basic setup from the GitHub example.

Having the compontent rendered makes all sliders unslideable

I've stubled upon a very interesting bug. If you have the react-zoom-pan-pinch component anywhere rendered on the screen, all input html elements of type range would no longer be slide-able. You can click on them to change their value, but sliding (click and drag) them does nothing.

Here is sample code of slider that would no longer work if you have used the component:

import React, { Component } from 'react';

class GeneralOpt extends Component {
    constructor(props) {
        super(props);
        this.state = {
            to: -39
        };
        this.handlePoseChange = this.handlePoseChange.bind(this);
    }

    handlePoseChange(event) {
        let state = {to: event.target.value};
        this.setState(state);
    }
    render() {
        return (
            <div id="sidebar-container">
                <input
                    id="to"
                    type="range"
                    min="-100"
                    max="100"
                    value={this.state.to}
                    onChange={this.handlePoseChange}/>
            </div>
        );
    }
}

export default GeneralOpt;

Text selection (click and drag on a text) also seems to not work. I guess the component is tapping into the sliding event of the whole page somehow. It would be nice if the sliding worked as expected everywhere except over the react-zoom-pan-pinch component.

Thank you for the nice tool

return functions from onZoomChange

Hey! Are there any return functions from onZoomChange?

I can only see data about the zoom, but I want to say 'when the zoom hits a scale of 8, reset/zoomOut' and can't seem to find anything

npm/yarn version1.5.5 is different from github

Hi, npm/yarn version1.5.5 is different from github.
i.e. TransformWrapper.d.ts import { TransformWrapperProps } from "../store/interfaces/transformWrapperInterface";. But transformWrapperInterface is not exist.
I'm just a little confused

Fix async operations before the component was unmounted

Getting an error after i navigate to a new route using 'react-router-dom' history.push method.

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

after i removed the use of TransformWrapper the error is gone.

I submitted a question about this on stackoverflow here and the answer i got was to submit an issue here.

How to remove animation after dragging/panning?

After panning and my mouse is no longer clicked, the wrapper still continues to animate. I tried setting enableVelocity to false but that behavior still happens. Is there a way that i can remove the extra animations after panning?

Thanks!

disableOnTarget typescript error

Trying to use the pan: { disableOnTarget } gives a typescript error not assignable to type

If I add disableOnTarget?: string[]; to the pan in .d.ts the feature works fine however

setScale animation/transition

Is it possible to make this function also take into account the animation time, such as reset?
because right now it just instantly changes transform without animation

I will get x offset when scaling to left

Hello,

I use div to encapsulate your div of react-transform-element, and if I use mouse wheel to zoom in our content, your div will get x offset so the content will move to left.
Is there and idea can solve this issue?
screenshot1
screenshot2

Mousewheel event

The mousewheel event is deprecated and doesn't work in Firefox. The wheel event might be a better option as a replacement.

defaultScale vs scale

If i set the defaultScale to 2 the scale is still set to 1 on initial render and on component update the scale remains at the position it was at before the update. If i set the scale to 2 then every time my component updates the scale is set back to 2. How can i have the scale set to 2 on initial render and not have it jump back to 2 on a component update?

Failed to execute 'requestAnimationFrame' on 'Window' when storing zoom level in state

I get this error when i use the onZoomChange to store the current zoom level in my components state.
this is an extract of my code, if i comment out the setZoom() statement below it works fine again.

    ....
    const [zoom, setZoom] = useState<number>();
    const zoomChange = ({ scale }) => {
        console.log('zoom', scale);
        setZoom(scale);
    };

    return (
        <SelectionProvider>
            <TransformWrapper {...opts} onZoomChange={zoomChange}>
                {({ zoomIn, zoomOut, resetTransform }) => (
                    <>
                        <TransformComponent>
                            <div className="graphView__container">
                                <Graph
                                    graph={graph}
                                    bounds={graphBounds}
                                    zoom={zoom || 1}
                                />
                            </div>
                        </TransformComponent>
                        <ToolButtons
                            zoomIn={zoomIn}
                            zoomOut={zoomOut}
                            resetTransform={resetTransform}
                        />
                    </>
                )}
            </TransformWrapper>
    );
TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function.
animation
src/store/animations/index.ts:35
    32 |     this.animation = null;
    33 |   } else {
    34 |     callback(step);
  > 35 |     requestAnimationFrame(this.animation);
    36 | ^  }
    37 | };
    38 | 

Callback for dragging start and stop

Hello. I have a simple interactive SVG map, I would like to have dragging callbacks to toggle pointer-events: none, to prevent clicking to buttons in during of dragging. That is, I need to know when I click and move the mouse. onPanningStart works when clicked only without waiting for mouse movement

Get updated scale position after zooming in or out

I'm currently using

<button
 type='button'
 onClick={(e) => this.onZoomIn(e, scale, zoomIn)} > 
+ 
</button>

and inside of

  onZoomIn = (e, scale, zoomIn) => {
    zoomIn(e);
    console.log(e, scale);
  }

This works fine except the scale that is returned is the old scale value. Is there a way that i can get the updated scale value after zooming in or out?

or

Is there by chance an onChange event or something similar where i can always get updated values when ever any change is made? Currently there is onPanning, onWheel, etc but there is nothing for onZoom.

Thanks

how to disable fling of image

Is there any function or variable can disable fling, which is when user drag image to one direction and the image will keep moving and slow down until stop.
image

Image with fixed width and height

From what i can see this library is meant for images with a width of 100% of the container. Using an image with a fixed width and height doesn't fully pan since its calculating for an image that is meant to be 100% of the container. I can fix this by setting limitToBounds to false so that i can pan it but then by doing this you can pan the content off the screen. Is there a way to use an image with a fixed width and height while sticking to the limit bounds?

Thanks.

Problem if use in TS context

Hi,
There is a problem with Type on TransformComponent component in TS context (class component)

error :
Type 'TransformComponent' is missing the following properties from type 'ElementClass': context, setState, forceUpdate, props, and 2 more.ts(2605)

https://codesandbox.io/s/boring-firefly-u35d3

Do you have an idea of the problem ?
Thanks.

Cannot read property 'positionX' of undefined

A simple usage of the library does not work.

<TransformWrapper>
     <TransformComponent>
         <img src={xxx} />
     </TransformComponent>
</TransformWrapper>

MacOS v10.11.6
node: v10.8.0
"react": "^16.3.2"
"react-zoom-pan-pinch": "^1.6.1"

Cannot change how quickly it zooms

None of the "AnimationSpeed" props seem to work. Can someone help me zoom faster or slower?

Also, I noticed the within the source code, the animation speed props are set to PropTypes,bool instead of PropTypes.number could that be the issue? I did not trace the code any further.

Zoom To Center of Image

I am trying to attach a slider component to trigger zoom in & out, I use it to update the scale value however when that happens it zooms into (0,0) (top, left) corner of the image. Is there an easy way to have this automatically zoom to the center of the image?

Remove double quotes from classname

In the TransformComponent file you use double quotes in the react-transform-component classname and I'm not sure it is suppose to be there. That class is for the developer to style the outer div and, since double quotes are not used in the react-transform-element which is a direct child of the outer div and have the same purpose, I think removing the double quotes would be the best approach to maintain consistency across the code.

The snippet of what I'm talking about:

<div ref={wrapperRef} className={`"react-transform-component" `${styles.container}`}>`
                                 ^^^                       ^^^
   <div ref={contentRef} className={`react-transform-element ${styles.content}`} style={style}>
       {children}
   </div>
</div>

Click event not work in TransformComponent with image tag

I know the click event is right in the div demo, but when I have a image component in the TransformComponent and set onClick in the image or have a map and some areas attrs, the click event did not work.

            <img
              src={require('./images/map.jpg')}
              useMap="#image-map"
              onClick={() => alert(1)}              // <---- not work
            />
            
            <map name="image-map">
              <area
                coords="751,538,846,640"
                shape="rect"
                onClick={() => alert(1)}             // <----- not work either
              />

Rendered Components break page boundary

Screen Shot 2019-09-09 at 9 26 01 AM

There is white space which extends past the react webpage boundary. From my testing, this is because the componets within the TransformComponet are technically larger than the page boundary. The screenshot is of the TransformComponet scaled somewhere close to 0.3.

I would like the whitespace to not exist while maintaining the functionality of this wonderful react-zoom-pan-pinch component. Is there a strategy that I can employ while retaining the original structure of my components within the TransformComponent?

OnWheel not always triggered

I've noticed since the last update that OnWheel is not always triggered and the component does not scale. I have to drag the component a little then i'm able to zoom again. If i revert back to the older version of the code then it works fine.

eventListeners aren't deleted properly

In StateContext file, in the componentDidMount, you return the removeEventListener for: mousedown, mousemove and mouseup events.
This removeEventListeners never executes, and the listeners keep working when you change page, creating a strange behavior when you try to select any text.

  componentDidMount() {
    const passiveOption = makePassiveEventOption(false);

    // Panning on window to allow panning when mouse is out of wrapper
    window.addEventListener("mousedown", this.handleStartPanning, passiveOption);
    window.addEventListener("mousemove", this.handlePanning, passiveOption);
    window.addEventListener("mouseup", this.handleStopPanning, passiveOption);
    return () => {
      window.removeEventListener("mousedown", this.handleStartPanning, passiveOption);
      window.removeEventListener("mousemove", this.handlePanning, passiveOption);
      window.removeEventListener("mouseup", this.handleStopPanning, passiveOption);
    };
  }

If you add the componentWillUnmount lifecycle with the removeEventListeners, it works as expected when you unmount the component.

componentDidMount() {
  const passiveOption = makePassiveEventOption(false);

  // Panning on window to allow panning when mouse is out of wrapper
  window.addEventListener("mousedown", this.handleStartPanning, passiveOption);
  window.addEventListener("mousemove", this.handlePanning, passiveOption);
  window.addEventListener("mouseup", this.handleStopPanning, passiveOption);
}

componentWillUnmount() {
  const passiveOption = makePassiveEventOption(false);

  window.removeEventListener("mousedown", this.handleStartPanning, passiveOption);
  window.removeEventListener("mousemove", this.handlePanning, passiveOption);
  window.removeEventListener("mouseup", this.handleStopPanning, passiveOption);
  }

Major version bump

Hi,

Is this module due for a major version bump? Got an update and the complete interface changed from 1.1.2 to now.

Nothing happen after resetTransform call

Before update to 1.1.1 it's worked nice. Now, after click on button that call resetTransform nothing happen. In DevTools no errors, no DOM changes.

React & React-dom - 16.9.0

Cannot read property 'getBoundingClientRect' of null

I got this error message every time when I click on the page:

Uncaught TypeError: Cannot read property 'getBoundingClientRect' of null
    at getComponentsSizes (index.es.js:348)
    at StateProvider.handleCalculateBounds (index.es.js:380)
    at StateProvider._this.handleStartPanning (index.es.js:941)
getComponentsSizes @ index.es.js:348
handleCalculateBounds @ index.es.js:380
StateProvider._this.handleStartPanning @ index.es.js:941
15:33:48.257 

When I tried to debug I added:
console.log("setWrapperComponent", wrapperComponent); to StateContext.js
and my console show:

setWrapperComponent <div>​…​</div>

and few seconds later:

setWrapperComponent null

I think when TransformWrapper added with array map and we change the array that can cause an issue. I can't reproduce the issue outside of our codebase.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.