Giter VIP home page Giter VIP logo

react-native-zoomable-view's Introduction

🚩🚩🚩 Attention: Deprecated 🚩🚩🚩

Sadly we are not using react-native in any of our projects anymore and therefore don't use this either. We tried to apply some fixes from time to time, but it took up way more time than we have available for a fun project. We also wanted to do a complete rewrite using react-animated for performance reasons, but we never made it past a prototype. Since we did not find enough contributors to keep the project alive and did not want to leave the users hanging, we decided to deprecate our codebase and talk to some of the people, who have forked and worked on it.

Fortunately the awesome guys from [openspacelabs](https://github.com/openspacelabs/) have used this package and extended it in their repo. We have talked to them and they have agreed that now have their fork is the defacto successor of react-native-zoomable-view.

There is also a reanimated version, with a (as far as I can see bit smaller feature set - but it might be perfect for you) available: https://github.com/kesha-antonov/react-native-zoom-reanimated

Please only use their package going forward: https://github.com/openspacelabs/react-native-zoomable-view .
This package will not be developed anymore and as soon as their npm package is published, we will archive our npm package.






react-native-zoomable-view

A view component for react-native with pinch to zoom, tap to move and double tap to zoom capability. You can zoom everything, from normal images, text and more complex nested views.

We are using this component already in production in two of our projects, but for quality assurance sake, please consider this component beta. We are happy to hear from you about bugs, issues and would also appreciate your pull requests, if you've made improvements or fixed bugs.

Preview

Getting started

Installation

$ npm install @dudigital/react-native-zoomable-view --save

or

$ yarn add @dudigital/react-native-zoomable-view

Basic Usage

This component is based on react-natives View, enhanced by panresponders and other events to make it zoomable. Therefore no platform specific configuration needs to be done.

Just use it as a drop in component instead of a normal view.

Import ReactNativeZoomableView:

import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';

Use the component:

<ReactNativeZoomableView
   maxZoom={1.5}
   minZoom={0.5}
   zoomStep={0.5}
   initialZoom={1}
   bindToBorders={true}
   onZoomAfter={this.logOutZoomState}
   style={{
      padding: 10,
      backgroundColor: 'red',
   }}
>
   <Text>This is the content</Text>
</ReactNativeZoomableView>

Example

Here is a full drop in example you can use in Expo, after installing the package.

import React from 'react';
import { View, Image } from 'react-native';
import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';

export default class App extends React.Component {
  /**
   * Log out an example event after zooming
   *
   * @param event
   * @param gestureState
   * @param zoomableViewEventObject
   */
  logOutZoomState = (event, gestureState, zoomableViewEventObject) => {
    console.log('');
    console.log('');
    console.log('-------------');
    console.log('Event: ', event);
    console.log('GestureState: ', gestureState);
    console.log('ZoomableEventObject: ', zoomableViewEventObject);
    console.log('');
    console.log(`Zoomed from ${zoomableViewEventObject.lastZoomLevel} to  ${zoomableViewEventObject.zoomLevel}`);
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        <ReactNativeZoomableView
          maxZoom={1.5}
          minZoom={0.5}
          zoomStep={0.5}
          initialZoom={1}
          bindToBorders={true}
          onZoomAfter={this.logOutZoomState}
          style={{
            padding: 10,
            backgroundColor: 'red',
          }}
        >
          <Image style={{ flex: 1, width: null, height: '100%' }}
                 source={require('./image.jpg')}
                 resizeMode="contain" />
        </ReactNativeZoomableView>
      </View>
    );
  }
}

Expo Snack Example

https://snack.expo.io/SkltQtr8Q

Example Repo

https://github.com/DuDigital/react-native-zoomable-view-example

Props

Options

These options can be used to limit and change the zoom behavior.

