Skip to content

Commit

Permalink
feat: create GitHub Pages demo
Browse files Browse the repository at this point in the history
added static files to deploy a demo page using GitHub Pages
  • Loading branch information
mcanam committed Apr 28, 2024
1 parent 1fda041 commit 6820475
Show file tree
Hide file tree
Showing 5 changed files with 517 additions and 0 deletions.
Binary file added favicon.ico
Binary file not shown.
Binary file added images/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">

<head>
<title>Liricle</title>

<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#00001b">

<meta name="title" content="Liricle">
<meta name="author" content="mcanam">
<meta name="description" content="Javascript lyrics synchronizer library">

<meta property="og:title" content="Liricle">
<meta property="og:description" content="Javascript lyrics synchronizer library">
<meta property="og:image" content="https://mcanam.github.io/liricle/images/banner.png">
<meta property="og:url" content="https://mcanam.github.io/liricle">

<meta name="twitter:title" content="Liricle">
<meta name="twitter:description" content="Javascript lyrics synchronizer library">
<meta name="twitter:image" content="https://mcanam.github.io/liricle/images/banner.png">
<meta name="twitter:card" content="summary_large_image">

<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/nouislider.min.css">
<link rel="stylesheet" href="style.css">
</head>

<body>
<header class="topbar">
<svg class="topbar__logo" xmlns="http://www.w3.org/2000/svg" width="40" height="72" fill="none" viewBox="0 0 40 72">
<path fill="#00F2C6" fill-rule="evenodd" d="M.026 28.553 0 28.57V0l19.974 14.305.026-.02v28.572L.026 28.553Z" clip-rule="evenodd" />
<path fill="#0277EF" fill-rule="evenodd" d="m0 57.143.026-.019L20 71.429V42.857l-.026.019L0 28.571v28.572Zm20 14.286L40 57.18 20 42.857V71.43Z" clip-rule="evenodd" />
</svg>
<h1 class="topbar__title">Liricle</h1>
<a href="https://github.com/mcanam/liricle" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z" />
</svg>
</a>
</header>

<main class="lyric" id="$lyric">
<div class="lyric__cursor" id="$lyric_cursor"></div>
<div class="lyric__content" id="$lyric_content"></div>
</main>

<div class="player">
<audio class="player__audio" id="$player_audio"></audio>
<button class="player__button" data-play="false" id="$player_play_button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-fill" viewBox="0 0 16 16">
<path d="m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pause-fill" viewBox="0 0 16 16">
<path d="M5.5 3.5A1.5 1.5 0 0 1 7 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5zm5 0A1.5 1.5 0 0 1 12 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5z" />
</svg>
</button>
<div class="player__progress">
<div class="player__slider" id="$player_slider"></div>
<div class="player__time">
<span class="player__time--current" id="$player_time_current">00:00.00</span>
<span class="player__time--total" id="$player_time_total">00:00.00</span>
</div>
</div>
<button class="player__button" id="$menu_button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
</svg>
</button>
</div>

<div class="menu" id="$menu">
<div class="menu__item">
<label class="menu__label">Load lyric</label>
<button class="menu__input" id="$menu_load_lyric">choose file</button>
</div>
<div class="menu__item">
<label class="menu__label">Load audio</label>
<button class="menu__input" id="$menu_load_audio">choose file</button>
</div>
<div class="menu__item">
<label class="menu__label">Lyric offset</label>
<input class="menu__input" id="$menu_lyric_offset" type="number" value="0" />
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/nouislider.min.js"></script>
<script src="script.js"></script>
</body>

</html>
198 changes: 198 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
fetch("https://raw.githubusercontent.com/mcanam/liricle/main/package.json").then(async res => {
const { version } = await res.json();
const script = document.createElement("script");

script.src = `https://cdn.jsdelivr.net/npm/liricle@${version}/dist/liricle.js`;
script.onload = () => main(window.Liricle);

document.body.append(script);
});

