Skip to content

Commit 0e87773

Browse files
committed
2 parents 3c71a83 + e733858 commit 0e87773

File tree

8 files changed

+117
-101
lines changed

8 files changed

+117
-101
lines changed

src/animated/Controller.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
interpolateTo,
1414
withDefault,
1515
toArray,
16-
getValues,
1716
callProp,
1817
is,
1918
} from '../shared/helpers'
@@ -329,7 +328,7 @@ export default class Controller {
329328

330329
if (this.hasChanged) {
331330
// Make animations available to frameloop
332-
this.configs = getValues(this.animations)
331+
this.configs = Object.values(this.animations)
333332
this.values = {}
334333
this.interpolations = {}
335334
for (let key in this.animations) {

src/animated/Interpolation.js renamed to src/animated/Interpolation.ts

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,80 @@
11
import * as Globals from './Globals'
22

3+
type ExtrapolateType = 'identity' | 'clamp' | 'extend'
4+
5+
type InputRange = number[]
6+
type OutputRange = number[] | string[]
7+
8+
/**
9+
* The config options for an interpolation.
10+
*/
11+
export type InterpolationConfig<In = number, Out = number | string> = {
12+
/**
13+
* @default 'extend'
14+
*/
15+
extrapolateLeft?: ExtrapolateType
16+
/**
17+
* @default 'extend'
18+
*/
19+
extrapolateRight?: ExtrapolateType
20+
/**
21+
* Shortcut to set `extrapolateLeft` and `extrapolateRight`
22+
* @default 'extend'
23+
*/
24+
extrapolate?: ExtrapolateType
25+
/**
26+
* Input ranges
27+
* @default [0,1]
28+
*/
29+
range: In[]
30+
output: Out[]
31+
map?: (value: number) => number
32+
easing?: (t: number) => number
33+
}
34+
35+
type Interpolator = (input: number) => number | string
36+
337
export default class Interpolation {
4-
// Default config = config, args
5-
// Short config = range, output, extrapolate
6-
static create(config, output, extra) {
7-
if (typeof config === 'function') return config
8-
else if (
9-
Globals.interpolation &&
10-
config.output &&
11-
typeof config.output[0] === 'string'
12-
)
13-
return Globals.interpolation(config)
14-
else if (Array.isArray(config))
38+
static create(interpolator: Interpolator): Interpolator
39+
static create(range: InputRange, output: OutputRange): Interpolator
40+
static create(config: InterpolationConfig): Interpolator
41+
static create(
42+
range: InputRange | InterpolationConfig | Interpolator,
43+
output?: OutputRange,
44+
extra?: ExtrapolateType
45+
): Interpolator {
46+
if (typeof range === 'function') {
47+
return range
48+
}
49+
if (Array.isArray(range)) {
1550
return Interpolation.create({
16-
range: config,
17-
output,
51+
range,
52+
output: output!,
1853
extrapolate: extra || 'extend',
1954
})
20-
55+
}
56+
if (Globals.interpolation && typeof range.output[0] === 'string') {
57+
return Globals.interpolation(range)
58+
}
59+
let config = range as InterpolationConfig<number, number>
2160
let outputRange = config.output
2261
let inputRange = config.range || [0, 1]
23-
let easing = config.easing || (t => t)
24-
let extrapolateLeft = 'extend'
62+
let easing = config.easing || ((t: number) => t)
63+
let extrapolateLeft: ExtrapolateType = 'extend'
2564
let map = config.map
2665

2766
if (config.extrapolateLeft !== undefined)
2867
extrapolateLeft = config.extrapolateLeft
2968
else if (config.extrapolate !== undefined)
3069
extrapolateLeft = config.extrapolate
3170

32-
let extrapolateRight = 'extend'
71+
let extrapolateRight: ExtrapolateType = 'extend'
3372
if (config.extrapolateRight !== undefined)
3473
extrapolateRight = config.extrapolateRight
3574
else if (config.extrapolate !== undefined)
3675
extrapolateRight = config.extrapolate
3776

38-
return input => {
77+
return (input: number) => {
3978
let range = findRange(input, inputRange)
4079
return interpolate(
4180
input,
@@ -53,15 +92,15 @@ export default class Interpolation {
5392
}
5493

5594
function interpolate(
56-
input,
57-
inputMin,
58-
inputMax,
59-
outputMin,
60-
outputMax,
61-
easing,
62-
extrapolateLeft,
63-
extrapolateRight,
64-
map
95+
input: number,
96+
inputMin: number,
97+
inputMax: number,
98+
outputMin: number,
99+
outputMax: number,
100+
easing: (t: number) => number,
101+
extrapolateLeft: ExtrapolateType,
102+
extrapolateRight: ExtrapolateType,
103+
map?: (x: number) => number
65104
) {
66105
let result = map ? map(input) : input
67106
// Extrapolate
@@ -88,7 +127,7 @@ function interpolate(
88127
return result
89128
}
90129

91-
function findRange(input, inputRange) {
130+
function findRange(input: number, inputRange: number[]) {
92131
for (var i = 1; i < inputRange.length - 1; ++i)
93132
if (inputRange[i] >= input) break
94133
return i - 1

src/shared/colorMatchers.js renamed to src/shared/colorMatchers.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22
const NUMBER = '[-+]?\\d*\\.?\\d+'
33
const PERCENTAGE = NUMBER + '%'
44

5-
function call() {
6-
return (
7-
'\\(\\s*(' +
8-
Array.prototype.slice.call(arguments).join(')\\s*,\\s*(') +
9-
')\\s*\\)'
10-
)
5+
function call(...parts: string[]) {
6+
return '\\(\\s*(' + parts.join(')\\s*,\\s*(') + ')\\s*\\)'
117
}
128

139
export const rgb = new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER))

src/shared/colors.js renamed to src/shared/colors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,6 @@ const colors = {
152152
yellowgreen: 0x9acd32ff,
153153
}
154154

155+
export type ColorName = keyof typeof colors
156+
155157
export default colors
File renamed without changes.

src/shared/helpers.js renamed to src/shared/helpers.ts

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import { useState, useCallback } from 'react'
2-
import AnimatedValue from '../animated/AnimatedValue'
3-
import AnimatedArray from '../animated/AnimatedArray'
1+
import { MutableRefObject, Ref, useCallback, useState } from 'react'
42

53
export const is = {
64
arr: Array.isArray,
7-
obj: a => Object.prototype.toString.call(a) === '[object Object]',
8-
fun: a => typeof a === 'function',
9-
str: a => typeof a === 'string',
10-
num: a => typeof a === 'number',
11-
und: a => a === void 0,
12-
nul: a => a === null,
13-
set: a => a instanceof Set,
14-
map: a => a instanceof Map,
15-
equ(a, b) {
5+
obj: (a: unknown): a is object =>
6+
Object.prototype.toString.call(a) === '[object Object]',
7+
fun: (a: unknown): a is Function => typeof a === 'function',
8+
str: (a: unknown): a is string => typeof a === 'string',
9+
num: (a: unknown): a is number => typeof a === 'number',
10+
und: (a: unknown): a is undefined => a === void 0,
11+
nul: (a: unknown): a is null => a === null,
12+
set: (a: unknown): a is Set<any> => a instanceof Set,
13+
map: (a: unknown): a is Map<any, any> => a instanceof Map,
14+
equ(a: any, b: any) {
1615
if (typeof a !== typeof b) return false
1716
if (is.str(a) || is.num(a)) return a === b
1817
if (
@@ -34,23 +33,22 @@ export function useForceUpdate() {
3433
return forceUpdate
3534
}
3635

37-
export function withDefault(value, defaultValue) {
36+
export function withDefault<T, DT>(value: T, defaultValue: DT) {
3837
return is.und(value) || is.nul(value) ? defaultValue : value
3938
}
4039

41-
export function toArray(a) {
40+
export function toArray<T>(a?: T | T[]): T[] {
4241
return !is.und(a) ? (is.arr(a) ? a : [a]) : []
4342
}
4443

45-
export function callProp(obj, ...args) {
44+
export function callProp<T>(
45+
obj: T,
46+
...args: any[]
47+
): T extends (...args: any[]) => infer R ? R : T {
4648
return is.fun(obj) ? obj(...args) : obj
4749
}
4850

49-
export function getValues(object) {
50-
return Object.keys(object).map(k => object[k])
51-
}
52-
53-
export function getForwardProps(props) {
51+
function getForwardProps(props: any) {
5452
const {
5553
to,
5654
from,
@@ -74,7 +72,7 @@ export function getForwardProps(props) {
7472
return forward
7573
}
7674

77-
export function interpolateTo(props) {
75+
export function interpolateTo(props: any) {
7876
const forward = getForwardProps(props)
7977
const rest = Object.keys(props).reduce(
8078
(a, k) => (!is.und(forward[k]) ? a : { ...a, [k]: props[k] }),
@@ -83,28 +81,13 @@ export function interpolateTo(props) {
8381
return { to: forward, ...rest }
8482
}
8583

86-
export function convertToAnimatedValue(acc, [name, value]) {
87-
return {
88-
...acc,
89-
[name]: new (is.arr(value) ? AnimatedArray : AnimatedValue)(value),
90-
}
91-
}
92-
93-
export function convertValues(props) {
94-
const { from, to, native } = props
95-
const allProps = Object.entries({ ...from, ...to })
96-
return native
97-
? allProps.reduce(convertToAnimatedValue, {})
98-
: { ...from, ...to }
99-
}
100-
101-
export function handleRef(ref, forward) {
84+
export function handleRef(ref: any, forward: Ref<any>) {
10285
if (forward) {
10386
// If it's a function, assume it's a ref callback
10487
if (is.fun(forward)) forward(ref)
10588
else if (is.obj(forward)) {
10689
// If it's an object and has a 'current' property, assume it's a ref object
107-
forward.current = ref
90+
;(forward as MutableRefObject<any>).current = ref
10891
}
10992
}
11093
return ref

src/shared/interpolation.js renamed to src/shared/interpolation.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import Interpolation from '../animated/Interpolation'
2-
import normalizeColor from './normalizeColors'
1+
import Interpolation, { InterpolationConfig } from '../animated/Interpolation'
32
import colors from './colors'
3+
import normalizeColor from './normalizeColors'
44

5-
function colorToRgba(input) {
5+
function colorToRgba(input: string) {
66
let int32Color = normalizeColor(input)
77
if (int32Color === null) return input
88
int32Color = int32Color || 0
@@ -31,43 +31,40 @@ const colorNamesRegex = new RegExp(`(${Object.keys(colors).join('|')})`, 'g')
3131
* -45deg // values with units
3232
* 0 2px 2px 0px rgba(0, 0, 0, 0.12) // box shadows
3333
*/
34-
export default function createInterpolation(config) {
34+
export default function createInterpolation(
35+
config: InterpolationConfig<number, string>
36+
) {
3537
// Replace colors with rgba
3638
const outputRange = config.output
3739
.map(rangeValue => rangeValue.replace(colorRegex, colorToRgba))
3840
.map(rangeValue => rangeValue.replace(colorNamesRegex, colorToRgba))
39-
// ->
40-
// [
41-
// [0, 50],
42-
// [100, 150],
43-
// [200, 250],
44-
// [0, 0.5],
45-
// ]
4641

47-
const outputRanges = outputRange[0].match(stringShapeRegex).map(() => [])
42+
const outputRanges: number[][] = outputRange[0]
43+
.match(stringShapeRegex)!
44+
.map(() => [])
4845
outputRange.forEach(value => {
4946
value
50-
.match(stringShapeRegex)
47+
.match(stringShapeRegex)!
5148
.forEach((number, i) => outputRanges[i].push(+number))
5249
})
5350
const interpolations = outputRange[0]
54-
.match(stringShapeRegex)
55-
.map((value, i) => {
51+
.match(stringShapeRegex)!
52+
.map((_value, i) => {
5653
return Interpolation.create({ ...config, output: outputRanges[i] })
5754
})
58-
return input => {
55+
return (input: number) => {
5956
let i = 0
6057
return (
6158
outputRange[0]
6259
// 'rgba(0, 100, 200, 0)'
6360
// ->
6461
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
65-
.replace(stringShapeRegex, () => interpolations[i++](input))
62+
.replace(stringShapeRegex, () => interpolations[i++](input) as string)
6663
// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
6764
// round the opacity (4th column).
6865
.replace(
6966
/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,
70-
(_, p1, p2, p3, p4) =>
67+
(_, p1: number, p2: number, p3: number, p4: number) =>
7168
`rgba(${Math.round(p1)}, ${Math.round(p2)}, ${Math.round(
7269
p3
7370
)}, ${p4})`

0 commit comments

Comments
 (0)