name type description default
zoomEnabled boolean Can be used to enable or disable the zooming dynamically true
initialZoom number Initial zoom level on startup 1.0
maxZoom number Maximum possible zoom level (zoom in). Can be set to null to allow unlimited zooming 1.5
minZoom number Minimum possible zoom level (zoom out) 0.5
doubleTapDelay number How much delay will still be recognized as double press (ms) 300
doubleTapZoomToCenter boolean If true, double tapping will always zoom to center of View instead of the direction it was double tapped in
bindToBorders boolean If true, it makes sure the object stays within box borders true
zoomStep number How much zoom should be applied on double tap 0.5
pinchToZoomInSensitivity number the level of resistance (sensitivity) to zoom in (0 - 10) - higher is less sensitive 3
pinchToZoomOutSensitivity number the level of resistance (sensitivity) to zoom out (0 - 10) - higher is less sensitive 1
zoomCenteringLevelDistance number the (zoom level - 0 - maxZoom) distance for pinch to zoom actions until they are shifted on new pinch to zoom center - higher means it centeres slower 0.5
movementSensibility number how resistant should shifting the view around be? (0.5 - 5) - higher is less sensitive 1.9
initialOffsetX number The horizontal offset the image should start at 0
initialOffsetY number The vertical offset the image should start at 0
longPressDuration number Duration in ms until a press is considered a long press 700
captureEvent boolean Defines whether the pan responder of the parent element should be captured. (useful for react-native modals, set it to true) false

Callbacks

These events can be used to work with data after specific events.

name description params expected return
onDoubleTapBefore Will be called, at the start of a double tap event, gestureState, zoomableViewEventObject void
onDoubleTapAfter Will be called at the end of a double tap event, gestureState, zoomableViewEventObject void
onShiftingBefore Will be called, when user taps and moves the view, but before our view movement work kicks in (so this is the place to interrupt movement, if you need to) event, gestureState, zoomableViewEventObject {boolean} if this returns true, ZoomableView will not process the shift, otherwise it will
onShiftingAfter Will be called, when user taps and moves the view, but after the values have changed already event, gestureState, zoomableViewEventObject void
onShiftingEnd Will be called, when user stops a tap and move gesture event, gestureState, zoomableViewEventObject void
onZoomBefore Will be called, while the user pinches the screen, but before our zoom work kicks in (so this is the place to interrupt zooming, if you need to) event, gestureState, zoomableViewEventObject {boolean} if this returns true, ZoomableView will not process the pinch, otherwise it will
onZoomAfter Will be called, while the user pinches the screen, but after the values have changed already event, gestureState, zoomableViewEventObject {boolean} if this returns true, ZoomableView will not process the pinch, otherwise it will
onZoomEnd Will be called after pinchzooming has ended event, gestureState, zoomableViewEventObject {boolean} if this returns true, ZoomableView will not process the pinch, otherwise it will
onLongPress Will be called after the user pressed on the image for a while event, gestureState void

Events

The following events allow you to control the ZoomableView zoom level & position from your component. (think of control buttons, ...)

You can find an implementation example in the example repo: https://github.com/DuDigital/react-native-zoomable-view-example

name description params expected return
zoomTo Changes the zoom level to a specific number newZoomLevel: number, bindToBorders = true Promise
zoomBy Changes the zoom level relative to the current level (use positive numbers to zoom in, negative numbers to zoom out) zoomLevelChange: number, bindToBorders = true Promise
moveTo Shifts the zoomed part to a specific point (in px relative to x: 0, y: 0) newOffsetX: number, newOffsetY: number, bindToBorders = true Promise
moveBy Shifts the zoomed part by a specific pixel number newOffsetX: number, newOffsetY: number, bindToBorders = true Promise

Example:

export default function App() {
  // you will need a reference to the ReactNativeZoomableView component
  const zoomableViewRef = createRef<ReactNativeZoomableView>();

  return (
    <View style={styles.container}>
      <View style={styles.zoomWrapper}>
        <ReactNativeZoomableView
          ref={zoomableViewRef}
          bindToBorders={true}
        >
          <Text style={styles.caption}>HelloWorld</Text>
        </ReactNativeZoomableView>
      </View>

      <View style={styles.controlWrapperLeft}>
        {/* Here you see some examples of moveBy */}
        <Button onPress={() => zoomableViewRef.current!.moveBy(-30, 0)} title="⬅️" />
        <Button onPress={() => zoomableViewRef.current!.moveBy(30, 0)} title="➡️" />
        <Button onPress={() => zoomableViewRef.current!.moveBy(0, -30)} title="⬆️" />
        <Button onPress={() => zoomableViewRef.current!.moveBy(0, 30)} title="⬇️" />

        {/* Here you see an example of moveTo */}
        <Button onPress={() => zoomableViewRef.current!.moveTo(300, 200)} title="Move to" />
      </View>

      <View style={styles.controlWrapperRight}>
        {/* Here you see examples of zoomBy */}
        <Button onPress={() => zoomableViewRef.current!.zoomBy(-0.1)} title="-" />
        <Button onPress={() => zoomableViewRef.current!.zoomBy(0.1)} title="+" />

        {/* Here you see an example of zoomTo */}
        <Button onPress={() => zoomableViewRef.current!.zoomTo(1)} title="reset" />
      </View>
    </View>
  );
}

