keyframes.mjs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { easeInOut } from '../../easing/ease.mjs';
  2. import { isEasingArray } from '../../easing/utils/is-easing-array.mjs';
  3. import { easingDefinitionToFunction } from '../../easing/utils/map.mjs';
  4. import { interpolate } from '../../utils/interpolate.mjs';
  5. import { defaultOffset } from '../../utils/offsets/default.mjs';
  6. import { convertOffsetToTimes } from '../../utils/offsets/time.mjs';
  7. function defaultEasing(values, easing) {
  8. return values.map(() => easing || easeInOut).splice(0, values.length - 1);
  9. }
  10. function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "easeInOut", }) {
  11. /**
  12. * Easing functions can be externally defined as strings. Here we convert them
  13. * into actual functions.
  14. */
  15. const easingFunctions = isEasingArray(ease)
  16. ? ease.map(easingDefinitionToFunction)
  17. : easingDefinitionToFunction(ease);
  18. /**
  19. * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
  20. * to reduce GC during animation.
  21. */
  22. const state = {
  23. done: false,
  24. value: keyframeValues[0],
  25. };
  26. /**
  27. * Create a times array based on the provided 0-1 offsets
  28. */
  29. const absoluteTimes = convertOffsetToTimes(
  30. // Only use the provided offsets if they're the correct length
  31. // TODO Maybe we should warn here if there's a length mismatch
  32. times && times.length === keyframeValues.length
  33. ? times
  34. : defaultOffset(keyframeValues), duration);
  35. const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
  36. ease: Array.isArray(easingFunctions)
  37. ? easingFunctions
  38. : defaultEasing(keyframeValues, easingFunctions),
  39. });
  40. return {
  41. calculatedDuration: duration,
  42. next: (t) => {
  43. state.value = mapTimeToKeyframe(t);
  44. state.done = t >= duration;
  45. return state;
  46. },
  47. };
  48. }
  49. export { defaultEasing, keyframes };