Skip to content

Commit 175853b

Browse files
authored
Merge pull request #6 from codepunkt/next
Ability to work with numeric css units (Fixes #2)
2 parents a112ae7 + f55ef33 commit 175853b

14 files changed

+611
-592
lines changed

README.md

+66-31
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,21 @@
55
[![Code Coverage](https://img.shields.io/coveralls/codepunkt/css-spring.svg?style=flat&label=Code%20Coverage)](https://coveralls.io/github/codepunkt/css-spring?branch=master)
66
[![MIT License](https://img.shields.io/npm/l/css-spring.svg?style=flat&label=License)](http://opensource.org/licenses/MIT)
77

8-
Generate physics based css-keyframe animations.
8+
Generate physics based css-keyframe animations for the css-in-js solution of your choice or plain css.
99

1010
<table>
1111
<tr>
1212
<td>
1313
<pre lang="javascript">
14-
import spring, { format } from 'css-spring'
14+
import spring, { toString } from 'css-spring'
1515

1616
const keyframes = spring(
17-
{ left: 0 },
18-
{ left: 250 },
17+
{ left: '0px', opacity: 0 },
18+
{ left: '250px', opacity: 1 },
1919
{ preset: 'wobbly', precision: 5 }
2020
)
2121

22-
const moveLeft = format(
23-
keyframes,
24-
format.PX_FORMATTER
25-
)
22+
const keyframeString = toString(keyframes)
2623
</pre>
2724
</td>
2825
<td>
@@ -39,14 +36,14 @@ const moveLeft = format(
3936
- [glamor](#glamor)
4037
- [API](#api)
4138
- [spring(start, target, options)](#springstart-target-options)
42-
- [format(keyframes, formatter)](#formatkeyframes-formatter)
39+
- [toString(keyframes, formatter)](#tostringkeyframes-formatter)
4340
- [Contributing](#contributing)
4441

4542
## Introduction
4643

4744
This library was inspired heavily by [react-motion](https://github.com/chenglou/react-motion), which allows you to create spring-based animations by repeatedly updating an elements inline styles. When animating lots of elements at the same time, this can be a burden on performance. Also, based on my own experience, integrating with some css-in-js libraries is hard.
4845

49-
This is where **css-spring** enters the stage. Enter the desired starting properties and target properties of your animation, optionally adjust the spring settings and **css-spring** generates a keyframe object or formatted keyframe animation css for your spring-based animation of choice.
46+
This is where **css-spring** enters the stage. Enter the desired starting properties and target properties of your animation, optionally adjust the spring settings and **css-spring** generates a keyframe object or keyframe animation css for your spring-based animation of choice.
5047

5148
The library is small and easy to work with. Nevertheless, it is in the early stages of development. There is a lot of improvements to be made - read the [Contributing](#contributing) section if you want to know how you can help.
5249

@@ -59,11 +56,11 @@ This section lists some examples of popular css-in-js libraries such as `styled-
5956
When used with the [styled-components](https://github.com/styled-components/styled-components) `keyframes` helper, generated keyframe animations can be applied to a styled component like this:
6057

6158
```javascript
62-
import spring, { format } from 'css-spring'
59+
import spring, { toString } from 'css-spring'
6360
import styled, { keyframes } from 'styled-components'
6461

65-
const springLeft = format(spring(
66-
{ left: 50 }, { left: 250 }, { preset: 'gentle' }
62+
const springLeft = toString(spring(
63+
{ left: '50px' }, { left: '250px' }, { preset: 'gentle' }
6764
))
6865

6966
const StyledDiv = styled.div`
@@ -73,14 +70,14 @@ const StyledDiv = styled.div`
7370

7471
### glamor
7572

76-
When used with the `keyframes` method of [glamor](https://github.com/threepointone/glamor), no special formatting is needed for pixel values:
73+
When used with the `keyframes` method of [glamor](https://github.com/threepointone/glamor), the keyframe object can be used as-is and there is no need to convert it to a string:
7774

7875
```jsx
7976
import { css } from 'glamor';
8077
import spring from 'css-spring';
8178

8279
const springLeft = css.keyframes('springLeft', spring(
83-
{ left: 50 }, { left: 250 }, { preset: 'gentle' }
80+
{ left: '50px' }, { left: '250px' }, { preset: 'gentle' }
8481
));
8582

8683
const MyComponent = () => (
@@ -93,12 +90,29 @@ const MyComponent = () => (
9390
## API
9491
### `spring(start, target, options)`
9592

96-
This method creates spring-based keyframes. Called with start and target properties, it returns an object with the interpolated animation values.
93+
This method creates spring-based keyframes. Called with `startProp` and `targetProp` arguments
94+
reflecting the starting and ending properties of the animation, it returns an object with the
95+
interpolated animation values.
96+
97+
The following properties in both the `startProp` and `endProp` objects are ignored when
98+
calculating the animation:
99+
100+
- properties that do not exist in both arguments
101+
- properties that have non-numeric values
102+
- properties with units that differ between both arguments
97103

98104
#### Arguments
99105

100-
- `start` (_Object_): The start properties for the animation. The keys should be css properties, the values should be able to be parsed to a number by `parseFloat`. Keys that can not be parsed or do not exist in the target properties are ignored.
101-
- `target` (_Object_): The target properties for the animation. The keys should be css properties, the values should be able to be parsed to a number by `parseFloat`. Keys that can not be parsed or do not exist in the start properties are ignored.
106+
- `startProps` (_Object_): The start properties for the animation.<br>
107+
```javascript
108+
// `startProps` example
109+
{ 'margin-left': '0px', opacity: 0 }
110+
```
111+
- `endProps` (_Object_): The end properties for the animation.<br>
112+
```javascript
113+
// `endProps` example
114+
{ 'margin-left': '250px', opacity: 1 }
115+
```
102116
- `options` (_Object_, optional): Animation options with these properties:
103117
- `precision` (_Number_, optional, defaults to `3`) Specifies the number of decimals in the rounding of interpolated values.
104118
- `preset` (_String_, optional): Presets for `stiffness` and `damping`, overriding any stiffness and damping values given. Available presets:
@@ -115,44 +129,65 @@ An object with `0%` to `100%` keys and the interpolated physics-based values for
115129

116130
```javascript
117131
{
118-
"0%": { "left": 0 },
119-
"1%": { "left": 3 },
120-
"2%": { "left": 8.544 },
132+
"0%": { "margin-left": "0px" },
133+
"1%": { "margin-left": "3px" },
134+
"2%": { "margin-left": "8.544px" },
121135
// 3% … 98%
122-
"99%": { "left": 249.981 }
123-
"100%": { "left": 250 }
136+
"99%": { "margin-left": "249.981px" }
137+
"100%": { "margin-left": "250px" }
124138
}
125139
```
126140

127-
### `format(keyframes, formatter)`
141+
### `toString(keyframes, formatter)`
128142

129-
This method takes the return value of `spring` and formats it to valid css (with corresponding units). As of now, the interpolated key-frame values are unitless because units are stripped at creation. Simple formatters that add `px`, `em` or `rem` units to every property value are available as `format.PX_FORMATTER`, `format.EM_FORMATTER` and `format.REM_FORMATTER`.
143+
This method takes the return value of `spring` and converts it to a css string.
130144

131145
#### Arguments
132146

133147
- `keyframes` (_Object_): The interpolated animation values object given by `spring`.
134-
- `formatter` (_Function_, optional, defaults to `format.PX_FORMATTER`): The formatter function that is invoked for every property/value combination.
148+
- `formatter` (_Function_, optional): The formatter function that is invoked for every property/value combination.
149+
```javascript
150+
// default formatter
151+
(property, value) => `${property}:${value};`
152+
```
135153

136154
#### Returns
137155

138-
A formatted css keyframes string.
156+
A css keyframe string.
139157

140158
#### Example
141159

142-
A keyframes object based on `startValues = { opacity: 0, left: '10px' }` and `targetValues = { opacity: 1, left: '20px' }` will have all units (in this case, `px`) removed from the interpolated values. In order to get css with the correct unit for the interpolated `left` values, but no unit for the interpolated `opacity` values, write your own formatter such as this:
160+
A keyframes object based on `startValues = { rotate: '0deg', left: '10px' }` and `targetValues = { rotate: '180deg', left: '20px' }` will be converted to this css string:
161+
162+
```css
163+
0%{rotate:0deg;left:10px}
164+
/* ... */
165+
100%{rotate:180deg;left:20px;}
166+
```
167+
168+
In order to have this formatted to a valid css transform, you could use a custom formatter like this one:
143169

144170
```javascript
145-
const keyframeCss = format(mySpring, (key, value) =>
146-
`${key}:${value}${key === 'left' ? 'px' : ''};`
171+
const keyframeCss = toString(keyframes, (property, value) =>
172+
property === 'rotate'
173+
? `transform:${property}(${value});`
174+
: `${property}:${value};`
147175
)
148176
```
149177

178+
This would net you the following css:
179+
180+
```css
181+
0%{transform:rotate(0deg);left:10px}
182+
/* ... */
183+
100%{transform:rotate(180deg);left:20px;}
184+
```
185+
150186
## Contributing
151187

152188
There's a lot of ideas floating in my head that could make working with **css-spring** easier. Some of these are:
153189
154190
- allowing the interpolation of array values like margins, paddings or translates ([#1](/../../issues/1))
155-
- automatically detecting css-units and re-applying them to the interpolated values of the keyframe animation ([#2](/../../issues/2))
156191
- color interpolation ([#3](/../../issues/3))
157192
158193
Feel free to contribute with your own issues and ideas, your thoughts on the ones listed above, example documentation for usage with other css-in-js frameworks or pull requests for features/improvements you'd like to see.

0 commit comments

Comments
 (0)