Pan Responder Hooks

Sometimes you need to change deeper level behavior, so we prepared these panresponder hooks for you.

name description params expected return
onStartShouldSetPanResponder description event, gestureState, zoomableViewEventObject, baseComponentResult {boolean} whether panresponder should be set or not
onMoveShouldSetPanResponder description event, gestureState, zoomableViewEventObject, baseComponentResult {boolean} whether panresponder should be set or not
onPanResponderGrant description event, gestureState, zoomableViewEventObject void
onPanResponderEnd Will be called when gesture ends (more accurately, on pan responder "release") event, gestureState, zoomableViewEventObject void
onPanResponderTerminate Will be called when the gesture is force-interrupted by another handler event, gestureState, zoomableViewEventObject void
onPanResponderTerminationRequest Callback asking whether the gesture should be interrupted by another handler (iOS only due to facebook/react-native#27778, facebook/react-native#5696, ...) event, gestureState, zoomableViewEventObject void
onPanResponderMove Will be called when user moves while touching event, gestureState, zoomableViewEventObject void

zoomableViewEventObject

The zoomableViewEventObject object is attached to every event and represents the current state of our zoomable view.

   {
      zoomLevel: number,         // current level of zooming (usually a value between minZoom and maxZoom)
      offsetX: number,           // current offset left
      offsetY: number,           // current offset top
      lastZoomLevel: number,     // last zoom level (before we started the movement)
      lastX: number,             // last offset left (before we started the movement)
      lastY: number,             // last offset top (before we started the movement)
      lastMovePinch: boolean,    // information if a movement is going on
      distanceBottom: number,    // view offset from bottom border
      distanceLeft: number,      // view offset from left border
      distanceRight: number,     // view offset from right border
      distanceTop: number,       // view offset from bottom border
      lastMovePinch: boolean,    // boolean, that states if this movement was a pinch movement
      originalHeight: number,    // original height of the outer view
      originalWidth: number,     // original width of the outer view
      captureEvent: boolean,     // should the panresponder be taken away from parent component (used for react-native modals) 
   }

Special configurations

React Native Modal

To make this work with react-native modals, you have to set the captureEvent prop to true. Otherwise the modal will stop the pinch2zoom event and it will not work.

TODO

  • Improve documentation
  • Add examples for more complex scenarios (react-native-zoomable-view in a swiper)
  • TESTS

Contributing

A lot of people are now using react-native-zoomable-view and there are always smaller things to improve and change.
Therefore any contributions are more than welcome! <3

Are you looking to help out and improve this project?
Either submit Pull requests with awesome changes or reach out to me on Twitter: https://twitter.com/SimonEritsch
Helping hands are always appreciated! :)

How to contribute

Just clone the example repository: https://github.com/DuDigital/react-native-zoomable-view-example

Adjust the package in the typescript files in node_modules/@dudigital/react-native-zoomable-view folder, while running npm transpile in that folder as well. (the transpile command will make sure to transpile the typescript code into javascript)

// We definitely need a better process here. If you have any ideas - please open an issue or PR about a solution. ;) // We would really appreciate it

react-native-zoomable-view's People

Contributors

adamaveray avatar atomheartother avatar dudyn5ky1 avatar jhainaua avatar jschao avatar kristijantomic avatar milansusnjar avatar npoussu avatar simonerich avatar skantus 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

react-native-zoomable-view's Issues

deeper zoom scroll out or skip out

I am displaying some large image inside. I set max Zoom to 5 (or higher). The first zoom with 2 fingers usually is OK. If I zoom more, the center point of zoom is moving out, or is zoom (with 2 fingers) again it is not easy zoom to point I want to. The point is moving away during zooming. Sometimes if I start second zoom (put 1st finger and after 1 second I puth the 2nd finger), the image skips.

Set zoomlevel from state

Hello, is there a way to set the zoomlevel from a button?

For example I want to reset the zoomlevel to 1 with a button.
Like the code below but then with updating the zoomlevel of the ReactNativeZoomableView component.

Thanks

import React, { Component } from 'react'
import { AppRegistry, Text, View, Button } from 'react-native'
import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView'
import { name as appName } from './app.json'

export default class App extends Component {
  constructor (props, context) {
    super(props, context)
    this.props = props

    this.state = { initialZoom: 1 }
  }

  resetZoom=() => {
   this.setState({ initialZoom: 1 })
  }

  setZoom =(event, gestureState, zoomableViewEventObject) => {
    this.setState({ initialZoom: zoomableViewEventObject.zoomLevel })
  }

  render () {
    return (
      <View style={{ flex: 1 }}>
        <ReactNativeZoomableView
          initialZoom={this.state.initialZoom}
          onZoomAfter={this.setZoom}>
          <View>
            <Text>
              Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</Text>
          </View>
        </ReactNativeZoomableView>
        <Text>Zoom factor: {this.state.initialZoom}</Text>
        <Button
          onPress={this.resetZoom}
          title='Reset zoom'
        />
      </View>
    )
  }
}

AppRegistry.registerComponent(appName, () => App)

Better description of the zoomLevel in the documentation

I worked with the zoomLevel attribute of the zoomableEventObject yesterday and I think it should be documented more clearly how the zoom relates to the scale of the view. The initial assumption would be that the zoomLevel is the factor the view is scaled by, but it is actually the square root of it.

It might have some advantages in the usability to scale it twice by the zoomLevel factor, but it should be written somewhere in the documentation to avoid confusion.

You Can Just Use ScrollView Instead (not an issue)

I found that all I needed for zoom was this. I'm not sure how to do double click to zoom but I don't really need it for my app. I just put this here for other people who might be having problems with react-native-zoomable-view.

<ScrollView bounces={false} bouncesZoom={false} maximumZoomScale={2} minimumZoomScale={1} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false}> /*your content*/ </ScrollView>

How to animate double tap zoom?

Hi,
How can I add a duration to zoom when double tap on photo. Zooming now have no duration and like a flash effect, suddenly zoom in and zoom out. Like twitter or ...

Initial zoom value and pinch to zoom bug

Found this bug when your initialZoom value is less than 1

The bug causes the zoom value to 1 during the first pinch gesture. In ReactNativeZoomableView.js fie in Line 32 you need to update as below

this.state = {
zoomLevel: props.initialZoom,
...initialState,
lastZoomLevel:props.initialZoom ? props.initialZoom : 1,
offsetX: props.initialOffsetX,
offsetY: props.initialOffsetY,
};

Adding a snap to zoom

Hey DuDigital,
I started using your great library and it's super intuitive and easy to use.
I would like to ad a "snap" experiance to my project, meaning that if the zoom level is between 0.9 to 1.1 I want it to be set to one.
I tried to modify the zoomableViewEventObject.zoomLevel but it's read only :/

Reset zoom level

Hello,

Great job at creating this zoom component, really appreciate it.

I was wondering if there is a way to reset zoom level on any event. I.e. when zoom level reaches 0.2 I'd like put it back to 1. How can I achieve that?

/Karolis

ScrollView is inactive

If you use ReactNativeZoomableView and ScrollView simultaneously, ScrollView will not work, unfortunately.
e.g:

 <ReactNativeZoomableView>
                        <ScrollView>
                               //your content
                       <ScrollView>
<ReactNativeZoomableView>

Scroll disable request

Thank it good lib,
may is ask more feature
scroll disable,
currently i have a problem when i use zoomable view with scroll view

<ScrollView>
<ZoomableView>
...
</ZoomableView>
</ScrollView>

Trying to use ReactNativeZoomableView and getting an error

I'm trying with this code and I'm getting an error ONLY when I try to zoom or any other interaction:

import React from 'react';
import { Image, View } from 'react-native';
import {ReactNativeZoomableView} from '@duagentur/react-native-zoomable-view';

export class FloorPlan extends React.Component {
    render() {
        return (
            <View style={{ flex: 1 }}>
            <ReactNativeZoomableView>
                <Image style={{flex: 1, width: null, height: '100%'}} 
                    source={require('../assets/floorPlans/FloorPlan_1.png')} 
                    resizeMode="contain" />
            </ReactNativeZoomableView>
            </View>
        );
    }
}

