react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Problem with scaling and onPanResponderMove

Open AssimDelteil opened this issue 4 years ago • 2 comments

Description

Iam making a canvas Component that I can move with 1 finger and move/rotate/scale with 2 fingers. My canvas's size is 200x200. In the onPanResponderMove: (event, gestureState) function I use event.nativeEvent.touches[<0 or 1>].location<X or Y> Printing those values gave me the expected ones (0x0 on top left and 200x200 on bottom right, regardless of the number of finger and the order of touches)

Then I scaled my canvas by 1.5 using style={..., [transform:[{scale: 1.5}] ]} There was no problem with 1 finger but with 2 finger the second finger's .location<X or Y> is messed up. When I put my first finger on bottom right and then the second at top left I get 200x200 (okay) and -100x-100 (wtf) I the opposite side when I put my first finger on top left and then the second at bottom right I get 0x0 (okay) and 300x300 (wtf) I think thats a bug, if not sorry iam a beginner. Is there another way to code what I want ?

React Native version: (Result of 'react-native info')

info Fetching system and libraries information... (node:16140) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency (Use node --trace-warnings ... to show where the warning was created) System: OS: Windows 10 10.0.19042 CPU: (8) x64 Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz Memory: 2.33 GB / 7.86 GB Binaries: Node: 14.15.0 - D:\Programmes\node.EXE Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD npm: 6.14.8 - D:\Programmes\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: 29 Build Tools: 29.0.2 System Images: android-30 | Google APIs Intel x86 Atom_64 Android NDK: Not Found Windows SDK: Not Found IDEs: Android Studio: Not Found Visual Studio: 16.7.30621.155 (Visual Studio Community�2019), 16.7.30611.23 (Visual Studio Professional�2019) Languages: Java: 16.0.1 npmPackages: @react-native-community/cli: Not Found react: 17.0.1 => 17.0.1 react-native: 0.64.2 => 0.64.2 react-native-windows: Not Found npmGlobalPackages: react-native: Not Found

And iam using an Honor View 20 (PCT_L29) (on android 10)

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Copy the code bellow (App.js and Components/Test.js)
  2. Download a square image to put in the Images folder and change the require at the image's source (I don't know if you get the same results as me on other phones or on emulator)

Expected Results

Touch bottom right with one finger -> get 200x200 in the console Touch top left with one finger -> get 0x0 in the console Touch top left with your first finger then touch bottom right with your second finger -> get 0x0 and 300x300 Touch bottom right with your first finger then touch top left with your second finger -> get 200x200 and -100x-100

Snack, code example, screenshot, or link to a repository:

Test.js:

import React from 'react';
import {StyleSheet, View, Image, PanResponder, Dimensions} from 'react-native';

export default class Test extends React.Component{
  constructor(props) {
    super(props)

    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => true,

      onPanResponderMove: (evt, gestureState) => {
        let touches = evt.nativeEvent.touches;
        //If the number of finger on my canvas changes
        if(touches.length !== this.nb_touches){
          this._onNbToucheChange(touches)
        }
      },

      onPanResponderRelease:(evt, gestureState) =>{
        this.nb_touches = 0 
      }
    })
  }

  //Number of fingers on my canvas
  nb_touches=0

  //Array of the first touches's coordonates (n fingers -> n elem)
  firstTouch=[]

  _onNbToucheChange(touches){
    //1 finger
    if(touches.length == 1){
      this.firstTouch = [[touches[0].locationX, touches[0].locationY]]
      console.log("1 finger: ",this.firstTouch)
    }
    //2 finger
    if(touches.length == 2){
      this.firstTouch = [[touches[0].locationX, touches[0].locationY],[touches[1].locationX, touches[1].locationY]]
      console.log("2 fingers: ",this.firstTouch)
    }
    this.nb_touches = touches.length
  }

  render(){
    return(
      <View
      style={styles.canvas}>
        <Image  
        {...this.panResponder.panHandlers}
        style={[styles.square, {transform:[{scale: 1.5}] }]} 
        source={require("../Images/square.png")}/>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  canvas: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  square:{
    width:200,
    height:200,
  },
})

App.js

import React from 'react';
import { StyleSheet} from 'react-native';
import Test from "./Components/Test"

export default class App extends React.Component {
  render(){
    return (
      <Test/>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

AssimDelteil avatar Jun 08 '21 16:06 AssimDelteil

Hello its me again. I found a solution: put the scale in the state and scaling with height/width:200*this.state.scale instead of scale: this.state.scale It give me the correct values

AssimDelteil avatar Jun 09 '21 07:06 AssimDelteil

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Feb 07 '24 05:02 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Feb 14 '24 05:02 github-actions[bot]