Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1330 from navikt/god-jul
Browse files Browse the repository at this point in the history
God jul
  • Loading branch information
anders-nom authored Dec 16, 2022
2 parents 2c9b5eb + 7a49889 commit c172952
Show file tree
Hide file tree
Showing 3 changed files with 337 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/komponenter/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { getUrlFromLookupTable } from '@navikt/nav-dekoratoren-moduler';
import cls from 'classnames';
import Skiplinks from 'komponenter/header/common/skiplinks/Skiplinks';
import { useOnPushStateHandlers } from '../../utils/hooks/useOnPushStateHandlers';
import { GodJul } from './common/godjul/GodJul';

import './Header.scss';

Expand Down Expand Up @@ -330,6 +331,7 @@ export const Header = () => {
return (
<div className={'decorator-wrapper'}>
<span id={'top-element'} tabIndex={-1} />
<GodJul />
<BrowserSupportMsg />
<header className={`siteheader${useSimpleHeader ? ' simple' : ''}`}>
<Skiplinks simple={useSimpleHeader} />
Expand Down
241 changes: 241 additions & 0 deletions src/komponenter/header/common/godjul/GodJul.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
$globe-width: 12px;
$globe-height: 28px;
$globe-spacing: 40px;
$globe-spread: 3px;
$light-off-opacity: 0.4;
$light-off-shadow-opacity: 0.2;

$color1: rgba(0, 247, 120, 1);
$color1-faded: rgba(0, 247, 120, $light-off-opacity);
$color1-faded-shadow: rgba(0, 247, 120, $light-off-shadow-opacity);
$color2: rgba(0, 175, 255, 1);
$color2-shadow: rgba(0, 175, 255, 0.5);
$color2-faded: rgba(0, 175, 255, $light-off-opacity);
$color2-faded-shadow: rgba(0, 255, 255, $light-off-shadow-opacity);
$color3: rgba(247, 0, 90, 1);
$color3-faded: rgba(247, 0, 90, $light-off-opacity);
$color3-faded-shadow: rgba(247, 0, 90, $light-off-shadow-opacity);

.godjul {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1001;
pointer-events: none;
}

.lightrope {
text-align: center;
white-space: nowrap;
overflow: hidden;
position: absolute;
margin: -15px 0 0 0;
padding: 0;
width: 100%;

li {
position: relative;
animation-fill-mode: both;
animation-iteration-count: infinite;
list-style: none;
margin: 0;
padding: 0;
width: $globe-width;
height: $globe-height;
border-radius: 50%;
margin: $globe-spacing/2;
display: inline-block;
background: $color1;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color1;
animation-name: flash-1;
animation-duration: 2s;

&:nth-child(2n + 1) {
background: $color2;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color2;
animation-name: flash-2;
animation-duration: 0.4s;
}

&:nth-child(4n + 2) {
background: $color3;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color3;
animation-name: flash-3;
animation-duration: 1.1s;
}

&:nth-child(odd) {
animation-duration: 1.8s;
}

&:nth-child(3n + 1) {
animation-duration: 1.4s;
}

&:before {
content: '';
position: absolute;
background: #222;
width: ($globe-width - 2);
height: $globe-height/3;
border-radius: 3px;
top: (0 - ($globe-height/6));
left: 1px;
}

&:after {
content: '';
top: (0 - $globe-height/2);
left: $globe-width - 3;
position: absolute;
width: $globe-spacing + 12;
height: ($globe-height/3 * 2);
border-bottom: solid #222 2px;
border-radius: 50%;
}

&:last-child:after {
content: none;
}

&:first-child {
margin-left: -$globe-spacing;
}
}
}

@keyframes flash-1 {
0%,
100% {
background: $color1;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color1;
}
50% {
background: $color1-faded;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color1-faded-shadow;
}
}

@keyframes flash-2 {
0%,
100% {
background: $color2;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color2;
}
50% {
background: $color2-faded;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color2-faded-shadow;
}
}

@keyframes flash-3 {
0%,
100% {
background: $color3;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color3;
}
50% {
background: $color3-faded;
box-shadow: 0 $globe-height/6 $globe-width * 2 $globe-spread $color3-faded-shadow;
}
}

.snowflakes {
li {
color: #fff;
text-shadow: 1px 2px 8px #000;

position: fixed;
top: -10%;
user-select: none;
cursor: default;
animation-name: snowflakes-fall, snowflakes-shake;
animation-duration: 10s, 3s;
animation-timing-function: linear, ease-in-out;
animation-iteration-count: infinite, infinite;
animation-play-state: running, running;
list-style: none;
margin: 0;
padding: 0;

&::before {
content: '';
}

&:nth-of-type(0) {
font-size: 2rem;
}
&:nth-of-type(1) {
font-size: 1.5rem;
}
&:nth-of-type(2) {
font-size: 1.25rem;
}
&:nth-of-type(3) {
font-size: 1.75rem;
}

&:nth-of-type(0) {
left: 1%;
animation-delay: 0s, 0s;
}
&:nth-of-type(1) {
left: 10%;
animation-delay: 1s, 1s;
}
&:nth-of-type(2) {
left: 20%;
animation-delay: 6s, 0.5s;
}
&:nth-of-type(3) {
left: 30%;
animation-delay: 4s, 2s;
}
&:nth-of-type(4) {
left: 40%;
animation-delay: 2s, 2s;
}
&:nth-of-type(5) {
left: 50%;
animation-delay: 8s, 3s;
}
&:nth-of-type(6) {
left: 60%;
animation-delay: 6s, 2s;
}
&:nth-of-type(7) {
left: 70%;
animation-delay: 2.5s, 1s;
}
&:nth-of-type(8) {
left: 80%;
animation-delay: 1s, 0s;
}
&:nth-of-type(9) {
left: 90%;
animation-delay: 3s, 1.5s;
}
}
}

@keyframes snowflakes-fall {
0% {
top: -10%;
}
100% {
top: 100%;
}
}
@keyframes snowflakes-shake {
0% {
transform: translateX(0px) rotate(0);
}
50% {
transform: translateX(80px) rotate(30deg);
}
100% {
transform: translateX(0px) rotate(0);
}
}
94 changes: 94 additions & 0 deletions src/komponenter/header/common/godjul/GodJul.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { useEffect, useState } from 'react';
import { logAmplitudeEvent } from '../../../../utils/analytics/amplitude';

import style from './GodJul.module.scss';

export const GodJul = () => {
const [isEnabled, setIsEnabled] = useState(false);

useEffect(() => {
let keysPressed: string[] = [];

const handler = (event: KeyboardEvent) => {
const { key } = event;
keysPressed.push(key.toLowerCase());
keysPressed = keysPressed.slice(-6);
if (keysPressed.join('') === 'godjul') {
setIsEnabled(true);
document.removeEventListener('keydown', handler);
logAmplitudeEvent('godjul');
}
};

document.addEventListener('keydown', handler);

return () => {
window.removeEventListener('keydown', handler);
};
}, []);

if (!isEnabled) {
return null;
}

return (
<div className={style.godjul} aria-hidden={true}>
<ul className={style.lightrope}>
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
</ul>
<ul className={style.snowflakes}>
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
<li />
</ul>
</div>
);
};

0 comments on commit c172952

Please sign in to comment.