Add Ethan
This commit is contained in:
parent
3de767b0cd
commit
78822334d9
27
flake.lock
Normal file
27
flake.lock
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1711163522,
|
||||
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
27
flake.nix
Normal file
27
flake.nix
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
description = "Cool people homepage";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
system = "aarch64-darwin";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
devShells.${system}.default =
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
yarn
|
||||
nodePackages.svelte-language-server
|
||||
nodePackages.typescript-language-server
|
||||
nodePackages.vscode-css-languageserver-bin
|
||||
tree
|
||||
];
|
||||
shellHook = ''
|
||||
exec zsh
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
@ -20,6 +20,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"metaphone-ts": "^1.0.1",
|
||||
"pokedex-api": "^1.1.2"
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
"liv",
|
||||
"nis",
|
||||
"gremlin",
|
||||
"ethan"
|
||||
];
|
||||
</script>
|
||||
|
||||
|
158
src/routes/b/ethan/+page.svelte
Normal file
158
src/routes/b/ethan/+page.svelte
Normal file
@ -0,0 +1,158 @@
|
||||
<script lang="ts">
|
||||
import CountDownTimer from "$lib/elem/CountDownTimer.svelte";
|
||||
import { metaphone } from "metaphone-ts";
|
||||
|
||||
let sounds = [
|
||||
"B",
|
||||
"X",
|
||||
"S",
|
||||
"K",
|
||||
"J",
|
||||
"T",
|
||||
"F",
|
||||
"H",
|
||||
"L",
|
||||
"M",
|
||||
"N",
|
||||
"P",
|
||||
"R",
|
||||
"0",
|
||||
"W",
|
||||
"Y",
|
||||
];
|
||||
|
||||
let custom_message = "";
|
||||
|
||||
let message =
|
||||
"Happy birthday Ethan! You are easily one of the closest friends I've ever had, and it's not even close. I've never met someone who's so willing to be goofy and crazy with me, but also has the capacity to be so serious when needed. I appreciate you as a friend as also just as a human on this planet. You make a difference in my life, so I'm sure you do for other people as well.";
|
||||
|
||||
let played_words: string[] = [];
|
||||
let playing = false;
|
||||
let playing_message = "";
|
||||
let stop = false;
|
||||
async function playAudio(message: string) {
|
||||
playing_message = message;
|
||||
playing = true;
|
||||
played_words = [];
|
||||
let words = message.split(" ");
|
||||
for (const word of words) {
|
||||
played_words.push(word);
|
||||
played_words = played_words;
|
||||
let phonemes = metaphone(word);
|
||||
for (const phoneme of phonemes) {
|
||||
let audio = document.querySelector(`#audio-${phoneme}`);
|
||||
if (audio) {
|
||||
audio.play();
|
||||
await new Promise((r) => setTimeout(r, audio.duration * 1000 - 100));
|
||||
}
|
||||
if (stop) {
|
||||
playing = false;
|
||||
stop = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, Math.min(word.length * 50, 300)));
|
||||
}
|
||||
playing = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div id="content">
|
||||
<div id="audio">
|
||||
{#each sounds as sound}
|
||||
<audio id="audio-{sound}" src="/ethan/{sound}.mp3"></audio>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div id="message">
|
||||
<h1>Hi Ethan!</h1>
|
||||
|
||||
<p>
|
||||
Do you remember that one time I was working on a procedural voices
|
||||
algorithm for a game project? Well, the game isn't finished and neither
|
||||
is the voice algorithm but ¯\_(ツ)_/¯.
|
||||
</p>
|
||||
<p>
|
||||
Anyways, you helped me create a voice using your samples, so I thought
|
||||
it would be fun to steal those and make you read your birthday message
|
||||
to yourself!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="automessage">
|
||||
<button disabled={playing} on:click={() => playAudio(message)}
|
||||
>Play</button
|
||||
>
|
||||
<button
|
||||
disabled={!playing}
|
||||
on:click={() => {
|
||||
stop = true;
|
||||
}}>Stop</button
|
||||
>
|
||||
<p>
|
||||
{#each message.split(" ") as word, i}
|
||||
{#if played_words.length >= i + 1 && playing_message == message}
|
||||
<span class="played">
|
||||
{word + " "}
|
||||
</span>
|
||||
{:else}
|
||||
{word + " "}
|
||||
{/if}
|
||||
{/each}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2>Write your own message if you want!</h2>
|
||||
|
||||
<div id="custommessage">
|
||||
<form
|
||||
on:submit|preventDefault={() => {
|
||||
playAudio(custom_message);
|
||||
}}
|
||||
>
|
||||
<input placeholder="custom mesage.." bind:value={custom_message} />
|
||||
<button disabled={playing}>Play</button>
|
||||
<button
|
||||
type="button"
|
||||
disabled={!playing}
|
||||
on:click={() => {
|
||||
stop = true;
|
||||
}}>Stop</button
|
||||
>
|
||||
</form>
|
||||
<p>
|
||||
{#each custom_message.split(" ") as word, i}
|
||||
{#if played_words.length >= i + 1 && playing_message == custom_message}
|
||||
<span class="played">
|
||||
{word + " "}
|
||||
</span>
|
||||
{:else}
|
||||
{word + " "}
|
||||
{/if}
|
||||
{/each}
|
||||
</p>
|
||||
</div>
|
||||
<CountDownTimer birthday={"Mar 25"} />
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
|
||||
|
||||
main {
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
#content {
|
||||
max-width: 40em;
|
||||
}
|
||||
|
||||
.played {
|
||||
color: cyan;
|
||||
}
|
||||
</style>
|
BIN
static/ethan/0.mp3
Normal file
BIN
static/ethan/0.mp3
Normal file
Binary file not shown.
BIN
static/ethan/A.mp3
Normal file
BIN
static/ethan/A.mp3
Normal file
Binary file not shown.
BIN
static/ethan/B.mp3
Normal file
BIN
static/ethan/B.mp3
Normal file
Binary file not shown.
BIN
static/ethan/E.mp3
Normal file
BIN
static/ethan/E.mp3
Normal file
Binary file not shown.
BIN
static/ethan/F.mp3
Normal file
BIN
static/ethan/F.mp3
Normal file
Binary file not shown.
BIN
static/ethan/H.mp3
Normal file
BIN
static/ethan/H.mp3
Normal file
Binary file not shown.
BIN
static/ethan/I.mp3
Normal file
BIN
static/ethan/I.mp3
Normal file
Binary file not shown.
BIN
static/ethan/J.mp3
Normal file
BIN
static/ethan/J.mp3
Normal file
Binary file not shown.
BIN
static/ethan/K.mp3
Normal file
BIN
static/ethan/K.mp3
Normal file
Binary file not shown.
BIN
static/ethan/L.mp3
Normal file
BIN
static/ethan/L.mp3
Normal file
Binary file not shown.
BIN
static/ethan/M.mp3
Normal file
BIN
static/ethan/M.mp3
Normal file
Binary file not shown.
BIN
static/ethan/N.mp3
Normal file
BIN
static/ethan/N.mp3
Normal file
Binary file not shown.
BIN
static/ethan/O.mp3
Normal file
BIN
static/ethan/O.mp3
Normal file
Binary file not shown.
BIN
static/ethan/P.mp3
Normal file
BIN
static/ethan/P.mp3
Normal file
Binary file not shown.
BIN
static/ethan/R.mp3
Normal file
BIN
static/ethan/R.mp3
Normal file
Binary file not shown.
BIN
static/ethan/S.mp3
Normal file
BIN
static/ethan/S.mp3
Normal file
Binary file not shown.
BIN
static/ethan/T.mp3
Normal file
BIN
static/ethan/T.mp3
Normal file
Binary file not shown.
BIN
static/ethan/U.mp3
Normal file
BIN
static/ethan/U.mp3
Normal file
Binary file not shown.
BIN
static/ethan/W.mp3
Normal file
BIN
static/ethan/W.mp3
Normal file
Binary file not shown.
BIN
static/ethan/X.mp3
Normal file
BIN
static/ethan/X.mp3
Normal file
Binary file not shown.
BIN
static/ethan/Y.mp3
Normal file
BIN
static/ethan/Y.mp3
Normal file
Binary file not shown.
@ -639,6 +639,11 @@ merge2@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
metaphone-ts@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/metaphone-ts/-/metaphone-ts-1.0.1.tgz#d3a9abbbbdb363bf82dcc755de7467352a8889f2"
|
||||
integrity sha512-98u3uoBxvsvRdxo4jE50evb0w4qDDU56pQHJnx8pT6UMwQdYlsekTUtbcJTppk38Nbe+I53eQsELIEbV9VRgXg==
|
||||
|
||||
micromatch@^4.0.4:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
||||
|
Loading…
Reference in New Issue
Block a user