Add calcylators: 1rm, Navy fat
This commit is contained in:
parent
4d9a4fc7f9
commit
f66cf85eb8
6 changed files with 299 additions and 67 deletions
|
|
@ -3,15 +3,40 @@
|
||||||
import viteLogo from "/vite.svg";
|
import viteLogo from "/vite.svg";
|
||||||
import { navigate } from "./lib/common";
|
import { navigate } from "./lib/common";
|
||||||
import { currentView } from "./lib/store";
|
import { currentView } from "./lib/store";
|
||||||
import FatPercentage from "./lib/FatPercentage.svelte";
|
import ArmyFatPercentage from "./lib/ArmyFatPercentage.svelte";
|
||||||
|
import NavyFatPercentage from "./lib/NavyFatPercentage.svelte";
|
||||||
|
import OneRepMax from "./lib/OneRepMax.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $currentView === "fatcalc"}
|
{#if $currentView === "armyfatcalc"}
|
||||||
<FatPercentage />
|
<ArmyFatPercentage />
|
||||||
|
{/if}
|
||||||
|
{#if $currentView === "navyfatcalc"}
|
||||||
|
<NavyFatPercentage />
|
||||||
|
{/if}
|
||||||
|
{#if $currentView === "onerepmax"}
|
||||||
|
<OneRepMax />
|
||||||
{/if}
|
{/if}
|
||||||
{#if $currentView === "start"}
|
{#if $currentView === "start"}
|
||||||
<button onclick={() => navigate("fatcalc")}>Kroppsfettkalkylator</button>
|
<main>
|
||||||
|
<nav>
|
||||||
|
<button onclick={() => navigate("armyfatcalc")}
|
||||||
|
>Kroppsfettkalkylator, Army</button
|
||||||
|
>
|
||||||
|
<button onclick={() => navigate("navyfatcalc")}
|
||||||
|
>Kroppsfettkalkylator, Navy</button
|
||||||
|
>
|
||||||
|
<button onclick={() => navigate("onerepmax")}>1RM-kalkylator</button
|
||||||
|
>
|
||||||
|
</nav>
|
||||||
|
</main>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
nav {
|
||||||
|
display: grid;
|
||||||
|
grid-template: subgrid / subgrid;
|
||||||
|
grid-column: 2 / 2;
|
||||||
|
grid-row: 2 / 6;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
74
src/app.css
74
src/app.css
|
|
@ -17,6 +17,19 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 5px solid crimson;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-color: #fff;
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background-color: crimson;
|
background-color: crimson;
|
||||||
}
|
}
|
||||||
|
|
@ -26,4 +39,65 @@ h2,
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
min-width: 100vw;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: grid;
|
||||||
|
gap: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-template-rows: repeat(7, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
display: grid;
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 2 / 4;
|
||||||
|
grid-template: subgrid / subgrid;
|
||||||
|
font-size: 2em;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
grid-column: 1 / 6;
|
||||||
|
grid-row: 1 / 2;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "=";
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "%";
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
background: rgba(255, 255, 255, 0.25);
|
||||||
|
display: grid;
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 4 / 8;
|
||||||
|
grid-template: subgrid / subgrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
max-width: 4em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: grid;
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 1 / 1;
|
||||||
|
grid-template: subgrid / subgrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
grid-column: 2 / 4;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
<span>
|
<span>
|
||||||
<button onclick={() => navigate("start")}>Tillbaka</button>
|
<button onclick={() => navigate("start")}>Tillbaka</button>
|
||||||
</span>
|
</span>
|
||||||
<h1>Kroppsfettkalkylator</h1>
|
<h1>Kroppsfettkalkylator, Army</h1>
|
||||||
</header>
|
</header>
|
||||||
<output>
|
<output>
|
||||||
{#if fatPercentage > 0}
|
{#if fatPercentage > 0}
|
||||||
|
|
@ -123,68 +123,8 @@
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
main {
|
|
||||||
min-width: 100vw;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: grid;
|
|
||||||
gap: 1em;
|
|
||||||
padding: 1em;
|
|
||||||
box-sizing: border-box;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
grid-template-rows: repeat(7, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
output {
|
|
||||||
background: rgba(0, 0, 0, 0.25);
|
|
||||||
display: grid;
|
|
||||||
grid-column: 1 / 4;
|
|
||||||
grid-row: 2 / 4;
|
|
||||||
grid-template-columns: subgrid;
|
|
||||||
font-size: 2em;
|
|
||||||
|
|
||||||
> span {
|
|
||||||
grid-column: 1 / 6;
|
|
||||||
grid-row: 1 / 2;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "=";
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: "%";
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
background: rgba(255, 255, 255, 0.25);
|
|
||||||
display: grid;
|
|
||||||
grid-column: 1 / 4;
|
|
||||||
grid-row: 4 / 8;
|
|
||||||
grid-template-columns: subgrid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gender {
|
.gender {
|
||||||
grid-column: 1 / 2;
|
grid-column: 1 / 2;
|
||||||
grid-row: 1 / 4;
|
grid-row: 1 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
|
||||||
max-width: 4em;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: grid;
|
|
||||||
grid-column: 1 / 4;
|
|
||||||
grid-row: 1 / 1;
|
|
||||||
grid-template-columns: subgrid;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
grid-column: 2 / 4;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
136
src/lib/NavyFatPercentage.svelte
Normal file
136
src/lib/NavyFatPercentage.svelte
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { navigate } from "./common";
|
||||||
|
|
||||||
|
let fatPercentage = $state(0);
|
||||||
|
let gender = $state("male");
|
||||||
|
let height = $state(null);
|
||||||
|
let waist = $state(null);
|
||||||
|
let neck = $state(null);
|
||||||
|
let hips = $state(null);
|
||||||
|
|
||||||
|
// https://www.omnicalculator.com/health/navy-body-fat
|
||||||
|
|
||||||
|
const male = (waist: number, neck: number, height: number) =>
|
||||||
|
495 /
|
||||||
|
(1.0324 -
|
||||||
|
0.19077 * Math.log10(waist - neck) +
|
||||||
|
0.15456 * Math.log10(height)) -
|
||||||
|
450;
|
||||||
|
|
||||||
|
const female = (
|
||||||
|
waist: number,
|
||||||
|
neck: number,
|
||||||
|
hips: number,
|
||||||
|
height: number,
|
||||||
|
) =>
|
||||||
|
495 /
|
||||||
|
(1.29579 -
|
||||||
|
0.35004 * Math.log10(waist + hips - neck) +
|
||||||
|
0.221 * Math.log10(height)) -
|
||||||
|
450;
|
||||||
|
|
||||||
|
const calculate = () => {
|
||||||
|
if (gender == "male") {
|
||||||
|
if (!waist || !neck || !height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fatPercentage = male(waist, neck, height);
|
||||||
|
} else {
|
||||||
|
if (!waist || !neck || !height || !hips) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fatPercentage = female(waist, neck, hips, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<span>
|
||||||
|
<button onclick={() => navigate("start")}>Tillbaka</button>
|
||||||
|
</span>
|
||||||
|
<h1>Kroppsfettkalkylator, Navy</h1>
|
||||||
|
</header>
|
||||||
|
<output>
|
||||||
|
{#if fatPercentage > 0}
|
||||||
|
<span>{Math.round(fatPercentage * 100) / 100}</span>
|
||||||
|
{/if}
|
||||||
|
</output>
|
||||||
|
<form>
|
||||||
|
<div class="gender">
|
||||||
|
<label>
|
||||||
|
Man
|
||||||
|
<input
|
||||||
|
bind:group={gender}
|
||||||
|
type="radio"
|
||||||
|
name="gender"
|
||||||
|
value="male"
|
||||||
|
id="male"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Kvinna
|
||||||
|
<input
|
||||||
|
bind:group={gender}
|
||||||
|
type="radio"
|
||||||
|
name="gender"
|
||||||
|
value="female"
|
||||||
|
id="female"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<label>
|
||||||
|
Kroppslängd
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
bind:value={height}
|
||||||
|
type="number"
|
||||||
|
id="height"
|
||||||
|
name="height"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Midja
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
type="number"
|
||||||
|
bind:value={waist}
|
||||||
|
id="waist"
|
||||||
|
name="waist"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
{#if gender == "female"}
|
||||||
|
<label>
|
||||||
|
Höft
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
type="number"
|
||||||
|
bind:value={hips}
|
||||||
|
id="hips"
|
||||||
|
name="hips"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
{/if}
|
||||||
|
<label>
|
||||||
|
Hals
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
type="number"
|
||||||
|
bind:value={neck}
|
||||||
|
id="neck"
|
||||||
|
name="neck"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.gender {
|
||||||
|
grid-column: 1 / 2;
|
||||||
|
grid-row: 1 / 4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
56
src/lib/OneRepMax.svelte
Normal file
56
src/lib/OneRepMax.svelte
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { navigate } from "./common";
|
||||||
|
|
||||||
|
let oneRepMax = $state(0);
|
||||||
|
let reps = $state(null);
|
||||||
|
let weight = $state(null);
|
||||||
|
|
||||||
|
// https://www.athlegan.com/calculate-1rm
|
||||||
|
|
||||||
|
const calculate = () => {
|
||||||
|
if (weight && reps) {
|
||||||
|
oneRepMax = weight / (1.0278 - 0.0278 * reps);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<span>
|
||||||
|
<button onclick={() => navigate("start")}>Tillbaka</button>
|
||||||
|
</span>
|
||||||
|
<h1>1RM</h1>
|
||||||
|
</header>
|
||||||
|
<output>
|
||||||
|
{#if oneRepMax > 0}
|
||||||
|
<span>{Math.round(oneRepMax * 100) / 100}</span>
|
||||||
|
{/if}
|
||||||
|
</output>
|
||||||
|
<form>
|
||||||
|
<label>
|
||||||
|
Reps
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
bind:value={reps}
|
||||||
|
type="number"
|
||||||
|
id="reps"
|
||||||
|
name="reps"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Vikt
|
||||||
|
<input
|
||||||
|
onchange={() => calculate()}
|
||||||
|
type="number"
|
||||||
|
bind:value={weight}
|
||||||
|
id="weight"
|
||||||
|
name="weight"
|
||||||
|
size="5"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { currentView } from "./store";
|
import { currentView } from "./store";
|
||||||
|
|
||||||
export const navigate = (page: "start" | "fatcalc") =>
|
export const navigate = (
|
||||||
currentView.update((_) => page);
|
page: "start" | "armyfatcalc" | "navyfatcalc" | "onerepmax",
|
||||||
|
) => currentView.update((_) => page);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue