Почему «смещение» существует в React Native Panresponder? - PullRequest
0 голосов
/ 24 марта 2019

TL; DR : я использую код Panresponder из документов React Native и мне нужно помочь понять, почему используется значение 'offset', а не просто анимированное значение.

Полный вопрос :

Сценарий :

Я использую Panresponder в React Native для перетаскивания объектов по экрану.Я использую стандартный код из документов RN.

По сути, перетаскиваемый объект имеет анимированное значение позиции.Когда вы щелкаете объект, смещение этого анимированного значения устанавливается на анимированное значение, а анимированное значение устанавливается на ноль.При перетаскивании анимированное значение постепенно устанавливается равным величине того, насколько далеко оно было перемещено в этом жесте.Когда вы отпускаете объект, смещение добавляется к анимированному значению, а затем смещение устанавливается на ноль.

Пример:

Например, если объектначинается с позиции 0, затем изначально и анимированное значение, и смещение устанавливаются на 0. Если вы перетаскиваете объект на 100 пикселей, анимированное значение постепенно увеличивается с 0 до 100 при перетаскивании.Когда вы отпускаете, к анимированному значению добавляется нулевое смещение (поэтому ничего не происходит).Если вы щелкнете объект еще раз, смещение будет установлено на 100, а анимированное значение будет установлено на 0. Если вы перетащите объект еще на 50 пикселей, анимированное значение увеличится с 0 до 50. Когда вы отпустите объект, значение 100смещение добавляется к анимированному значению, которое становится равным 150, а смещение сбрасывается на ноль.

Таким образом, анимированное значение всегда содержит расстояние, перетаскиваемое в текущем жесте, при этом смещение сохраняетположение, в котором находился объект до начала текущего жеста перетаскивания, и когда вы отпускаете объект, это сохраненное значение смещения прикрепляется к анимированному значению, так что, когда объект находится в покое, анимированное значение содержит общее расстояние, на которое объектбыл перетащен всеми объединенными жестами.

Код:

Вот код, который я использую для этого:

this.animatedValue.addListener((value) => this._value = value); // Make this._value hold the value of this.animatedValue (essentially extract the x and y values from the more complex animatedValue)
this.panResponder = PanResponder.create({
    onPanResponderGrant: () => { // When user clicks to initiate drag
        this.animatedValue.setOffset({ // Save 'distance dragged so far' in offset
            x: this._value.x,
            y: this._value.y,
        })
        this.animatedValue.setValue({ x: 0, y: 0}) // Set this.animatedValue to (0, 0) so that it will hold only 'distance so far in current gesture'
    },
    onPanResponderMove: Animated.event([ // As object is dragged, continually update animatedValue
        null, { dx: this.animatedValue.x, dy: this.animatedValue.y}
    ]),
    onPanResponderRelease: (e, gestureState) => { // On release, add offset to animatedValue and re-set offset to zero.
        this.animatedValue.flattenOffset();
    }
}

Мой вопрос:

Этот код работает отлично.Когда я не понимаю, зачем нам смещение?Почему мы должны сбрасывать анимированное значение на ноль при каждом новом жесте, сохранять его значение в смещении и повторно добавлять его к анимированному значению после его перетаскивания?Когда объект отпущен, он в конечном итоге просто перетаскивает общее расстояние, так почему бы просто не использовать анимированное значение и , а не использовать смещение?В моем примере выше, почему бы просто не увеличить анимированное значение до 100 при его перетаскивании на 100px, а затем при повторном нажатии и перетаскивании обновлять анимированное значение?

Возможное решение:

Единственное преимущество, которое я могу придумать, используя смещение, это то, что animatedValue теперь позволяет вам отслеживать «расстояние до текущего жеста», а не просто «общее расстояние до всех комбинированных жестов».».Возможен сценарий, в котором вам нужно значение «расстояние до сих пор в текущем жесте», поэтому мне интересно, является ли это единственной причиной когда-либо использовать смещение, или есть более фундаментальная причина, по которой я упускаю, почему мыследует использовать его все время?

Любое понимание было бы здорово.

Спасибо!

1 Ответ

0 голосов
/ 03 мая 2019

Поскольку лучше, чтобы состояние всего анимированного значения было автономным, чтобы вы могли передать его значение преобразованию.Конечно, может быть, вам не нужно «общее пройденное расстояние», в этом случае, ну, не используйте смещения, но если вы это сделаете, лучше использовать смещение AnimatedValue.

Позвольте мне показать вам, почемуКодируя пример отслеживания общего расстояния, пройденного между касаниями, без использования встроенного смещения:

this.offsetValue = {x: 0, y:0};
this.panResponder = PanResponder.create({
    onPanResponderGrant: () => { // When user clicks to initiate drag
        this.animatedValue.setValue({ x: 0, y: 0}) // Set this.animatedValue to (0, 0) so that it will hold only 'distance so far in current gesture'
    },
    onPanResponderMove: Animated.event([ // As object is dragged, continually update animatedValue
        null, { dx: this.animatedValue.x, dy: this.animatedValue.y}
    ]),
    onPanResponderRelease: (e, gestureState) => {
        // Set the offset to the current position
        this.offsetValue = {x: gestureState.dx, y: gestureState.dy}
        // Reset our animatedvalue since the offset is now all good
        this.animatedValue.setValue({ x: 0, y: 0})
    }
}

Это работает, и теперь кода меньше, теперь у вас есть исходное значение для текущего касания в Animated.Значение и, если вы хотите общее расстояние, вы можете использовать this.offsetValue.Кроме ... как вы применяете это, чтобы точно получить общее расстояние?Вы можете подумать, что можете сделать это:

<Animated.View
  style={{
    transform: [
      { translateX: this.offset.x + this.animatedValue.x },
      { translateY: this.offset.y + this.animatedValue.y },
    ],
  }}
  {...this.panResponder.panHandlers}
/>

Но это будет ошибкой, потому что animatedValue.x не является числом, очевидно.Вы можете использовать ._value напрямую, но тогда какой смысл использовать Animated?Вся идея в том, что вы можете передать один анимированный объект в свойство transform.Вот почему вы просто используете внутреннее смещение объекта.

...