Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkpiano committed May 11, 2022
1 parent bb07591 commit 6d872f8
Show file tree
Hide file tree
Showing 21 changed files with 1,142 additions and 11 deletions.
41 changes: 40 additions & 1 deletion 00-fundamentals/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,44 @@
<title>Fundamentals</title>
<link rel="stylesheet" href="style.scss" />
</head>
<body></body>
<body>
<form class="ui-form">
<input class="ui-input" type="email" placeholder="[email protected]" />
<button class="ui-button" type="button" onclick="setState('subscribing')">
<span data-show="subscribe">Subscribe</span>
<span data-show="subscribing">Subscribing</span>
<span data-show="success">Success!</span>
<span data-show="error">Error</span>
</button>
</form>
</body>
<script>
const form = document.querySelector('.ui-form');

function setState(state) {
const active = document.querySelectorAll(`[data-active]`);

active.forEach((activeEl) => delete activeEl.dataset.active);

form.dataset.state = state;

const show = document.querySelectorAll(`[data-show="${state}"]`);

show.forEach((el) => {
el.dataset.active = true;
});

if (state === 'subscribing') {
setTimeout(() => {
if (Math.random() < 0.9) {
setState('error');
} else {
setState('success');
}
}, 2000);
}
}

setState('subscribe');
</script>
</html>
30 changes: 30 additions & 0 deletions 00-fundamentals/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Lesson 0: Fundamentals

- Why animate? Guidance and clarification, style and branding.
- Duration: how long an _iteration_ of an animation takes to complete.
- Delay: how long it takes before an animation _starts_
- Timing function: the _easing_ of an animation
- CSS Variables: custom properties that can be inherited by elements and set by JavaScript:

```css
:root {
--duration: 2s;
}

.thing {
animation-duration: calc(var(--duration, 1s));
}
```

```js
const thingEl = document.querySelector('.thing');

thingEl.style.setProperty('--color', 'green');
```

## Resources