export default FloorPlan;

The error I'm getting:

TypeError: TypeError: Cannot read property 'getValue' of null

This error is located at:
    in RCTView (at View.js:60)
    in View (at ReactNativeZoomableView.js:538)
    in RCTView (at View.js:60)
    in View (at ReactNativeZoomableView.js:533)
    in ReactNativeZoomableView (at FloorPlan.js:13)
    in RCTView (at View.js:60)
    in View (at FloorPlan.js:12)
    ...

Am I doing something wrong? Is there any documentation or example on how to use ReactNativeZoomableView?

Event return values in documentation are wrong

Just FYI, in several places, the doc/README says things like:

{boolean} if this returns false, ZoomableView will not process the shift, otherwise it will

That's actually backwards...false (or no value) will process the event, and a "true" will cancel it.

PanResponde weird behavior if view is zoomed

Hey! So i have an ReactNativeZoomableView, and as a child a draggable component. (I can drag it with a PanResponder). If the image has no zoom it can move without any issues, but if I move it around while the image is zoomed theres a weird behavior, the component moves a lot more, for example. there is a 1.8 zoom, the draggable component is at the top of the screen, but if I move my finger to the middle, the component moves to the bottom of the screen. Is there any way to fix this?

Programatically move zoomed area

Hi,
I need to create something like minimap and when user clicks in minimap I need to move zoomed area to different position, is it possible somehow? Using ref or something like that?

How to shift the view?

Hi, I am reading the README but I do not quite understand how to shift the view. May I ask for help?

Incorrect return type in inde.d.ts

It looks like the return type for onZoomBefore, onZoomAfter and onZoomEnd is incorrect.

These types should be void instead of boolean

Move x and y while pinch zooming

I'm trying to use this component as a pinch to zoom component (similar to how Instagram works).

I figured out how to snap back on release, but I can't figure out how to make the component move in the x and y directions as the pinch moves.

Couple of questions

I just took a look at code and some questions come in my mind.

  1. In this line why you didn't use PureComponent to reduce unnecessary re-renderings?

  2. I'm not much familiar with PanResponder but is it possible to replace it with react-native-gesture-handler library to get smooth and robust gesture animation?

ComponentWillMount deprecated

Hi!
Thanks for this nice package, it suits my needs perfectly :-)
Recently I've been getting a warning message on my app though:

Warning: componentWillMount is deprecated and will be removed in the next major version. Use componentDidMount instead. As a temporary workaround, you can rename to UNSAFE_componentWillMount.

Please update the following components: ReactNativeZoomableView

Learn more about this warning here:
https://fb.me/react-async-component-lifecycle-hooks

Pinch gesture not working

I have a Twilio integration I want to let the user zoom in/out in the remote camera view.

<ReactNativeZoomableView
  maxZoom={3}
  minZoom={0.5}
  zoomStep={0.3}
  initialZoom={1}
  captureEvent
>
  <TwilioVideoParticipantView
    style={styles.remoteVideo}
    key={trackSid}
    trackIdentifier={trackIdentifier}
  />
</ReactNativeZoomableView>

Double-tap is working properly but the pinch gesture is not working for me. :/

"react-native": "~0.61.4"
"@dudigital/react-native-zoomable-view": "^1.0.15"

How to reset zoom value.

Hi
I was to reset the zoom level.The use case for which I am trying to do is If the view is already zoomed In and then user double tab the view it should reset to initial zoom level but is is not working as expected.Can you please suggest any solution.

