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

inverting touch point

Open coado opened this issue 1 year ago • 0 comments

Summary:

This is a continuation of solving this issue, which was partially solved here. The PR introduces calculating matrix inverse that is optimized for 4x4 affine transformations. It's divided into three main parts: calculating determinant inverse, 3x3 matrix inverse, and translation inverse. The 3x3 matrix inverse calculation algorithm is based on David G. Simpson's implementation from Nasa https://caps.gsfc.nasa.gov/simpson/software/m33inv_f90.txt.

For now I've removed the part of the code that checks specifically for vertical and horizontal transformation, but I have an idea to bring it back in the Invert function, which could speed up in these cases (I think we can do the same for rotations).

Currently, it's not possible to click on View outside of its parent bounds. I can add the check that will traverse down the tree if the component has any overflowing children.

Should I close my previous draft to this issue?

Cc: @realsoelynn

Changelog:

[IOS][FIXED] - inverting touch point in findNodeAtPoint

Test Plan:

extended examples from this reproducer: https://github.com/realsoelynn/rn-inspectortools-transform-related-reproducer

import React from 'react';
import type {PropsWithChildren} from 'react';
import {
  Pressable,
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

type SectionProps = PropsWithChildren<{
  title: string;
}>;

function Section({children, title}: SectionProps): React.JSX.Element {
  return (
    <View style={styles.sectionContainer}>
      <Text style={styles.sectionTitle}>{title}</Text>
      <View style={{backgroundColor: '#808080'}}>{children}</View>
    </View>
  );
}

type ItemProps = PropsWithChildren<{
  title: string;
}>;

function Item({title}: ItemProps): React.JSX.Element {
  return (
    <Pressable
      style={styles.item}
      onPress={() => console.log(title + ' pressed.')}>
      <Text>{title}</Text>
    </Pressable>
  );
}

function App(): React.JSX.Element {
  return (
    <SafeAreaView>
      <ScrollView>
        <Section title="Nested Transform Example">
          <View
            style={{
              transform: [{translateX: 100}, {rotate: '90deg'}],
              width: '200',
            }}>
            <View
              style={{
                transform: [{scaleY: -1}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
          </View>
        </Section>

        <Section title="Rotation Transform Example">
            <View
              style={{
                transform: [{rotate: '45deg'}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>

        <Section title="Scale Transform Example">
            <View
              style={{
                transform: [{scale: 1.2}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>


        <Section title="Translate X Transform Example">
            <View
              style={{
                transform: [{translateX: 100}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>

        <Section title="Translate Y Transform Example">
            <View
              style={{
                transform: [{translateY: 30}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>

        <Section title="Skew Transform Example">
            <View
              style={{
                transform: [{skewX: '20deg'}, {skewY: '20deg'}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>

        <Section title="Projection Transform Example">
            <View
              style={{
                transform: [{perspective: 400}, {rotateY: '50deg'}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
        </Section>

        <Section title="Inverted ScrollView Example">
          <ScrollView
            contentInsetAdjustmentBehavior="automatic"
            style={{
              transform: [{scaleY: -1}],
            }}>
            <Item title="Item 1" />
            <Item title="Item 2" />
            <Item title="Item 3" />
          </ScrollView>
        </Section>

        <Section title="Inverted Parent View Example">
          <View
            style={{
              transform: [{scaleY: -1}],
            }}>
            <Item title="Item 1" />
            <Item title="Item 2" />
            <Item title="Item 3" />
          </View>
        </Section>

        <Section title="Double Inversion Example">
          <View
            style={{
              transform: [{rotateY: '180deg'}],
            }}>
            <View
              style={{
                transform: [{scaleY: -1}],
              }}>
              <Item title="Item 1" />
              <Item title="Item 2" />
              <Item title="Item 3" />
            </View>
          </View>
        </Section>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: '600',
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
    width: '50%',
  },
  sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: '400',
  },
  highlight: {
    fontWeight: '700',
  },
});

export default App;

coado avatar Aug 19 '24 14:08 coado