Blame view

天文台pc/tianwentai-ui/node_modules/motion-dom/dist/es/utils/interpolate.mjs 2.51 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  import { invariant, clamp, MotionGlobalConfig, noop, pipe, progress } from 'motion-utils';
  import { mix } from './mix/index.mjs';
  
  function createMixers(output, ease, customMixer) {
      const mixers = [];
      const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
      const numMixers = output.length - 1;
      for (let i = 0; i < numMixers; i++) {
          let mixer = mixerFactory(output[i], output[i + 1]);
          if (ease) {
              const easingFunction = Array.isArray(ease) ? ease[i] || noop : ease;
              mixer = pipe(easingFunction, mixer);
          }
          mixers.push(mixer);
      }
      return mixers;
  }
  /**
   * Create a function that maps from a numerical input array to a generic output array.
   *
   * Accepts:
   *   - Numbers
   *   - Colors (hex, hsl, hsla, rgb, rgba)
   *   - Complex (combinations of one or more numbers or strings)
   *
   * ```jsx
   * const mixColor = interpolate([0, 1], ['#fff', '#000'])
   *
   * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
   * ```
   *
   * TODO Revisit this approach once we've moved to data models for values,
   * probably not needed to pregenerate mixer functions.
   *
   * @public
   */
  function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
      const inputLength = input.length;
      invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
      /**
       * If we're only provided a single input, we can just make a function
       * that returns the output.
       */
      if (inputLength === 1)
          return () => output[0];
      if (inputLength === 2 && output[0] === output[1])
          return () => output[1];
      const isZeroDeltaRange = input[0] === input[1];
      // If input runs highest -> lowest, reverse both arrays
      if (input[0] > input[inputLength - 1]) {
          input = [...input].reverse();
          output = [...output].reverse();
      }
      const mixers = createMixers(output, ease, mixer);
      const numMixers = mixers.length;
      const interpolator = (v) => {
          if (isZeroDeltaRange && v < input[0])
              return output[0];
          let i = 0;
          if (numMixers > 1) {
              for (; i < input.length - 2; i++) {
                  if (v < input[i + 1])
                      break;
              }
          }
          const progressInRange = progress(input[i], input[i + 1], v);
          return mixers[i](progressInRange);
      };
      return isClamp
          ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v))
          : interpolator;
  }
  
  export { interpolate };
  //# sourceMappingURL=interpolate.mjs.map