slideToPosition.ts 2.2 KB

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