Skip to content

Instantly share code, notes, and snippets.

@HDVinnie
Created November 30, 2019 23:04
Show Gist options
  • Save HDVinnie/8dd76e21a08bfddb4107b09160971d6e to your computer and use it in GitHub Desktop.
Save HDVinnie/8dd76e21a08bfddb4107b09160971d6e to your computer and use it in GitHub Desktop.
Christmas Advent Calendar🎄🎅

Christmas Advent Calendar🎄🎅

A little self-set challenge to create a xmas advent calendar using javascript and css grid with a little animation and a hint of 3d. Works best in desktop.

Merry Christmas! I hope you enjoy!

A Pen by A Dunkley on CodePen.

License.

<div class="calendar-bg">
<h1 class="title">🎄 MERRY 🎅<br>CHRISTMAS</h1>
<div id="grid" class="grid"></div>
</div>
const days = 25;
const daysArray = [];
const randomDaysArray = [];
const grid = document.getElementById('grid');
const images = [
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/ball.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/ball2.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/hat.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/snowman.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/snowman2.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/star.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/star2.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/stocking.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/stocking2.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/tree.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/tree2.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/snowflake.svg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2175134/holly.svg'
];
// create an array of numbers 1-25
for (let i=1; i<=days; i+=1) {
daysArray.push(i);
}
let randomDay = 0;
// get today's date in dd format
const today = new Date().getDate();
for (let i=1; i <= days; i+=1) {
// picks a random day from array of days
randomDay = Math.floor(Math.random() * daysArray.length);
let randomImageNum = Math.floor(Math.random()*images.length);
grid.innerHTML += `
<div class="day">
<span class="door door-${daysArray[randomDay]}">
<span class="number">${daysArray[randomDay]}</span>
</span>
<div class="bg-img" style="background-image: url(${images[randomImageNum]})"></div>
</div>
`;
// populate new array with randomly selected dates
randomDaysArray.push(daysArray[randomDay]);
// remove random day from array
daysArray.splice(randomDay, 1);
}
let doors = document.getElementsByClassName('door');
for (let i=0; i<=days; i+=1) {
if (randomDaysArray[i] <= today) {
doors[i].addEventListener('click', () => {
doors[i].classList.add('open');
});
}
}
* {
box-sizing: border-box; margin: 0;
font-family: montserrat, sans-serif;
}
.calendar-bg {
background: #042f5f;
background-image: linear-gradient(30deg, white 15%, #042f5f 85%);
background-size: 20px 100%;
background-position: center;
padding-bottom: 50px;
}
.title {
text-align: center;
color: white;
letter-spacing: 0.3vw;
font-size: 10vw;
line-height: 1;
padding-top: 30px;
margin: 0px auto 30px;
@media screen and (min-width: 440px) {
letter-spacing: 3px;
font-size: 3em;
}
@media screen and (min-width: 768px) {
letter-spacing: 4px;
font-size: 4em;
}
}
.grid {
padding: 20px;
max-width: 960px;
margin: 0px auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 3vw;
perspective: 1500px;
@media screen and (min-width: 440px) {
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 16px;
}
@media screen and (min-width: 600px) {
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 20px;
}
@media screen and (min-width: 768px) {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}
}
.day {
min-height: 123px;
box-sizing: border-box;
position: relative;
box-shadow: 0 0 20px rgba(80,80,120,0.5) inset, 0 0 5px 2px rgba(80,80,120,0.3) inset;
&:nth-last-child(1) {
grid-column: 2;
@media screen and (min-width: 600px) {
left: calc(50% + 10px);
}
@media screen and (min-width: 768px) {
grid-column: unset;
left: unset;
}
}
}
.door {
background-color: #dd0707;
background-image: linear-gradient(45deg, white, transparent 5%, transparent 45%, white 50%, transparent 55%, transparent 95%, white 100%);
background-size: 20px 20px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform-origin: left center;
transform-style: preserve-3d;
transform: rotateY(0deg);
cursor: pointer;
}
/* back of door */
.door:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: rgb(170,10,10);
transform: translateZ(-1px);
}
.open {
z-index: 100;
animation: open-door 1s forwards;
}
@keyframes open-door {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-90deg);
z-index: 200;
}
}
.number {
position: absolute;
top: 6px;
right: 6px;
text-align: center;
color: #fff;
font-size: 5vw;
font-weight: 600;
min-width: 30px;
background: #dd0707;
padding: 5px 7px;
border-radius: 50% 50%;
@media screen and (min-width: 440px) {
font-size: 1.5em;
}
@media screen and (min-width: 768px) {
font-size: 1.8em;
}
}
.bg-img {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(216,226,210,1);
background-position: center;
background-repeat: no-repeat;
background-size: 70%;
z-index: -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment