React-native-gesture-handler: Reagir manipulador de gestos nativo que não funciona com modal no Android

Criado em 9 nov. 2018  ·  3Comentários  ·  Fonte: software-mansion/react-native-gesture-handler

`` `import React, {Component} de 'react';
import {Modal, StyleSheet, View, Dimensions} from 'react-native';
import {
PanGestureHandler,
Estado,
PinchGestureHandler,
} de 'reagir-nativo-gestor-manipulador';

import Animated, {Easing} de 'react-native-reanimated';
importar PropTypes de 'prop-types'

// setInterval (() => {
// deixe iters = 1e8,
// soma = 0;
// while (iters--> 0) sum + = iters;
//}, 300);

const {
definir,
cond,
eq,
ou,
adicionar,
sub,
Pancada,
min,
max,
depurar,
multiplicar,
dividir,
Menor que,
Primavera,
definiram,
decair,
cronometragem,
ligar,
diff,
acc,
não,
abdômen,
bloquear,
startClock,
stopClock,
clockRunning,
Valor,
Relógio,
evento,
} = Animado;

function scaleDiff (value) {
const tmp = novo valor (1);
prev prev = novo valor (1);
return [set (tmp, divide (value, prev)), set (prev, value), tmp];
}

function dragDiff (valor, atualização) {
const tmp = novo valor (0);
prev prev = novo valor (0);
return cond (
atualizando,
[definir (tmp, sub (valor, prev)), definir (prev, valor), tmp],
conjunto (anterior, 0)
);
}

// retorna o coeficiente de atrito linear. Quando value é 0 coeficiente é 1 (sem atrito), então
// cresce linearmente até atingir MAX_FRICTION quando value é igual
// para MAX_VALUE
fricção de função (valor) {
const MAX_FRICTION = 5;
const MAX_VALUE = 100;
return max (
1,
min (MAX_FRICTION, some (1, multiplique (valor, (MAX_FRICTION - 1) / MAX_VALUE)))
);
}

velocidade da função (valor) {
const clock = new Clock ();
const dt = diff (relógio);
retornar cond (menosThan (dt, 1), 0, multiplicar (1000, dividir (diff (valor), dt)));
}

const MIN_SCALE = 1;
const MAX_SCALE = 2;

function scaleRest (value) {
return cond (
lessThan (valor, MIN_SCALE),
MIN_SCALE,
cond (menos que (MAX_SCALE, valor), MAX_SCALE, valor)
);
}

function scaleFriction (value, rest, delta) {
const MAX_FRICTION = 20;
const MAX_VALUE = 0,5;
const res = multiplicação (valor, delta);
const howFar = abs (sub (repouso, valor));
fricção const = max (
1,
min (MAX_FRICTION, some (1, multiplique (howFar, (MAX_FRICTION - 1) / MAX_VALUE)))
);
return cond (
lessThan (0, howFar),
multiplicar (valor, adicionar (1, dividir (adicionar (delta, -1), fricção))),
res
);
}

function runTiming (clock, value, dest, startStopClock = true) {
estado const = {
acabado: novo valor (0),
posição: novo valor (0),
frameTime: novo valor (0),
tempo: novo valor (0),
};

const config = {
toValue: novo valor (0),
duração: 300,
easing: Easing.inOut (Easing.cubic),
};

Retorna [
cond (clockRunning (clock), 0, [
definido (estado finalizado, 0),
definir (state.frameTime, 0),
set (state.time, 0),
set (state.position, value),
set (config.toValue, dest),
startStopClock && startClock (clock),
]),
tempo (relógio, estado, configuração),
cond (state.finished, startStopClock && stopClock (clock)),
state.position,
];
}

function runDecay (clock, value, velocity) {
estado const = {
acabado: novo valor (0),
velocidade: novo valor (0),
posição: novo valor (0),
tempo: novo valor (0),
};

configuração const = {desaceleração: 0,99};

Retorna [
cond (clockRunning (clock), 0, [
definido (estado finalizado, 0),
set (state.velocity, velocity),
set (state.position, value),
set (state.time, 0),
startClock (clock),
]),
set (state.position, value),
decadência (relógio, estado, configuração),
cond (state.finished, stopClock (clock)),
state.position,
];
}

function bouncyPinch (
valor,
gesto,
gesto Ativo,
focalX,
displacementX,
focalY,
deslocamento Y
) {
const clock = new Clock ();

const delta = scaleDiff (gesto);
const rest = scaleRest (valor);
const focalXRest = cond (
lessThan (valor, 1),
0,
sub (displacementX, multiplique (focalX, add (-1, divide (rest, value))))
);
const focalYRest = cond (
lessThan (valor, 1),
0,
sub (deslocamentoY, multiplicar (focalY, adicionar (-1, dividir (repouso, valor))))
);
const nextScale = new Value (1);

return cond (
[delta, gesto ativo],
[
stopClock (relógio),
set (nextScale, scaleFriction (value, rest, delta)),
definir(
displacementX,
sub (displacementX, multiplique (focalX, add (-1, divide (nextScale, value))))
),
definir(
deslocamento Y,
sub (displacementY, multiplique (focalY, add (-1, divide (nextScale, value))))
),
nextScale,
],
cond (
ou (clockRunning (clock), não (eq (resto, valor))),
[
set (displacementX, runTiming (clock, displacementX, focalXRest, false)),
set (displacementY, runTiming (clock, displacementY, focalYRest, false)),
runTiming (clock, value, rest),
],
valor
)
);
}

function bouncy (
valor,
gestoDiv,
gesto Ativo,
lowerBound,
limite superior,
atrito
) {
const timingClock = new Clock ();
const decayClock = new Clock ();

velocidade const = velocidade (valor);

// o valor ultrapassou os limites (inferior, superior)
const isOutOfBounds = ou (
lessThan (value, lowerBound),
lessThan (upperBound, value)
);
// posição para ajustar (superior ou inferior está além ou o valor atual em outro lugar)
const rest = cond (
lessThan (value, lowerBound),
lowerBound,
cond (lessThan (upperBound, value), upperBound, value)
);
// quanto o valor excede os limites, isso é usado para calcular o atrito
const outOfBounds = abs (sub (repouso, valor));

return cond (
[GestO Div, velocidade, gesto Ativo],
[
stopClock (timingClock),
stopClock (decayClock),
add (value, divide (gestureDiv, friction (outOfBounds))),
],
cond (
ou (clockRunning (timingClock), isOutOfBounds),
[stopClock (decayClock), runTiming (timingClock, value, rest)],
cond (
ou (clockRunning (decayClock), lessThan (5, abs (velocidade))),
runDecay (decayClock, valor, velocidade),
valor
)
)
);
}

const WIDTH = 300;
const HEIGHT = 300;

classe Viewer extends Component {
pinchRef = React.createRef ();
panRef = React.createRef ();
construtor (adereços) {
super (adereços);

// DECLARE TRANSX
const panTransX = new Value(0);
const panTransY = new Value(0);

// PINCH
const pinchScale = new Value(1);
const pinchFocalX = new Value(0);
const pinchFocalY = new Value(0);
const pinchState = new Value(-1);

this._onPinchEvent = event([
  {
    nativeEvent: {
      state: pinchState,
      scale: pinchScale,
      focalX: pinchFocalX,
      focalY: pinchFocalY,
    },
  },
]);

// SCALE
const scale = new Value(1);
const pinchActive = eq(pinchState, State.ACTIVE);
this._focalDisplacementX = new Value(0);
const relativeFocalX = sub(
  pinchFocalX,
  add(panTransX, this._focalDisplacementX)
);
this._focalDisplacementY = new Value(0);
const relativeFocalY = sub(
  pinchFocalY,
  add(panTransY, this._focalDisplacementY)
);
this._scale = set(
  scale,
  bouncyPinch(
    scale,
    pinchScale,
    pinchActive,
    relativeFocalX,
    this._focalDisplacementX,
    relativeFocalY,
    this._focalDisplacementY
  )
);

// PAN
const dragX = new Value(0);
const dragY = new Value(0);
const panState = new Value(-1);
this._onPanEvent = event([
  {
    nativeEvent: {
      translationX: dragX,
      translationY: dragY,
      state: panState,
    },
  },
]);

const panActive = eq(panState, State.ACTIVE);
const panFriction = value => friction(value);

// X
const panUpX = cond(
  lessThan(this._scale, 1),
  0,
  multiply(-1, this._focalDisplacementX)
);
const panLowX = add(panUpX, multiply(-WIDTH, add(max(1, this._scale), -1)));
this._panTransX = set(
  panTransX,
  bouncy(
    panTransX,
    dragDiff(dragX, panActive),
    or(panActive, pinchActive),
    panLowX,
    panUpX,
    panFriction
  )
);

// Y
const panUpY = cond(
  lessThan(this._scale, 1),
  0,
  multiply(-1, this._focalDisplacementY)
);
const panLowY = add(
  panUpY,
  multiply(-HEIGHT, add(max(1, this._scale), -1))
);
this._panTransY = set(
  panTransY,
  bouncy(
    panTransY,
    dragDiff(dragY, panActive),
    or(panActive, pinchActive),
    panLowY,
    panUpY,
    panFriction
  )
);

}
render () {
// Os dois valores animados abaixo fazem com que a escala pareça estar concluída
// a partir do canto superior esquerdo da visualização da imagem em vez de seu centro. Esse
// é necessário para que a matemática do "ponto focal da escala" funcione corretamente
const scaleTopLeftFixX = divide (multiply (WIDTH, add (this._scale, -1)), 2);
const scaleTopLeftFixY = divide (multiply (HEIGHT, add (this._scale, -1)), 2);
Retorna (
ref = {this.pinchRef}
simultaneousHandlers = {this.panRef}
onGestureEvent = {this._onPinchEvent}
onHandlerStateChange = {this._onPinchEvent}>

ref = {this.panRef}
avgTouches
simultaneousHandlers = {this.pinchRef}
onGestureEvent = {this._onPanEvent}
onHandlerStateChange = {this._onPanEvent}>
estilo = {[
styles.image,
{
transformar: [
{translateX: this._panTransX},
{traduzirY: this._panTransY},
{translateX: this._focalDisplacementX},
{translateY: this._focalDisplacementY},
{translateX: scaleTopLeftFixX},
{translateY: scaleTopLeftFixY},
{escala: this._scale},
],
},
]}
resizeMode = "esticar"
source = {this.props.source}
/>




);
}
}

exportar a classe padrão ImageView extends Component {
render () {
Retorna (


);
}
}

ImageView.propTypes = {
im ageSource: PropTypes.any
};

estilos const = StyleSheet.create ({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '# F5FCFF',
},
embrulho: {
estouro: 'escondido',
},
imagem: {
largura: Dimensions.get ('janela'). largura,
altura: Dimensions.get ('janela'). altura,
backgroundColor: 'black',
},
}); `` `

Todos 3 comentários

Duplicado de # 139

use View em vez de Modal!

@yasahmed , em algum lugar como o meu projeto você deve usar o Modal porque algumas áreas absolutas estão na tela e o Pan deve aparecer no topo delas.

No meu caso devo usar o Modal, mas ainda não encontrei uma solução.

Esta página foi útil?
0 / 5 - 0 avaliações