Skip to content

Commit

Permalink
feat: learned Fling gesture and applied for better performance
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreBellas committed May 3, 2024
1 parent 961957e commit c4b4748
Showing 1 changed file with 41 additions and 51 deletions.
92 changes: 41 additions & 51 deletions src/views/Game/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import {
import { IDirection } from '@interfaces/direction'
import BoardDatabaseService from '@services/database/board.database'
import { RotateCcw } from 'lucide-react-native'
import { useEffect, useState } from 'react'
import { useEffect } from 'react'
import { Alert, Platform } from 'react-native'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import { useSharedValue } from 'react-native-reanimated'
import {
Directions,
Gesture,
GestureDetector,
} from 'react-native-gesture-handler'

import Tile from './Tile'

Expand All @@ -24,66 +27,53 @@ export default function Board() {
const boardDispatch = useBoardDispatch()
// #endregion

const [isMoveInTimeout, setIsMoveInTimeout] = useState(false)

// #region Constant values
const space = 'md'
const moveTimeout = 100
// #endregion

// #region Animation
const startXSlide = useSharedValue<number | null>(null)
const startYSlide = useSharedValue<number | null>(null)

const pan = Gesture.Pan()
.activeOffsetX([-80, 80])
.activeOffsetY([-80, 80])
const rightFlingGesture = Gesture.Fling()
.direction(Directions.RIGHT)
.numberOfPointers(1)
.shouldCancelWhenOutside(true)
.onStart((e) => {
startXSlide.value = e.x
startYSlide.value = e.y
.runOnJS(true)
.onEnd(() => {
boardDispatch({ type: 'move', direction: 'right' })
})
.onEnd((e) => {
if (isMoveInTimeout) return

const dx = e.x - (startXSlide.value ?? 0)
const dy = e.y - (startYSlide.value ?? 0)
if (dx === 0 && dy === 0) return

let boardAction: { type: 'move'; direction: IDirection }

if (Math.abs(dx) > Math.abs(dy)) {
boardAction =
dx > 0
? { type: 'move', direction: 'right' }
: { type: 'move', direction: 'left' }
} else {
boardAction =
dy > 0
? { type: 'move', direction: 'down' }
: { type: 'move', direction: 'up' }
}

setIsMoveInTimeout(true)
boardDispatch(boardAction)
const leftFlingGesture = Gesture.Fling()
.direction(Directions.LEFT)
.numberOfPointers(1)
.shouldCancelWhenOutside(true)
.runOnJS(true)
.onEnd(() => {
boardDispatch({ type: 'move', direction: 'left' })
})
const upFlingGesture = Gesture.Fling()
.direction(Directions.UP)
.numberOfPointers(1)
.shouldCancelWhenOutside(true)
.runOnJS(true)
.onEnd(() => {
boardDispatch({ type: 'move', direction: 'up' })
})
.onFinalize(() => {
startXSlide.value = null
startYSlide.value = null
const downFlingGesture = Gesture.Fling()
.direction(Directions.DOWN)
.numberOfPointers(1)
.shouldCancelWhenOutside(true)
.runOnJS(true)
.onEnd(() => {
boardDispatch({ type: 'move', direction: 'down' })
})
const moveGesture = Gesture.Race(
rightFlingGesture,
leftFlingGesture,
upFlingGesture,
downFlingGesture,
)
// #endregion

// #region Effects

// onMoveTimeout
useEffect(() => {
if (!isMoveInTimeout) return

setTimeout(() => {
setIsMoveInTimeout(false)
}, moveTimeout)
}, [isMoveInTimeout])

// onKeyboardMove
useEffect(() => {
if (Platform.OS !== 'web') return
Expand Down Expand Up @@ -158,7 +148,7 @@ export default function Board() {
// #endregion

return (
<GestureDetector gesture={pan}>
<GestureDetector gesture={moveGesture}>
<Box alignItems="center" width="$full">
<View w="$full" alignItems="flex-end">
<Button
Expand Down

0 comments on commit c4b4748

Please sign in to comment.