<ReactNativeZoomableView
   maxZoom={1.5}
   minZoom={1}
   zoomStep={0.5}
   zoomEnabled={this.state.isEnabledZoom}
   initialZoom={this.state.initialZoom}
   bindToBorders={true}
 onDoubleTapAfter={(event, gestureState, zoomableViewEventObject)=>{


    if(this.state.initialZoom>1){
     this.setState({ initialZoom: 1,isEnabledZoom:false, scroll:true })
     }else{
     this.setState({ initialZoom:zoomableViewEventObject.zoomLevel,isEnabledZoom:true })
     }/>

This is what I am currently doing.
Thanks

yarn add command fails

yarn command fails with

error An unexpected error occurred: "expected hoisted manifest for \"@dudigital/react-native-zoomable-view#react-native#@react-native-community/cli#@react-native-community/cli-hermes\""

Missing Type definition in npm package

Type definition file does not exist in npm package that installed in a RN project. so importing in typescript projects causes error;

import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';

image

image

Cannot move / zoom when component placed in a modal and in front of other components

Hello,

I am currently using the component in a Modal and I have a problem when I try to move or zoom / dezoom the component.

It only occurs when I place my finger on a place where the component in the modal is in front of 2 components of the background page. I'm sorry for this terrible explanation but it is pretty hard to tell clearly what is the problem, so I've made this video to show it.

As you can see in the video, when I put my finger where the map is in the background or where the title area is (the blue are), I cannot interact with the component anymore. Here are the concerned areas drawn in orange :

Screenshot_20210616-143434

I've already tried to disable pointer events on the entire background page when the modal is open but still nothing happens when I interact with zoomable view in front of background components. I've also tried to log OnShiftingBefore and OnShiftingAfter events and both aren't called in the areas where the component isn't interactible with.

Here's the code :

<View style={styles.header}>
    /* Header content */
</View>
<View style={styles.main}>
    <View style={styles.carteContainer}>
        <Modal
            /* useless options for this exemple */
            transparent={true}
        >
            <View style={styles.containerModalContent}>
                /* Closing Modal Button */
                <View  style={{ height: props.CanvasSize.y/props.CanvasSize.x * 350 }}>
                    <ReactNativeZoomableView
                        zoomEnabled={true}
                        maxZoom={1.5}
                        minZoom={0.95}
                        zoomStep={0.25}
                        initialZoom={1}
                        bindToBorders={true}
                        style={{
                            height: props.CanvasSize.y/props.CanvasSize.x * 350,
                            width: props.CanvasSize.x/props.CanvasSize.y * 350,
                        }}
                        onZoomEnd={ResizeMapElements}
                        captureEvent={true}
                    >
                        <Map />
                    <ReactNativeZoomableView/>
                </View>
            </View>
        </Modal>
        <TouchableOpacity 
            style={styles.staticMap}
            onPress={() => {
                setOpenContainerModal(true);
            }}
        >
            <Map />
        </TouchableOpacity>
    /* bottom button */
    </View>
</View>

Any idea of what could block the interaction with the component in a modal?

Webpack complie error

Tried to use module in expo Framework, but got following error when trying to open in WebBrowser

Module parse failed: Unexpected token (66:19)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| * @type {number}
| */

longPressTimeout = null;
|
| /**

bindToBorders not working

When I zoom, the image just enlarges and covers the entire screen. Whether I use bindToBorders or try other workarounds like wrapping in different size views, I still get the same effect.

import React from "react";
import {
  Container,
  Text,
  Button,
  View,
  Icon,
  StyleProvider,
} from "native-base";
import {
  ImageBackground,
  Image,
  TouchableOpacity,
  TextInput,
  Modal,
  Dimensions,
} from "react-native";

import ImageZoom from "react-native-image-pan-zoom";

import ReactNativeZoomableView from "@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView";

import styles from "./ShotLoggerStyles";
import texts from "../../Style/texts";

import getTheme from "../../native-base-theme/components";
import marksmenOne from "../../native-base-theme/variables/marksmenOne";

import HeaderComponent from "../../Components/Header/Header";
import FooterComponent from "../../Components/Footer/FooterComponent";
import ChangeWeapon from "../../Components/ChangeWeapon";
import WeaponsModal from "../../Components/Modal/WeaponsModal";
import Loader from "../../Components/Loader/Loader";

const mainBG = require("../../assets/Backgrounds/metal.jpg");
const contentBG = require("../../assets/Backgrounds/training.jpg");

const ShotLoggerView = props => {
  const {
    leftPress,
    log,
    addShot,
    removeShot,
    updateShots,
    updateScore,
    changeWeaponHandler,
    _takeImageHandler,
    saveLog,
    weaponModalVisible,
    toggleWeaponModal,
    loading,
    displayHeight,
    logOutZoomState,
  } = props;

  return (
    <Container>
      <StyleProvider style={getTheme(marksmenOne)}>
        <ImageBackground source={mainBG} style={styles.mainBG}>
          <Loader visible={loading} />
          <HeaderComponent
            headerTitle="Logging Shots"
            leftPress={leftPress}
            leftAction="close"
          />
          <View style={styles.content}>
            {!log.image ? (
              <>
                <ChangeWeapon
                  weaponModalVisible={weaponModalVisible}
                  onChangeWeapon={changeWeaponHandler}
                  toggleWeaponModal={toggleWeaponModal}
                />
                <ImageBackground style={styles.noImage} source={contentBG}>
                  <Text style={texts.headerTitle}>
                    Take a picture of your target
                  </Text>

                  <Button
                    icon
                    style={styles.buttonPrimary}
                    onPress={() => _takeImageHandler()}
                  >
                    <Icon style={styles.buttonIcon} name="camera" />
                  </Button>
                </ImageBackground>
              </>
            ) : (
              <>
                <View style={styles.details}>
                  <View style={styles.detailsItem}>
                    <Text style={texts.bodyWhite}>Shots</Text>
                    <TextInput
                      style={styles.input}
                      defaultValue={log.shots.toString()}
                      editable={false}
                    />
                  </View>
                  <View style={styles.detailsItem}>
                    <Text style={texts.bodyWhite}>Score</Text>
                    <TextInput
                      style={styles.input}
                      onChangeText={value => updateScore(value)}
                      clearTextOnFocus
                      keyboardType="number-pad"
                      returnKeyType="done"
                    />
                  </View>
                </View>


                <View style={{ width: 300 }}>
                  <ReactNativeZoomableView
                    maxZoom={2.5}
                    minZoom={1}
                    zoomStep={0.5}
                    initialZoom={1}
                    bindToBorders={true}
                    // onZoomAfter={logOutZoomState}
                  >
                    <TouchableOpacity
                      activeOpacity={1}
                      style={styles.pointer}
                      onPress={evt => addShot(evt.nativeEvent)}
                    >
                      <View
                        style={[
                          styles.instructions,
                          log.heatmap.length > 0
                            ? { zIndex: -5 }
                            : { zIndex: 20 },
                        ]}
                      >
                        <Text style={texts.headerBody}>
                          Tap the picture to add &amp; remove shots.
                        </Text>
                      </View>

                      <Image
                        style={{ width: 300, height: 300 }}
                        source={{ uri: `data:image/jpg;base64,${log.image}` }}
                      />

                      {log.heatmap.length > 0 &&
                        log.heatmap.map((shot, index) => {
                          return (
                            <TouchableOpacity
                              key={index}
                              onPress={() => removeShot(index)}
                              style={[
                                styles.shot,
                                { left: shot.x - 10, top: shot.y - 10 },
                              ]}
                            />
                          );
                        })}
                    </TouchableOpacity>
                  </ReactNativeZoomableView>
                </View>
              </>
            )}
          </View>
          <FooterComponent
            rightAction={saveLog}
            rightActionText="Save shots"
            rightActionDisable={!log.image}
          />
        </ImageBackground>
      </StyleProvider>
    </Container>
  );
};

export default ShotLoggerView;

Calculate initial zoom

Hello people.

How do I get the initial zoom to fit my screen size?

Example:
My image is width 1080 (myimage.width)
My screen is width 375 (windowdimension.width )
And the scale is 3 (windowdimension.scale)

The calculation I'm doing is this:

const windowdimension = Dimensions.get('window');
const zoom = myimage.width / windowdimension.width / windowdimension.scale;
What returns 0.96

But it does not fit perfectly on the screen, it is much larger, if I check using the log and go down, the ideal scale should be 0.59, could someone help me?

Cannot pan the view while zoomed in

Hi,

I am trying to build a feature to pan and zoom the image using the ReactNativeZoomableView, and find that the zoomed in view cannot be moved around. The screenshots in the documentation illustrate this capability, so I download the code example and run in with latest expo SDK, and still cannot move the view as showed in the documentation.

The pan functionality is only working if I double tap to zoom in. If I pin-zoom the view, I am no longer able to pan the view unless I exit and re-enter the screen.

Could you please provide an example of how the view can be panned and moved? Thanks

LongPress dont work

The LongPress only work one time.
After work one time, it doesnt work more.

Not working when inside of panGestureHandler from 'react-native-gesture-handler'

In my RN 0.62.2 app, on top of swipe, the zoomable-view does not zoom. here is the code:

import { PanGestureHandler, State, TouchableOpacity, PinchGestureHandler } from "react-native-gesture-handler";  //ver 1.7
import FastImage from 'react-native-fast-image';
import {Button, Left, Right,  Icon, Input, Text, Header, Container, Content } from 'native-base';
import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView'; //ver 1.0.15

 return (
    <Container style={styles.container}>
        
        <Header>
            <Left>
                <Button transparent onPress={() => navigation.goBack()}>
                <Icon name="arrow-back-sharp" />
                </Button>
            </Left>
            
            <Right>
    
            </Right>
        </Header>
   
    <TouchableOpacity onPress={()=>navigation.goBack()}>  //<<==go back when click
        
    <PanGestureHandler {...gestureHandler}>  //<<==allow swipe the image horizontally left and right.
        <Animated.View style={styles.pan}>
        <Animated.View
            style={[{width: width * images.length, height, flexDirection: "row",}, { transform: [{ translateX }] }]}  //<<==animation over X
        >
            {images.map((img_source) => (  //<<==images is an array holding image data
            <View key={img_source.fileName} style={styles.picture}>
                <ReactNativeZoomableView  //<<==
                        maxZoom={3}
                        minZoom={1}
                        zoomStep={0.5}
                        initialZoom={1}
                        bindToBorders={true}
                        captureEvent={true}
                    >
                <FastImage 
                        source={{uri:img_source.path}} 
                        resizeMode={FastImage.resizeMode.contain} 
                        style={styles.image}
                    />
                    </ReactNativeZoomableView>
            </View>
            ))}
        </Animated.View>
        </Animated.View>
    </PanGestureHandler>

    </PinchGestureHandler> */}
    </TouchableOpacity>
    </Container>
  );
};