function main(Liricle) {
window.liricle = new Liricle();

////////////////////// PLAYER //////////////////////////////

let sliding = false;

noUiSlider.create($player_slider, {
start: 0,
connect: "lower",
range: { min: 0, max: 100 },
});

$player_slider.noUiSlider.on("slide", () => {
const value = parseFloat($player_slider.noUiSlider.get());
sliding = true;
$player_audio.currentTime = value;
});

$player_slider.noUiSlider.on("change", () => {
sliding = false;
});

$player_play_button.addEventListener("click", () => {
if (isNaN($player_audio.duration)) return;

if ($player_play_button.dataset.play == "false") {
$player_audio.play();
$player_play_button.dataset.play = "true";
} else {
$player_audio.pause();
$player_play_button.dataset.play = "false";
}
});

$player_audio.src = "https://raw.githubusercontent.com/mcanam/assets/main/liricle-demo/audio.mp3";

$player_audio.addEventListener("canplaythrough", () => {
const duration = $player_audio.duration;

$player_slider.noUiSlider.updateOptions({
range: { min: 0, max: duration },
});

$player_time_total.innerText = timeToText(duration);
});

$player_audio.addEventListener("timeupdate", () => {
const time = $player_audio.currentTime;

if (!sliding) $player_slider.noUiSlider.set(time);
$player_time_current.innerText = timeToText(time);
});

$player_audio.addEventListener("ended", () => {
$player_play_button.dataset.play = "false";
});

function timeToText(time) {
let min = Math.floor(time / 60);
let sec = (time % 60).toFixed(2);
min = min < 10 ? "0" + min : min;
return min + ":" + sec;
}

////////////////////// MENU //////////////////////////////

let isShow = false;

$menu_load_lyric.addEventListener("click", () => {
loadFile(dataURL => liricle.load({ url: dataURL }));
});

$menu_load_audio.addEventListener("click", () => {
loadFile(dataURL => ($player_audio.src = dataURL));
});

$menu_lyric_offset.addEventListener("blur", () => {
liricle.offset = $menu_lyric_offset.value;
});

$menu_button.addEventListener("click", () => {
const rect = $menu_button.getBoundingClientRect();

$menu.style.top = rect.y - $menu.offsetHeight - 20 + "px";
$menu.style.left = rect.x - $menu.offsetWidth + 50 + "px";
$menu.classList[isShow ? "remove" : "add"]("show");

isShow = !isShow;
});

window.addEventListener("click", e => {
if (!isShow) return;
if (e.target.closest(".menu")) return;
if (e.target == $menu_button) return;

$menu.classList.remove("show");
isShow = !isShow;
});

function loadFile(callback) {
const input = document.createElement("input");
const reader = new FileReader();

input.type = "file";
input.multiple = false;

input.onchange = () => {
const file = input.files[0];
reader.readAsDataURL(file);
};

reader.onload = () => {
callback(reader.result);
};

input.click();
}

////////////////////// LYRIC //////////////////////////////

let $lines = [];
let $activeLine = null;

liricle.load({
url: "https://raw.githubusercontent.com/mcanam/assets/main/liricle-demo/lyric-enhanced.lrc"
});

liricle.on("load", ({ tags, lines, enhanced }) => {
$lines = [];
$activeLine = null;
$lyric_content.innerHTML = "";

// set default offset
if ("offset" in tags) {
liricle.offset = tags.offset;
$menu_lyric_offset.value = tags.offset;
}

lines.forEach(line => {
const $line = document.createElement("div");
$line.className = "lyric__line";
$line.innerHTML = line.words ? "" : line.text;

if (enhanced && line.words) {
line.words.forEach(word => {
const $word = document.createElement("span");
$word.className = "lyric__word";
$word.innerHTML = word.text + " ";

$line.append($word);
});
}

$lines.push($line);
$lyric_content.append(...$lines);
});

if (enhanced) $lyric_cursor.style.display = "block";
});

liricle.on("sync", (line, word) => {
if ($activeLine) {
$activeLine.classList.remove("active");
}

$activeLine = $lines[line.index];
$activeLine.classList.add("active");

const oh1 = $lyric.offsetHeight / 2;
const oh2 = $activeLine.offsetHeight / 2;

$lyric.scrollTop = $activeLine.offsetTop - (oh1 - oh2);

if (word) {
const $word = $activeLine.children[word.index];

$lyric_cursor.style.width = $word.offsetWidth + "px";
$lyric_cursor.style.top = ($word.offsetTop + $word.offsetHeight) + "px";
$lyric_cursor.style.left = $word.offsetLeft + "px";
}
});

$player_audio.addEventListener("timeupdate", () => {
const time = $player_audio.currentTime;
liricle.sync(time);
});
}
Loading

0 comments on commit 6820475

Please sign in to comment.