Skip to content

Instantly share code, notes, and snippets.

@shshaw shshaw/index.html
Created Jun 12, 2019

Embed
What would you like to do?
🍍↩️ Pineapple Placement, Part 1 | Complex Web Animation Challenge! | @keyframers 2.8.0
<a href="https://youtu.be/Obj0-fID7Yc" target="_blank" data-keyframers-credit style="color: #FFF"></a>
<script src="https://codepen.io/shshaw/pen/QmZYMG.js"></script>
<div id="app" data-state="1">
<div class="bg main-bg" data-flip-key="main-bg" data-scene="2"></div>
<div class="bg articles-bg" data-flip-key="main-bg" data-scene="1"></div>
<h1 class="logo">@keyframers</h1>
<form class="search">
<div class="bg" data-flip-key="search-bg"></div>
<div data-flip-key="search">Search</div>
</form>
<nav class="content section-navigation" data-scene="1">
<article class="hero">
<div class="bg" data-flip-key="title-bg"></div>
<img data-flip-key="title-img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1188/pineapple.png" />
<h1 class="nav-title" data-flip-key="title" data-flip-no-scale>Move and<br/>Mint</h1>
<div class="subtext">56 articles</div>
</article>
</nav>
<nav class="articles" data-scene="1">
<label>Popular</label>
<article style="--i: 0">
<header>Web Animation Is Hard</header>
<div class="author">Stephen Shaw</div>
</article>
<article style="--i: 1">
<header>Web Animation Is Simple</header>
<div class="author">David Khourshid</div>
</article>
<article style="--i: 2">
<header>No, Seriously. Web Animation Is Hard</header>
<div class="author">Stephen Shaw</div>
</article>
<article style="--i: 3">
<header>Maybe Someone Should Explain Web Animation Better</header>
<div class="author">David Khourshid</div>
</article>
</nav>
<aside class="sidebar" data-scene="2">
<div class="bg" data-flip-key="title-bg"></div>
<img data-flip-key="title-img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1188/pineapple.png" />
<h1 class="nav-title" data-flip-key="title" data-flip-no-scale>Move and<br/>Mint</h1>
</aside>
<main class="content" data-scene="2">
<article>
<h2>How animation really affects your life</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab quidem dignissimos quam illum consequatur dicta, maiores provident rerum. Deserunt beatae asperiores quo in dolores ullam doloremque odio recusandae laboriosam repellat.</p>
</article>
</main>
</div>

🍍↩️ Pineapple Placement, Part 1 | Complex Web Animation Challenge! | @keyframers 2.8.0

David Khourshid (invisible and inaudible) and Stephen Shaw build a complex web animation based on a Twitter challenge by Josh Comeau. We'll return for a part two with David visible and audible 😬

(Note: David's audio did not come through properly due to a technical error on Shaw's part. Oops! The episode still has lots of good bits, but starts out with Keyflections with a little dubbing that help explain a bit)

Skip around: 0:08 Special Message 1:10 Keyflections 5:00 Episode Start 6:30 Animation overview 10:00 Start coding 1:36:00 Keyflections

Additional Resources:

Like what we're doing? There are many ways you can support @keyframers so we can keep live coding awesome animations!

Topics covered:

  • FLIP
  • Animation coordination
  • CSS Grid

A Pen by Shaw on CodePen.

License.

