Giter VIP home page Giter VIP logo

Comments (11)

zhiqingchen avatar zhiqingchen commented on May 15, 2024 1

handleGesture={false}可禁用手势

from react-native-echarts.

zhiqingchen avatar zhiqingchen commented on May 15, 2024 1

try @wuba/[email protected]
@ekoooo

from react-native-echarts.

ekoooo avatar ekoooo commented on May 15, 2024 1

@zhiqingchen 你好,经过这边调试,确系是下面这个函数的问题

export function usePanResponder(
dispatchEvents: DispatchEvents
): [PanResponderInstance] {
const [zooming, setZooming] = useState(false);
const [moving, setMoving] = useState(false);
const pan = useRef({
initialX: 0,
initialY: 0,
prevDistance: 0,
});
const panResponder = useMemo(
() =>
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponder: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: ({ nativeEvent }) => {
dispatchEvents(['mousedown', 'mousemove'], nativeEvent);
},
onPanResponderMove: ({ nativeEvent }) => {
const touches = nativeEvent.touches;
const length = touches.length;
if (length === 1) {
if (!moving || zooming) {
setMoving(true);
setZooming(false);
} else {
dispatchEvents(['mousemove'], nativeEvent);
}
} else if (length === 2) {
const [
{ locationX: x0, locationY: y0 },
{ locationX: x1, locationY: y1 },
] = touches as [NativeTouchEvent, NativeTouchEvent];
const distance = calcDistance(x0, y0, x1, y1);
const { x, y } = calcCenter(x0, y0, x1, y1);
if (!zooming) {
pan.current = {
initialX: x,
initialY: y,
prevDistance: distance,
};
setZooming(true);
} else {
const { initialX, initialY, prevDistance } = pan.current;
const delta = distance - prevDistance;
pan.current.prevDistance = distance;
dispatchEvents(['mousewheel'], nativeEvent, {
zrX: initialX,
zrY: initialY,
zrDelta: delta / 120,
});
}
}
},
onPanResponderTerminationRequest: () => true,
onPanResponderRelease: ({ nativeEvent }) => {
if (!zooming) {
dispatchEvents(['mouseup', 'click'], nativeEvent);
}
setMoving(false);
setZooming(false);
},
onPanResponderTerminate: () => {},
onShouldBlockNativeResponder: () => {
return false;
},
}),
[dispatchEvents, moving, zooming, pan]
);
return [panResponder];
}

由于创建 panResponder 使用 useMemo 依赖了 moving, zooming, 从按下到滑动过程中 moving 的值发生变更,导致 PanResponder.create 重新创建,由于原始 panResponder 中有保存 InteractionManager.createInteractionHandle 返回的
handle 的信息,重新创建后保存的 handle 信息被清空,导致结束滑动时找不到 handle,所未能执行 InteractionManager.clearInteractionHandle 动作。

下面是在 PanResponder.js 中添加了打印 log 输入的结果:

debug2

解决方案:把下面 movingzooming 的定义由 useState 改为 useRef 的方式,避免重复 PanResponder.create

const [zooming, setZooming] = useState(false);
const [moving, setMoving] = useState(false);

更改后的打印日志信息:

debug3

这样就可以正常 InteractionManager.createInteractionHandle 了。

from react-native-echarts.

ekoooo avatar ekoooo commented on May 15, 2024

由于我使用图表只用于显示作用,直接用透明 View 遮住图表先暂时解决这个问题。

from react-native-echarts.

zhiqingchen avatar zhiqingchen commented on May 15, 2024

pie图单指滑动就会有这个错误吗?还是需要来开debug才会有?

from react-native-echarts.

zhiqingchen avatar zhiqingchen commented on May 15, 2024

修改后能运行的地方是?

from react-native-echarts.

ekoooo avatar ekoooo commented on May 15, 2024

pie图单指滑动就会有这个错误吗?还是需要来开debug才会有?

只要是滑动就会有这个问题,不一定要开 debug, 我修改 /node_modules/react-native/Libraries/Interaction/InteractionManager.js 这里的 debug 标志是为了能看清楚 log

from react-native-echarts.

ekoooo avatar ekoooo commented on May 15, 2024

修改后能运行的地方是?

修改了这个文件的代码

export function usePanResponder(
dispatchEvents: DispatchEvents
): [PanResponderInstance] {
const [zooming, setZooming] = useState(false);
const [moving, setMoving] = useState(false);
const pan = useRef({
initialX: 0,
initialY: 0,
prevDistance: 0,
});
const panResponder = useMemo(
() =>
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponder: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: ({ nativeEvent }) => {
dispatchEvents(['mousedown', 'mousemove'], nativeEvent);
},
onPanResponderMove: ({ nativeEvent }) => {
const touches = nativeEvent.touches;
const length = touches.length;
if (length === 1) {
if (!moving || zooming) {
setMoving(true);
setZooming(false);
} else {
dispatchEvents(['mousemove'], nativeEvent);
}
} else if (length === 2) {
const [
{ locationX: x0, locationY: y0 },
{ locationX: x1, locationY: y1 },
] = touches as [NativeTouchEvent, NativeTouchEvent];
const distance = calcDistance(x0, y0, x1, y1);
const { x, y } = calcCenter(x0, y0, x1, y1);
if (!zooming) {
pan.current = {
initialX: x,
initialY: y,
prevDistance: distance,
};
setZooming(true);
} else {
const { initialX, initialY, prevDistance } = pan.current;
const delta = distance - prevDistance;
pan.current.prevDistance = distance;
dispatchEvents(['mousewheel'], nativeEvent, {
zrX: initialX,
zrY: initialY,
zrDelta: delta / 120,
});
}
}
},
onPanResponderTerminationRequest: () => true,
onPanResponderRelease: ({ nativeEvent }) => {
if (!zooming) {
dispatchEvents(['mouseup', 'click'], nativeEvent);
}
setMoving(false);
setZooming(false);
},
onPanResponderTerminate: () => {},
onShouldBlockNativeResponder: () => {
return false;
},
}),
[dispatchEvents, moving, zooming, pan]
);
return [panResponder];
}

