feat(chritsmas): create challenge for christmas

This commit is contained in:
thomas
2023-10-30 21:28:40 +01:00
parent 3e1dc89d78
commit 58215fe349
22 changed files with 549 additions and 7 deletions

View File

@@ -0,0 +1,32 @@
import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import { PrimeService } from './prime-number.service';
import { UnknownPersonComponent } from './unknown-person/unknown-person.component';
@Component({
standalone: true,
imports: [CommonModule, UnknownPersonComponent],
providers: [PrimeService],
selector: 'app-root',
template: `
<unknown-person [step]="loadingPercentage()" class="relative grow" />
<button
class="border border-white rounded-md px-4 py-2 text-white w-fit self-center text-2xl my-3"
(click)="discover()">
Discover
</button>
<div class="text-white p-1">Progress: {{ loadingPercentage() }}%</div>
`,
host: {
class: `flex flex-col h-screen w-screen bg-[#1f75c0]`,
},
})
export class AppComponent {
primeService = inject(PrimeService);
loadingPercentage = this.primeService.loadingPercentage;
discover() {
this.primeService.calculatePrimeLength();
}
}

View File

@@ -0,0 +1,5 @@
import { ApplicationConfig } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [],
};

View File

@@ -0,0 +1,30 @@
import { Injectable, computed, signal } from '@angular/core';
@Injectable()
export class PrimeService {
private finalResult = 664579;
private primesLength = signal(0);
loadingPercentage = computed(
() => (this.primesLength() * 100) / this.finalResult
);
calculatePrimeLength() {
this.findPrimesUpToLimit(10000000);
}
private findPrimesUpToLimit(limit: number) {
for (let num = 2; num <= limit; num++) {
let isPrime = true;
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
this.primesLength.update((l) => l + 1);
}
}
}
}

View File

@@ -0,0 +1,223 @@
*,
*:before,
*:after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #fff2c8;
}
.container {
width: 380px;
height: 500px;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
.container *:before,
.container *:after {
position: absolute;
content: '';
}
.santa {
height: 220px;
width: 200px;
background-color: #e84701;
border-radius: 80px;
position: absolute;
left: 115px;
top: 200px;
}
.santa:before,
.santa:after {
width: 40px;
margin: auto;
left: 0;
right: 0;
background-color: #fff2c8;
}
.santa:before {
height: 130px;
}
.santa:after {
height: 40px;
bottom: -15px;
}
.hand-l {
background-color: #e84701;
height: 90px;
width: 105px;
position: absolute;
right: -30px;
top: 20px;
border-radius: 0 80px 0 0;
}
.hand-l:before {
margin: auto;
width: 35px;
height: 15px;
background-color: #ffffff;
top: 85px;
left: 71px;
}
.hand-l:after {
height: 15px;
width: 30px;
background-color: #fad2af;
left: 74px;
top: 101px;
border-radius: 0 0 30px 30px;
}
.hand-r {
height: 150px;
width: 180px;
border: 30px solid transparent;
border-bottom: 40px solid #e84701;
position: absolute;
left: -100px;
bottom: 150px;
border-radius: 50%;
animation: wave 1.5s infinite;
transform-origin: right;
}
@keyframes wave {
50% {
transform: rotate(15deg);
}
}
.hand-r:before {
width: 35px;
height: 15px;
background-color: #ffffff;
transform: rotate(-50deg);
top: 68px;
left: -22px;
}
.hand-r:after {
width: 30px;
height: 15px;
background-color: #fad2af;
transform: rotate(-50deg);
left: -31px;
top: 58px;
border-radius: 15px 15px 0 0;
}
.face {
position: absolute;
margin: auto;
height: 180px;
width: 180px;
background-color: #fad2af;
border: 25px solid #f2e6da;
border-radius: 50%;
left: 0;
right: 0;
bottom: 140px;
}
.beard {
position: absolute;
height: 90px;
width: 180px;
background-color: #ffffff;
border-radius: 0 0 90px 90px;
right: -25px;
bottom: -25px;
}
.beard:before {
width: 55px;
height: 25px;
background-color: #f2e6da;
border-radius: 20px 0;
left: 34px;
}
.beard:after {
height: 25px;
width: 55px;
background-color: #f2e6da;
border-radius: 0 20px;
right: 34px;
}
.eyes {
height: 12px;
width: 12px;
background-color: #0078ca;
border-radius: 50%;
position: absolute;
top: 40px;
left: 40px;
box-shadow: 38px 0 #0078ca, 19px 20px #f69697;
}
.eyes:before {
height: 12px;
width: 25px;
background-color: #ffffff;
border-radius: 10px 0;
left: -10px;
bottom: 20px;
}
.eyes:after {
height: 12px;
width: 25px;
background-color: #ffffff;
border-radius: 0 10px;
left: 32px;
bottom: 20px;
}
.hat {
position: absolute;
height: 60px;
width: 120px;
background-color: #e84701;
top: -98px;
left: 85px;
border-radius: 0 0 60px 60px;
}
.hat:before {
height: 40px;
width: 40px;
background-color: #ffffff;
left: 100px;
top: -15px;
border-radius: 50%;
}
.belt {
position: absolute;
width: 100%;
height: 30px;
background-color: #000000;
top: 100px;
}
.belt:before {
height: 100%;
width: 40px;
border: 7px solid #ffdc2e;
margin: auto;
left: 0;
right: 0;
}
.belt:after {
height: 5px;
width: 15px;
background-color: #ffdc2e;
left: 100px;
top: 12px;
}
.shoe {
height: 20px;
width: 20px;
background-color: #000000;
position: absolute;
top: 220px;
left: 60px;
border-radius: 20px 0 0 0;
}
.shoe:before {
height: 20px;
width: 20px;
background-color: #000000;
top: 0;
left: 60px;
border-radius: 0 20px 0 0;
}

View File

@@ -0,0 +1,35 @@
import { NgIf } from '@angular/common';
import { Component, Input } from '@angular/core';
@Component({
selector: 'unknown-person',
standalone: true,
imports: [NgIf],
template: `
<div
class="bg-black absolute inset-0 z-10 text-white text-center text-3xl"
[style.height.%]="100 - step">
<div
class="relative top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
*ngIf="step !== 100">
Who is here?
</div>
</div>
<div class="container">
<div class="santa">
<div class="hand-l"></div>
<div class="hand-r"></div>
<div class="hat"></div>
<div class="face">
<div class="beard"></div>
<div class="eyes"></div>
</div>
<div class="belt"></div>
<div class="shoe"></div>
</div>
</div>
`,
styleUrls: [`unknown-person.component.css`],
})
export class UnknownPersonComponent {
@Input({ required: true }) step!: number;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>performance-christmas-web-worker</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@@ -0,0 +1,7 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig).catch((err) =>
console.error(err)
);

View File

@@ -0,0 +1,5 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* You can add global styles to this file, and also import other style files */