- [Ground Rules for CSS Animations](https://css-tricks.com/ground-rules-for-web-animations/)
- [UX Animation Principles: Duration](https://codepen.io/team/keyframers/pen/gdJJZV)
- [UX Animation Principles: Stagger](https://codepen.io/team/keyframers/pen/GXaaNw)
- [UX Animation Principles: Acceleration](https://codepen.io/team/keyframers/pen/ZqbWao)
124 changes: 124 additions & 0 deletions 00-fundamentals/style.scss
Original file line number Diff line number Diff line change
@@ -1 +1,125 @@
@import '../styles/base.scss';

:root {
--color-gray: #8c97b7;
--color-blue: #1c38f1;
--color-green: #1fcdb0;
--input-height: 3rem;
--transition-duration: 0.3s;
--transition-easing: cubic-bezier(0.5, 0, 0.5, 1);
--animation-duration: 0.8s;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #f9fbff;
}

.ui-form {
background: #fff;
box-shadow: 0 0.5rem 1rem #0003;
padding: 1rem;
border-radius: 0.25rem;
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: 1fr;
grid-column-gap: 1rem;
grid-template-areas: 'input button';
transition: all var(--transition-duration) var(--transition-easing);
will-change: transform;

--color: var(--color-gray);
&:focus-within {
--color: var(--color-blue);
}

&[data-state='subscribe'] {
animation: slide-up var(--animation-duration) var(--transition-easing);
}

&[data-state='success'] {
--color: var(--color-green);
}

&[data-state='error'] {
--color: var(--color-red, red);
animation: shake 1s ease;
}

> .ui-input,
> .ui-button {
animation-name: slide-up;
animation-fill-mode: both;
animation-timing-function: var(--transition-easing);
animation-delay: calc(var(--animation-duration) / 2);
}

> .ui-input {
animation-duration: 0.5s;
}
> .ui-button {
animation-duration: 0.6s;
}
}

.ui-input {
grid-area: input;
padding: 0 1rem;
height: var(--input-height);
border: 2px solid var(--color);
border-radius: 0.25rem;
outline: none;
transition: inherit;
}

.ui-button {
grid-area: button;
border: none;
padding: 0 1rem;
color: white;
font-weight: bold;
border-radius: 0.25rem;
height: var(--input-height);
background-color: var(--color);
transition: inherit;
}

[data-show]:not([data-active]) {
display: none;
}

.ui-form {
overflow: hidden;
}

@keyframes slide-up {
from {
opacity: 0;
transform: translateY(100%);
}
to {
opacity: 1;
transform: none;
}
}

@keyframes shake {
20%,
40%,
60%,
80% {
transform: translateX(1%);
}
10%,
30%,
50%,
70%,
90% {
transform: translateX(-1%);
}
from,
to {
transform: none;
}
}
7 changes: 6 additions & 1 deletion 01-transitions/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
<title>Transitions</title>
<link rel="stylesheet" href="style.scss" />
</head>
<body></body>
<body>
<form class="ui-form">
<input type="text" class="ui-input" placeholder="[email protected]" />
<button type="button" class="ui-button">Login</button>
</form>
</body>
</html>
16 changes: 16 additions & 0 deletions 01-transitions/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Lesson 1: Transitions

- [`transition-property`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-property)
- [`transition-duration`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-duration)
- [`transition-delay`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-delay)
- [`transition-timing-function`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function)
- [`transition`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition) (shorthand)

## Exercise

- Add border-color transitions for the different states of the input field.
- Add background-color transitions for the different states of the button.

## Resources

- [Springy Switchbox](https://codepen.io/team/keyframers/pen/JVdxzz)
58 changes: 58 additions & 0 deletions 01-transitions/style.scss
Original file line number Diff line number Diff line change
@@ -1 +1,59 @@
@import '../styles/base.scss';

body {
display: flex;
justify-content: center;
align-items: center;
background-color: #ECF5F7;
}

.ui-form {
display: flex;
flex-direction: column;
gap: 1rem;
background-color: #fff;
padding: 2rem;
box-shadow: 0 .5rem 1rem #0001;
border-radius: .25rem;
}

.ui-input {
appearance: none;
background-color: #F7FAFC;
border: 2px solid #eee;
border-radius: .25rem;
transition: 0.3s all ease-in-out;
padding: 1rem;
outline: none;

&:hover, &:focus {
border-color: #bbb;
}

&:focus {
border-color: #2146B3;
background-color: #fff;
}
}

.ui-button {
background-color: #2146B3;
color: white;
padding: 1rem;
display: block;
appearance: none;
border: none;
outline: 2px solid transparent;
outline-offset: 2px;
transition: all .3s;
border-radius: .25rem;
cursor: pointer;

&:focus {
outline: 2px solid #2146b3;
}

&:active {
opacity: 0.8;
}
}
14 changes: 14 additions & 0 deletions 02-keyframes/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Lesson 2: Keyframes and animations

- [`@keyframes`](https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes)
- [`animation-name`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-name) (shorthand)
- [`animation-duration`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-duration)
- [`animation-delay-delay`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay-delay)
- [`animation-timing-function`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function)
- [`animation-fill-mode`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode)
- [`animation`](https://developer.mozilla.org/en-US/docs/Web/CSS/animation) (shorthand)

## Exercise

- Add an entry animation to the form.
- Create a shake animation; we will use this later.
14 changes: 14 additions & 0 deletions 03-choreography/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Lesson 3: Choreography

- Staggered animations
- Planning choreographed animations

## Exercise

- Stagger the entrance of the input and button.
- Then, choreograph the entrance so that the button appears after the input.

## Resources

- [UX Animation Principles: Choreography](https://codepen.io/team/keyframers/pen/yRYJPr)
- [UX Animation Principles: Grid](https://codepen.io/team/keyframers/pen/bmVejm)
19 changes: 19 additions & 0 deletions 04-states/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Lesson 4: States

- Determining states for animation
- [Data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes)
- Creating simple state machines

## Exercise

- Use JavaScript to change the state of the form from `'subscribe'` to `'loading'` when the button is clicked.
- After 2 seconds in `'loading'`, change the state to `'success'` or `'error'` (chosen randomly to simulate an error state)
- Hint: use `Math.random() < 0.5`
- On the `'error'` state, animate the form by shaking it
- You will need to create a `shake` animation with `@keyframes`
- Refactor to a state machine to send events and prevent impossible state transitions (we'll do this together)

## Resources

- [Expanding Video Player](https://codepen.io/team/keyframers/pen/dLjZEO)
- [Contact Form Transitions](https://codepen.io/team/keyframers/pen/YzwGZwN)
1 change: 1 addition & 0 deletions 04-states/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import '../styles/base.scss';

body {
background: #000;
Expand Down
41 changes: 40 additions & 1 deletion 05-layout/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,44 @@
<title>Layout</title>
<link rel="stylesheet" href="style.scss" />
</head>
<body></body>
<body>
<div id="app" data-state="collapsed">
<figure class="ui-figure"></figure>
<div class="ui-content">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore
ullam hic consectetur ducimus neque ipsam incidunt voluptatem
voluptatum eos. Voluptatum minus omnis provident sit architecto,
mollitia nihil aspernatur sed praesentium.
</p>
</div>
</div>
</body>
<script>
const figureEl = document.querySelector('.ui-figure');
window.app.addEventListener('click', () => {
const firstRect = figureEl.getBoundingClientRect();
app.dataset.state =
app.dataset.state === 'collapsed' ? 'expanded' : 'collapsed';

requestAnimationFrame(() => {
const lastRect = figureEl.getBoundingClientRect();

const dx = firstRect.x - lastRect.x;
const dy = firstRect.y - lastRect.y;
const dw = firstRect.width / lastRect.width;
const dh = firstRect.height / lastRect.height;

figureEl.style.setProperty('--dx', dx);
figureEl.style.setProperty('--dy', dy);
figureEl.style.setProperty('--dw', dw);
figureEl.style.setProperty('--dh', dh);
figureEl.dataset.flip = 'invert';

requestAnimationFrame(() => {
figureEl.dataset.flip = 'play';
});
});
});
</script>
</html>
Loading

0 comments on commit 6d872f8

Please sign in to comment.