把这里

const panResponder = useMemo(

改成了下面的这样(只是简单的把 useMemo 改成了 useRef),就能正常的 InteractionManager: clear interaction handle

const panResponder = useRef(PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onStartShouldSetPanResponderCapture: () => true,
    onMoveShouldSetPanResponder: () => true,
    onMoveShouldSetPanResponderCapture: () => true,
    onPanResponderGrant: _ref2 => {
      let {
        nativeEvent
      } = _ref2;
      dispatchEvents(['mousedown', 'mousemove'], nativeEvent);
    },
    onPanResponderMove: _ref3 => {
      let {
        nativeEvent
      } = _ref3;
      const touches = nativeEvent.touches;
      const length = touches.length;
      if (length === 1) {
        if (!moving || zooming) {
          setMoving(true);
          setZooming(false);
        } else {
          dispatchEvents(['mousemove'], nativeEvent);
        }
      } else if (length === 2) {
        const [{
          locationX: x0,
          locationY: y0
        }, {
          locationX: x1,
          locationY: y1
        }] = touches;
        const distance = calcDistance(x0, y0, x1, y1);
        const {
          x,
          y
        } = calcCenter(x0, y0, x1, y1);
        if (!zooming) {
          pan.current = {
            initialX: x,
            initialY: y,
            prevDistance: distance
          };
          setZooming(true);
        } else {
          const {
            initialX,
            initialY,
            prevDistance
          } = pan.current;
          const delta = distance - prevDistance;
          pan.current.prevDistance = distance;
          dispatchEvents(['mousewheel'], nativeEvent, {
            zrX: initialX,
            zrY: initialY,
            zrDelta: delta / 120
          });
        }
      }
    },
    onPanResponderTerminationRequest: () => true,
    onPanResponderRelease: _ref4 => {
      let {
        nativeEvent
      } = _ref4;
      if (!zooming) {
        dispatchEvents(['mouseup', 'click'], nativeEvent);
      }
      setMoving(false);
      setZooming(false);
    },
    onPanResponderTerminate: () => {},
    onShouldBlockNativeResponder: () => {
      return false;
    }
  })).current;

from react-native-echarts.

zhiqingchen avatar zhiqingchen commented on May 15, 2024

可能的原因:
fram-x/FluidTransitions@2dfd40b
facebook/react-native#8624

from react-native-echarts.

zhiqingchen avatar zhiqingchen commented on May 15, 2024

@zhiqingchen 你好,经过这边调试,确系是下面这个函数的问题

export function usePanResponder(
dispatchEvents: DispatchEvents
): [PanResponderInstance] {
const [zooming, setZooming] = useState(false);
const [moving, setMoving] = useState(false);
const pan = useRef({
initialX: 0,
initialY: 0,
prevDistance: 0,
});
const panResponder = useMemo(
() =>
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponder: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: ({ nativeEvent }) => {
dispatchEvents(['mousedown', 'mousemove'], nativeEvent);
},
onPanResponderMove: ({ nativeEvent }) => {
const touches = nativeEvent.touches;
const length = touches.length;
if (length === 1) {
if (!moving || zooming) {
setMoving(true);
setZooming(false);
} else {
dispatchEvents(['mousemove'], nativeEvent);
}
} else if (length === 2) {
const [
{ locationX: x0, locationY: y0 },
{ locationX: x1, locationY: y1 },
] = touches as [NativeTouchEvent, NativeTouchEvent];
const distance = calcDistance(x0, y0, x1, y1);
const { x, y } = calcCenter(x0, y0, x1, y1);
if (!zooming) {
pan.current = {
initialX: x,
initialY: y,
prevDistance: distance,
};
setZooming(true);
} else {
const { initialX, initialY, prevDistance } = pan.current;
const delta = distance - prevDistance;
pan.current.prevDistance = distance;
dispatchEvents(['mousewheel'], nativeEvent, {
zrX: initialX,
zrY: initialY,
zrDelta: delta / 120,
});
}
}
},
onPanResponderTerminationRequest: () => true,
onPanResponderRelease: ({ nativeEvent }) => {
if (!zooming) {
dispatchEvents(['mouseup', 'click'], nativeEvent);
}
setMoving(false);
setZooming(false);
},
onPanResponderTerminate: () => {},
onShouldBlockNativeResponder: () => {
return false;
},
}),
[dispatchEvents, moving, zooming, pan]
);
return [panResponder];
}

由于创建 panResponder 使用 useMemo 依赖了 moving, zooming, 从按下到滑动过程中 moving 的值发生变更,导致 PanResponder.create 重新创建,由于原始 panResponder 中有保存 InteractionManager.createInteractionHandle 返回的

handle 的信息,重新创建后保存的 handle 信息被清空,导致结束滑动时找不到 handle,所未能执行 InteractionManager.clearInteractionHandle 动作。

下面是在 PanResponder.js 中添加了打印 log 输入的结果:

debug2

解决方案:把下面 movingzooming 的定义由 useState 改为 useRef 的方式,避免重复 PanResponder.create

const [zooming, setZooming] = useState(false);
const [moving, setMoving] = useState(false);

更改后的打印日志信息:

debug3

这样就可以正常 InteractionManager.createInteractionHandle 了。

是这个原因

from react-native-echarts.

ekoooo avatar ekoooo commented on May 15, 2024

try @wuba/[email protected] @ekoooo

经过测试没有问题了,感谢!

from react-native-echarts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.