slideToPosition.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { maxTouchTime, slideAcceleration } from '../variables';
  2. import { CloseEdgeEnum } from '../types';
  3. import { getClosedHorizontal, getClosedVertical } from './getCloseEdge';
  4. /**
  5. * 适应到合适的图片偏移量
  6. */
  7. const slideToPosition = ({
  8. x,
  9. y,
  10. lastX,
  11. lastY,
  12. width,
  13. height,
  14. scale,
  15. touchedTime,
  16. }: {
  17. x: number;
  18. y: number;
  19. lastX: number;
  20. lastY: number;
  21. width: number;
  22. height: number;
  23. scale: number;
  24. touchedTime: number;
  25. }): {
  26. x: number;
  27. y: number;
  28. } => {
  29. const moveTime = Date.now() - touchedTime;
  30. // 初始速度
  31. const speedX = (x - lastX) / moveTime;
  32. const speedY = (y - lastY) / moveTime;
  33. // 停下所消耗时间
  34. const slideTimeX = Math.abs(speedX / slideAcceleration);
  35. const slideTimeY = Math.abs(speedY / slideAcceleration);
  36. // 计划滑动位置
  37. const planX = Math.floor(x + speedX * slideTimeX);
  38. const planY = Math.floor(y + speedY * slideTimeY);
  39. let currentX = planX;
  40. let currentY = planY;
  41. const { innerWidth, innerHeight } = window;
  42. // 图片超出的长度
  43. const outOffsetX = (width * scale - innerWidth) / 2;
  44. const outOffsetY = (height * scale - innerHeight) / 2;
  45. const horizontalCloseEdge = getClosedHorizontal(planX, scale, width);
  46. const verticalCloseEdge = getClosedVertical(planY, scale, height);
  47. // x
  48. if (horizontalCloseEdge === CloseEdgeEnum.Small) {
  49. currentX = 0;
  50. } else if (horizontalCloseEdge === CloseEdgeEnum.Before) {
  51. currentX = outOffsetX;
  52. } else if (horizontalCloseEdge === CloseEdgeEnum.After) {
  53. currentX = -outOffsetX;
  54. }
  55. // y
  56. if (verticalCloseEdge === CloseEdgeEnum.Small) {
  57. currentY = 0;
  58. } else if (verticalCloseEdge === CloseEdgeEnum.Before) {
  59. currentY = outOffsetY;
  60. } else if (verticalCloseEdge === CloseEdgeEnum.After) {
  61. currentY = -outOffsetY;
  62. }
  63. // 时间过长
  64. if (
  65. moveTime >= maxTouchTime &&
  66. (horizontalCloseEdge === CloseEdgeEnum.Normal &&
  67. verticalCloseEdge === CloseEdgeEnum.Normal)
  68. ) {
  69. return {
  70. x,
  71. y,
  72. };
  73. }
  74. return {
  75. x: currentX,
  76. y: currentY,
  77. };
  78. };
  79. export default slideToPosition;