Skip to content

Commit 46ec218

Browse files
committed
add easing configuration and listen to window resize events
1 parent b902cb8 commit 46ec218

File tree

10 files changed

+1185
-150
lines changed

10 files changed

+1185
-150
lines changed

README.md

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,31 @@
22

33
![demo of animate-css-grid in action](./demo/grid.gif)
44

5-
This small-ish (4.4kb minified and gzipped) script wraps a CSS grid (or really, any container element) and animates updates to its children.
5+
This small script wraps a CSS grid (or really, any container element) and animates updates to its children.
66
When the grid container, or one of its immediate children, is updated via the addition or removal of a class, the grid will smoothly transition its children to their new positions and sizes.
77

88
[Example on Codepen](https://codepen.io/aholachek/pen/VXjOPB)
99

1010
## How to use it
1111

12-
Call the `wrapGrid` method on your grid container and pass in an optional config object.
12+
Call the `wrapGrid` method on your grid container.
13+
14+
The optional config object allows you to control duration, staggering, and easing.
15+
16+
[Available easing functions](https://sole.github.io/tween.js/examples/03_graphs.html).
17+
18+
Example options object:
19+
20+
```js
21+
{
22+
// create a stagger effect (default is false)
23+
stagger: true,
24+
// specify a duration in ms (default is 250 ms)
25+
duration: 500
26+
// specify an easing as a string. default is 'Quadratic.InOut'
27+
easing: 'Sinusoidal.InOut'
28+
}
29+
```
1330

1431
ES6 Module:
1532

@@ -20,39 +37,35 @@ import { wrapGrid } from animateCSSGrid
2037

2138
const grid = document.querySelector(".grid");
2239

23-
const { unwrapGrid } = wrapGrid(grid, {
24-
// create a stagger effect (default is false)
25-
stagger: true,
26-
// specify a duration (default is 300 ms)
27-
duration: 300
28-
});
40+
const { unwrapGrid } = wrapGrid(grid, {duration: 500});
2941

3042
// later, to remove transitions
3143
unwrapGrid()
3244
```
3345

3446
Or from a script tag:
47+
3548
```html
3649
<script src="https://unpkg.com/animate-css-grid@latest"></script>
3750

3851
<script>
3952
const grid = document.querySelector(".grid");
40-
const { unwrapGrid } = animateCSSGrid.wrapGrid(grid);
53+
const { unwrapGrid } = animateCSSGrid.wrapGrid(grid, {stagger: true});
4154
</script>
4255
```
4356

44-
4557
## How it works
4658

4759
The script registers a `MutationObserver` that activates when the grid or one of its immediate children adds or loses a class.
4860
It uses the FLIP animation technique to smoothly update the grid, applying a counter transform to the children of each item so that they do not appear distorted while the transition occurs.
4961

5062
## Requirements
5163

52-
1. The updates to the grid will have to come from addition or removal of a class. Currently, inline style updates will not trigger transitions.
53-
2. If a grid item has children, they should be surrounded by a single container element.
64+
1. The updates to the grid will have to come from addition or removal of a class. Currently, inline style updates will not trigger transitions.
65+
2. If a grid item has children, they should be surrounded by a single container element.
5466

5567
OK:
68+
5669
```html
5770
<!-- grid style applied via a class -->
5871
<div class="some-grid-class-that-changes">
@@ -67,6 +80,7 @@ OK:
6780
```
6881

6982
Not going to work:
83+
7084
```html
7185
<!-- grid styles applied inline -->
7286
<div style="[grid styles that change]">

demo/index.css

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,50 @@ body {
9696
button {
9797
padding: 0.5rem;
9898
}
99+
100+
/* for the accordion */
101+
102+
.subjects {
103+
margin-top: 5rem;
104+
display: grid;
105+
grid-template-columns: repeat(auto-fit, minmax(5rem, 1fr));
106+
height: 100vh;
107+
}
108+
109+
.subject {
110+
padding: 2rem;
111+
overflow: hidden;
112+
color: #191919;
113+
}
114+
115+
.subject__content {
116+
display: none;
117+
}
118+
119+
.subject:first-of-type {
120+
background-color: #366f6e;
121+
}
122+
123+
.subject:nth-of-type(2) {
124+
background-color: #79ac91;
125+
}
126+
127+
.subject:nth-of-type(3) {
128+
background-color: #e2b060;
129+
}
130+
131+
.subject:nth-of-type(4) {
132+
background-color: #e86448;
133+
}
134+
135+
.subject:nth-of-type(5) {
136+
background-color: #dc5263;
137+
}
138+
139+
.subject--active {
140+
grid-column-end: span 3;
141+
}
142+
143+
.subject--active .subject__content {
144+
display: block;
145+
}

demo/index.html

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<meta http-equiv="X-UA-Compatible" content="ie=edge">
88
<title>animate-css-grid example</title>
99
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
10-
<link rel="stylesheet" href="index.css">
10+
<link rel="stylesheet" href="./index.css">
1111
</head>
1212

1313
<body>
@@ -16,6 +16,7 @@
1616
<p>click a card to expand it</p>
1717
<button class="btn js-toggle-grid">toggle grid size</button>
1818
<button class="btn js-add-card">add a card</button>
19+
<button class="btn js-remove-listener">remove animations</button>
1920
</div>
2021

2122
<div class="grid">
@@ -78,45 +79,68 @@
7879
</div>
7980
</div>
8081
</div>
81-
<script src="../dist/main.js"></script>
82-
<script>
83-
const grid = document.querySelector(".grid");
84-
85-
document
86-
.querySelector(".js-toggle-grid")
87-
.addEventListener("click", () => grid.classList.toggle("grid--full"));
88-
89-
document
90-
.querySelector(".js-add-card")
91-
.addEventListener("click", () => {
92-
const randomNumber = Math.floor(Math.random() * 5) + 1
93-
grid.insertAdjacentHTML('beforeend',
94-
`
95-
<div class="card card--${randomNumber}">
96-
<div>
97-
<div class="card__avatar"></div>
98-
<div class="card__title"></div>
99-
<div class="card__description"></div>
82+
<div class="p-4">
83+
<div class="subjects">
84+
<section class="subject subject--active">
85+
<div>
86+
<h2 class="subject__title">
87+
Title One
88+
</h2>
89+
<div class="subject__content">
90+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, sequi quas porro blanditiis distinctio consequatur minima
91+
optio vero eaque autem. Odit enim totam rem officia quae iste placeat labore similique?
10092
</div>
10193
</div>
102-
`
103-
)
104-
});
105-
106-
grid.addEventListener('click', (ev) => {
107-
let target = ev.target
108-
while (target.tagName !== 'HTML') {
109-
if (target.classList.contains('card')) {
110-
target.classList.toggle('card--expanded')
111-
return
112-
}
113-
target = target.parentElement
114-
}
115-
})
94+
</section>
95+
<section class="subject">
96+
<div>
97+
<h2 class="subject__title">
98+
Title Two
99+
</h2>
100+
<div class="subject__content">
101+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, sequi quas porro blanditiis distinctio consequatur minima
102+
optio vero eaque autem. Odit enim totam rem officia quae iste placeat labore similique?
103+
</div>
104+
</div>
105+
</section>
106+
<section class="subject">
107+
<div>
108+
<h2 class="subject__title">
109+
Title Three
110+
</h2>
111+
<div class="subject__content">
112+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, sequi quas porro blanditiis distinctio consequatur minima
113+
optio vero eaque autem. Odit enim totam rem officia quae iste placeat labore similique?
114+
</div>
115+
</div>
116+
</section>
117+
<section class="subject">
118+
<div>
119+
<h2 class="subject__title">
120+
Title Four
121+
</h2>
122+
<div class="subject__content">
123+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, sequi quas porro blanditiis distinctio consequatur minima
124+
optio vero eaque autem. Odit enim totam rem officia quae iste placeat labore similique?
125+
</div>
126+
</div>
127+
</section>
128+
<section class="subject">
129+
<div>
130+
<h2 class="subject__title">
131+
Title Five
132+
</h2>
133+
<div class="subject__content">
134+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, sequi quas porro blanditiis distinctio consequatur minima
135+
optio vero eaque autem. Odit enim totam rem officia quae iste placeat labore similique?
136+
</div>
137+
</div>
138+
</section>
116139

117-
const {
118-
unwrapGrid
119-
} = animateCSSGrid.wrapGrid(grid);
140+
</div>
141+
</div>
142+
<script src="../bundle.js"></script>
143+
<script>
120144
</script>
121145

122146
</body>

demo/index.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { wrapGrid } from '../src/index.js';
2+
3+
const grid = document.querySelector('.grid');
4+
5+
document
6+
.querySelector('.js-toggle-grid')
7+
.addEventListener('click', () => grid.classList.toggle('grid--full'));
8+
9+
document.querySelector('.js-add-card').addEventListener('click', () => {
10+
const randomNumber = Math.floor(Math.random() * 5) + 1;
11+
grid.insertAdjacentHTML(
12+
'beforeend',
13+
`
14+
<div class="card card--${randomNumber}">
15+
<div>
16+
<div class="card__avatar"></div>
17+
<div class="card__title"></div>
18+
<div class="card__description"></div>
19+
</div>
20+
</div>
21+
`
22+
);
23+
});
24+
25+
grid.addEventListener('click', ev => {
26+
let target = ev.target;
27+
while (target.tagName !== 'HTML') {
28+
if (target.classList.contains('card')) {
29+
target.classList.toggle('card--expanded');
30+
return;
31+
}
32+
target = target.parentElement;
33+
}
34+
});
35+
36+
const { unwrapGrid } = wrapGrid(grid);
37+
38+
document
39+
.querySelector('.js-remove-listener')
40+
.addEventListener('click', unwrapGrid);
41+
42+
// ========================================================
43+
// accordion test
44+
// ========================================================
45+
46+
const subjects = document.querySelector('.subjects');
47+
48+
// animate the grid
49+
const { unwrapGridSubjects } = wrapGrid(subjects, { easing: 'Linear.None' });
50+
51+
// add a click handler
52+
subjects.addEventListener('click', ev => {
53+
[...document.querySelectorAll('.subject')].forEach(el =>
54+
el.classList.remove('subject--active')
55+
);
56+
let target = ev.target;
57+
while (target.tagName !== 'HTML') {
58+
if (target.classList.contains('subject')) {
59+
target.classList.toggle('subject--active');
60+
return;
61+
}
62+
target = target.parentElement;
63+
}
64+
});

demo/webpack.config.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var path = require('path');
2+
3+
module.exports = {
4+
// can be relative (???)
5+
entry: path.resolve(__dirname, 'index.js'),
6+
output: {
7+
filename: 'bundle.js',
8+
// has to be absolute (???)
9+
path: path.resolve(__dirname, 'demo'),
10+
},
11+
12+
module: {
13+
rules: [
14+
{
15+
test: /\.js$/,
16+
exclude: /node_modules/,
17+
use: {
18+
loader: 'babel-loader',
19+
},
20+
},
21+
],
22+
},
23+
};

0 commit comments

Comments
 (0)