const styles = StyleSheet.create({
container: {
    ...StyleSheet.absoluteFillObject,  //<<==fill up all space under header
    backgroundColor: "black",
},
pan:{
    flexGrow:1,
},
picture: {
    flexGrow:1,
    overflow: "hidden",
},
image: {
    ...StyleSheet.absoluteFillObject,  //image noshow without this line
    width: undefined,
    height: undefined,
},
});

Swipe stops working as well.

React-native-zoomable-view in a swiper

So I hear from the README that this is a todo. I'd really love to have an example of that :) What all needs to be customized to get the gestures to play nice?

Scroll with two fingers

Hi. This library is great, thank you.

Just one thing: scrolling while zooming should be possible. That's the common behaviour if you zoom in chrome by example.

By other hand, in my case i'm not zooming a static image, but a drawing canvas. So, I'm disabling the one finger gestures like this:

handleMoveShouldSetPanResponder = (e, gestureState) => {
    return gestureState.numberActiveTouches === 2;
  };

However, doing that makes it impossible to scroll now. Because I can't scroll with two fingers.

ReactNativeZoomableView effects on children absolute positioning

I draw a graph in my application and I want to add zoom functionality to that graph. so I wrapped my graph elements into a ReactNativeZoomableView

the overall structure is something like this:

<ReactNativeZoomableView>
  <Svg>
    <Svg/>
    <Svg/>
    <Svg/>
    ...
  </Svg>
  <View/>
  <View/>
  <View/>
  ...
</ReactNativeZoomableView>

I place the Views on the screen by using absolute positions and draw the lines using react-native-svg.

The correct result must be like below (has taken from a 5.7" 720x1280 device)

Screenshot_2019-12-11-12-44-16

but for some unknown reason, it seems using ReactNativeZoomableView causes that the top absolute positions change about a fix constant value. the value is somehow related to device/emulator resolution. you can see a few samples of that

4.0" 480*800 hdpi
Screenshot_1576053203

5.0" 1080*1920 420dpi
Screenshot_1576056618

I tested it on android (with four devices and a few emulators with different screen sizes). I am not able to test the problem on IOS right now, so I can't confirm if the problem exists on the IOS platform or not.

is there any workaround for this issue?

Performance error when zooming

I am trying to get this package working on my Expo based app but when I zoom in or out it is very laggy and I get the following error in the console.

For reference I am using the exact same code used in the example, the only difference being I have a navigation bar set up

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the method `timeStamp` on a released/nullified synthetic event. This is a no-op function. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.

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.