console.clear();
const elApp = document.querySelector('#app');
const elHero = document.querySelector('.hero');
const elSidebar = document.querySelector('.sidebar');
function setState(state) {
// change data-state attribute
elApp.dataset.state = state;
// remove any active data-attributes
document.querySelectorAll(`[data-active]`).forEach(el => {
delete el.dataset.active;
});
// add active data-attributes to proper elements
document.querySelectorAll(`[data-scene~="${state}"]`)
.forEach(el => {
el.dataset.active = true;
});
}
setState(1);
const flipping = new Flipping({
duration: 800
});
elHero.addEventListener('click', flipping.wrap(() => {
setState(2);
}));
elSidebar.addEventListener('click', flipping.wrap(() => {
setState(1);
}));
<script src="https://unpkg.com/flipping@1.1.0/dist/flipping.web.js"></script>
@import url("https://fonts.googleapis.com/css?family=Raleway:400,800&display=swap");
:root {
--red: #db0c41;
--blue: #11176d;
--grey: #efeff1;
--duration: 0.8s;
--ease: cubic-bezier(0.7, 0, 0.3, 1);
}
*,
*::before,
*::after {
position: relative;
box-sizing: border-box;
}
html {
font-size: 16px;
height: 100%;
background: var(--blue);
font-family: Raleway, sans-serif;
}
img {
max-width: 100%;
height: auto;
}
// --------------------------
body {
min-height: 100%;
padding: 3vmin;
display: grid;
align-items: center;
justify-content: center;
}
#app {
display: grid;
grid-template-columns: auto 2.5fr 0.25fr 1.5fr;
grid-template-rows: auto 2fr auto;
grid-column-gap: 0px;
grid-row-gap: 0px;
background: var(--grey);
--bg: white;
min-height: 80vh;
// height: 90vh;
}
/* ---------------------------------- */
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--bg);
}
.articles-bg,
.main-bg {
--bg: white;
pointer-events: none;
}
.logo {
grid-column: 1;
grid-row: 1;
font-size: 1.2rem;
align-self: center;
justify-self: start;
z-index: 10;
padding: 0.25em 1em;
}
.search {
--bg: var(--red);
grid-column: 4;
grid-row: 1;
color: white;
z-index: 10;
display: grid;
justify-content: center;
align-content: center;
#app[data-state="2"] & {
grid-column: 3 / -1;
}
}
.content {
grid-column: 2;
grid-row: 2;
display: grid;
align-content: center;
justify-content: center;
}
.nav-title {
margin: 0;
font-size: 2.5rem;
font-size: 5vw;
font-weight: 800;
}
.hero {
--bg: var(--red);
color: white;
display: grid;
grid-template-columns: 1fr 2fr;
grid-template-rows: auto auto;
padding: 1rem;
> img {
max-width: 200%;
width: auto;
height: auto;
grid-column: 1;
grid-row: 1 / -1;
margin: -75% 0 -75% -100%;
}
> h1 {
grid-column: 2 / -1;
align-self: center;
}
> .subtext {
grid-column: 2 / -1;
grid-row: 2 / -1;
align-self: self-end;
}
}
.sidebar {
--bg: var(--red);
color: white;
grid-column: 1;
grid-row: 1 / -1;
padding: 1rem;
display: grid;
align-content: end;
img { max-width: 220px; }
}
/* ---------------------------------- */
.articles-bg,
.articles {
grid-column: 4;
grid-row: 2;
}
.articles {
padding: 1rem;
> label {
display: block;
color: #aaa;
margin-bottom: 1rem;
font-weight: bold;
text-transform: uppercase;
font-size: .8rem;
}
> header {
line-height: 1.4;
margin-bottom: .5rem;
}
> article,
> label {
transition: opacity var(--duration) var(--ease),
transform var(--duration) var(--ease);
}
> article {
visibility: visible;
transition-duration: calc(var(--duration) + 30ms * var(--i));
transition-delay: calc(30ms * var(--i));
}
&:not([data-active]) {
> article, > label {
opacity: 0;
transform: translateX(-50%);
}
}
}
/* ---------------------------------- */
article {
margin-bottom: 1rem;
header {
font-weight: bold;
color: var(--blue);
}
}
main {
&:not([data-active]) {
article {
opacity: 0;
transform: translateX(50%);
transition-duration: calc(var(--duration) / 2);
}
}
article {
--bg: white;
transition: all var(--duration) var(--ease);
padding: 2rem;
}
h2 {
color: var(--red);
}
p {
color: var(--blue);
line-height: 1.5;
}
}
h1 {
white-space: nowrap;
}
/* ---------------------------------- */
.bg[data-flip-key] { display: none; }
.bg[data-flip-key="search-bg"],
.bg[data-active],
[data-active] .bg { display: block; }
[data-scene] {
visibility: hidden;
&:not([data-active]) [data-flip-key] {
display: none;
}
}
[data-active] {
visibility: visible;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.