on-scroll-handler.mjs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import { warnOnce } from 'motion-utils';
  2. import { updateScrollInfo } from './info.mjs';
  3. import { resolveOffsets } from './offsets/index.mjs';
  4. function measure(container, target = container, info) {
  5. /**
  6. * Find inset of target within scrollable container
  7. */
  8. info.x.targetOffset = 0;
  9. info.y.targetOffset = 0;
  10. if (target !== container) {
  11. let node = target;
  12. while (node && node !== container) {
  13. info.x.targetOffset += node.offsetLeft;
  14. info.y.targetOffset += node.offsetTop;
  15. node = node.offsetParent;
  16. }
  17. }
  18. info.x.targetLength =
  19. target === container ? target.scrollWidth : target.clientWidth;
  20. info.y.targetLength =
  21. target === container ? target.scrollHeight : target.clientHeight;
  22. info.x.containerLength = container.clientWidth;
  23. info.y.containerLength = container.clientHeight;
  24. /**
  25. * In development mode ensure scroll containers aren't position: static as this makes
  26. * it difficult to measure their relative positions.
  27. */
  28. if (process.env.NODE_ENV !== "production") {
  29. if (container && target && target !== container) {
  30. warnOnce(getComputedStyle(container).position !== "static", "Please ensure that the container has a non-static position, like 'relative', 'fixed', or 'absolute' to ensure scroll offset is calculated correctly.");
  31. }
  32. }
  33. }
  34. function createOnScrollHandler(element, onScroll, info, options = {}) {
  35. return {
  36. measure: () => measure(element, options.target, info),
  37. update: (time) => {
  38. updateScrollInfo(element, info, time);
  39. if (options.offset || options.target) {
  40. resolveOffsets(element, info, options);
  41. }
  42. },
  43. notify: () => onScroll(info),
  44. };
  45. }
  46. export { createOnScrollHandler };