vendor: 3,916 bytes, lines 1-155
1import converter from '../converter.js'; 2import { getMode } from '../modes.js'; 3import normalizePositions from '../util/normalizePositions.js'; 4import easingMidpoint from '../easing/midpoint.js'; 5import { mapper, mapAlphaMultiply, mapAlphaDivide } from '../map.js'; 6 7const isfn = o => typeof o === 'function'; 8const isobj = o => o && typeof o === 'object'; 9const isnum = o => typeof o === 'number'; 10 11const interpolate_fn = (colors, mode = 'rgb', overrides, premap) => { 12 let def = getMode(mode); 13 let conv = converter(mode); 14 15 let conv_colors = []; 16 let positions = []; 17 let fns = {}; 18 19 colors.forEach(val => { 20 if (Array.isArray(val)) { 21 conv_colors.push(conv(val[0])); 22 positions.push(val[1]); 23 } else if (isnum(val) || isfn(val)) { 24 // Color interpolation hint or easing function 25 fns[positions.length] = val; 26 } else { 27 conv_colors.push(conv(val)); 28 positions.push(undefined); 29 } 30 }); 31 32 normalizePositions(positions); 33 34 // override the default interpolators 35 // from the color space definition with any custom ones 36 let fixed = def.channels.reduce((res, ch) => { 37 let ffn; 38 if (isobj(overrides) && isobj(overrides[ch]) && overrides[ch].fixup) { 39 ffn = overrides[ch].fixup; 40 } else if (isobj(def.interpolate[ch]) && def.interpolate[ch].fixup) { 41 ffn = def.interpolate[ch].fixup; 42 } else { 43 ffn = v => v; 44 } 45 res[ch] = ffn(conv_colors.map(color => color[ch])); 46 return res; 47 }, {}); 48 49 if (premap) { 50 let ccolors = conv_colors.map((color, idx) => { 51 return def.channels.reduce( 52 (c, ch) => { 53 c[ch] = fixed[ch][idx]; 54 return c; 55 }, 56 { mode } 57 ); 58 }); 59 fixed = def.channels.reduce((res, ch) => { 60 res[ch] = ccolors.map(c => { 61 let v = premap(c[ch], ch, c, mode); 62 return isNaN(v) ? undefined : v; 63 }); 64 return res; 65 }, {}); 66 } 67 68 let interpolators = def.channels.reduce((res, ch) => { 69 let ifn; 70 if (isfn(overrides)) { 71 ifn = overrides; 72 } else if (isobj(overrides) && isfn(overrides[ch])) { 73 ifn = overrides[ch]; 74 } else if ( 75 isobj(overrides) && 76 isobj(overrides[ch]) && 77 overrides[ch].use 78 ) { 79 ifn = overrides[ch].use; 80 } else if (isfn(def.interpolate[ch])) { 81 ifn = def.interpolate[ch]; 82 } else if (isobj(def.interpolate[ch])) { 83 ifn = def.interpolate[ch].use; 84 } 85 86 res[ch] = ifn(fixed[ch]); 87 return res; 88 }, {}); 89 90 let n = conv_colors.length - 1; 91 92 return t => { 93 // clamp t to the [0, 1] interval 94 t = Math.min(Math.max(0, t), 1); 95 96 if (t <= positions[0]) { 97 return conv_colors[0]; 98 } 99 100 if (t > positions[n]) { 101 return conv_colors[n]; 102 } 103 104 // Convert `t` from [0, 1] to `t0` between the appropriate two colors. 105 // First, look for the two colors between which `t` is located. 106 // Note: this can be optimized by searching for the index 107 // through bisection instead of start-to-end. 108 let idx = 0; 109 while (positions[idx] < t) idx++; 110 let start = positions[idx - 1]; 111 let delta = positions[idx] - start; 112 113 let P = (t - start) / delta; 114 115 // use either the local easing, or the global easing, if any 116 let fn = fns[idx] || fns[0]; 117 if (fn !== undefined) { 118 if (isnum(fn)) { 119 fn = easingMidpoint((fn - start) / delta); 120 } 121 P = fn(P); 122 } 123 124 let t0 = (idx - 1 + P) / n; 125 126 return def.channels.reduce( 127 (res, channel) => { 128 let val = interpolators[channel](t0); 129 if (val !== undefined) { 130 res[channel] = val; 131 } 132 return res; 133 }, 134 { mode } 135 ); 136 }; 137}; 138 139const interpolate = (colors, mode = 'rgb', overrides) => 140 interpolate_fn(colors, mode, overrides); 141 142const interpolateWith = 143 (premap, postmap) => 144 (colors, mode = 'rgb', overrides) => { 145 let post = postmap ? mapper(postmap, mode) : undefined; 146 let it = interpolate_fn(colors, mode, overrides, premap); 147 return post ? t => post(it(t)) : it; 148 }; 149 150const interpolateWithPremultipliedAlpha = interpolateWith( 151 mapAlphaMultiply, 152 mapAlphaDivide 153); 154 155export { interpolate, interpolateWith, interpolateWithPremultipliedAlpha };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.