Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adriancmiranda/af0b889e1d55377a096e23f62206647d to your computer and use it in GitHub Desktop.
Save adriancmiranda/af0b889e1d55377a096e23f62206647d to your computer and use it in GitHub Desktop.
Flipping Birthstones #Codevember

Flipping Birthstones #Codevember

Codevember day 4: sapphire! Uses the Web Animations API, so if it doesn't work in your browser, that's why.

Click anywhere to see the effect.

A Pen by Adrian C Miranda on CodePen.

License.

<div id="gemstones" data-state="sapphire"></div>
const gemstones = {
garnet: 'january',
amethyst: 'february',
aquamarine: 'march',
diamond: 'april',
emerald: 'may',
alexandrite: 'june',
ruby: 'july',
peridot: 'august',
sapphire: 'september',
tourmaline: 'october',
topaz: 'november',
turquoise: 'december'
};
function mapLetters(word, prefix) {
const seen = {};
return [...word].map(char => {
if (seen[char] !== undefined) {
++seen[char];
return `<span data-flip-key="${prefix}-${char}-${seen[char]}">${char}</span>`;
} else {
seen[char] = 0;
return `<span data-flip-key="${prefix}-${char}">${char}</span>`;
}
});
}
const gemstonesHTML = Object.keys(gemstones).map(gemstone => {
const month = gemstones[gemstone];
return `
<div class="gemstone" id="${gemstone}">
<div class="month">
${mapLetters(month, 'month').join('')}
</div>
<div class="gem">
${mapLetters(gemstone, 'gem').join('')}
</div>
</div>
`
}).join('\n');
const gemstonesElm = document.getElementById('gemstones');
gemstonesElm.innerHTML = gemstonesHTML;
// state machine
function cycle(states, action) {
const statesMap = {};
states.forEach((state, i) => {
statesMap[state] = {
[action]: states[i + 1] || states[0]
};
});
return statesMap;
}
const machine = cycle(Object.keys(gemstones), 'CLICK');
function transition(state, action) {
return machine[state][action];
}
// FLIPPING!
const flipping = new Flipping({
parentElement: gemstonesElm,
duration: 600
});
function update(state) {
gemstonesElm.setAttribute('data-state', state);
}
let currentState = 'sapphire';
document.body.addEventListener('click', flipping.wrap(() => {
currentState = transition(currentState, 'CLICK');
update(currentState);
}));
update(currentState);
<script src="https://unpkg.com/[email protected]/dist/flipping.web.js"></script>
@import url('https://fonts.googleapis.com/css?family=PT+Serif');
$gemstones:
'garnet',
'amethyst',
'aquamarine',
'diamond',
'emerald',
'alexandrite',
'ruby',
'peridot',
'sapphire',
'tourmaline',
'topaz',
'turquoise';
@each $gemstone in $gemstones {
[data-state="#{$gemstone}"] .gemstone:not(##{$gemstone}) {
display: none;
}
}
span {
display: inline-block;
// will-change: transform;
}
.month {
font-size: 3vmin;
letter-spacing: 1vmin;
text-transform: uppercase;
opacity: 0.5;
}
.gem {
font-size: 10vmin;
font-family: PT Serif, serif;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #191919;
color: white;
user-select: none;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
*, *:before, *:after {
box-sizing: border-box;
position: relative;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment