UNPKG

kashi

Version:

Singing at the top of my lungs

217 lines (155 loc) β€’ 9.41 kB
<div align="center"> <a href="https://gitlab.com/lucasmc64/kashi">GitLab</a> β€’ <a href="https://www.npmjs.com/package/kashi">NPM</a> β€’ <a href="https://unpkg.com/browse/kashi@latest">CDN</a> β€’ <a href="https://ko-fi.com/lucasmc64">Ko-fi</a> </div> ![Kashi](https://gitlab.com/lucasmc64/kashi/-/raw/main/readme/cover.png) # 🎀 Kashi ## 🎯 Goal This project is a dependency-free library that aims to provide a way to correctly read, format, structure, and display song lyrics. ## πŸ“œ Features - [x] 🎡 Process and list song lyrics in .lrc files - [x] πŸ’ͺ Supports both directly inputting the .lrc file and a URL that returns it - [x] βœ‰οΈ Implements the Observer pattern and emits events at each step of the process whenever something changes - [x] ✏️ Allows you to enter custom text when the lyrics line is empty - [ ] 🎀 Synchronizes the lyrics with the music that is playing - [ ] 🎩 Supports multiple lyrics for the same song (useful to keep track of the original lyrics and their translation) - [ ] 🧞 Supports the [Walaoke extension](https://en.wikipedia.org/wiki/LRC_(file_format)#Walaoke_extension) - [ ] πŸ•–οΈ Supports the [A2 extension](https://en.wikipedia.org/wiki/LRC_(file_format)#A2_extension_(Enhanced_LRC_format)) ## 🎨 How to use it in my project? ### <span id="classic-scripts">πŸ™Œ Classic scripts</span> The project is also exported using [UMD](https://github.com/umdjs/umd), which means that all variables and classes such as the `Kashi` class is exposed globally, and can be used in any script imported after the library. > **Note**: You should **change `X.Y.Z` to the library version number** according to your needs, this is just an example. It is recommended to always use the latest version. > > It is recommended that you pin to the latest stable version of the lib. However, if you always want to use the latest version, you can also use `latest` instead of a predefined version number. **Be careful** though, breaking changes may be introduced and your project may need to adapt to the changes. ```html <!DOCTYPE html> <html> <head> <!-- ... --> <script src="https://unpkg.com/kashi@X.Y.Z/kashi.js" defer></script> <!-- ... --> </head> <body> <div id="kashi"></div> </body> </html> ``` ```js "use strict"; // Using the file or using a url, both works fine new Kashi({ // url, // Public link that returns the file when a GET request is made OR... file. // Loaded from an input[type="file"] or anywhere else container: document.getElementById("kashi"), }); ``` ### πŸ“¦οΈ ES6 Modules The HTML is very similar to the classic scripts version, just change the `.js` extension to `.mjs` (and maybe will be necessary to adds a `type="module"` too), which will result in something similar to this: > **Note**: Please read the [previous section](#classic-scripts) to get the details involved in importing and choosing a package version, they are the same here. ```html <script src="https://unpkg.com/kashi@X.Y.Z/kashi.mjs" type="module" defer ></script> ``` ```javascript import { Kashi } from "kashi"; // Usage is essentially the same as in the previous section // Using the file or using a url, both works fine new Kashi({ // url, // Public link that returns the file when a GET request is made OR... file. // Loaded from an input[type="file"] or anywhere else container: document.getElementById("kashi"), }); ``` ### βš›οΈ React Install the lib using your favorite package manager. ```bash npm install kashi ``` Since the library was designed primarily to be used with vanilla JS, a _helper_ component needs to be created to encapsulate Kashi's behavior and make it simple to reuse throughout the application. > **Note**: There is TypeScript support, and even if your project doesn't use the JS superset, it should help VSCode and other editors provide autocomplete/code suggestions. ```tsx import { useEffect, useRef } from "react"; import { Kashi, KashiProps } from "kashi"; // Example using Vite, React and TypeScript export const KashiWrapper = (props: KashiProps) => { const ref = useRef<HTMLDivElement>(null); useEffect(() => { if (ref.current) { new Kashi({ ...props, container: ref.current, }); } return () => { // Required to avoid duplication when React is in Strict Mode if (ref.current) { ref.current.innerHTML = ""; } }; }, [ref.current]); return <div className="kashi-wrapper" ref={ref} />; }; ``` ## 🧐 Constructor properties You must pass some properties to Kashi to define what lyrics display and where. Here are its specifications: | Property | Type | Default value | Is required? | Description | | --------------- | ------------------ | ------------- | ------------ | ----------------------------------------- | | `file` | `Blob` (or `File`) | - | No | Lyrics file | | `url` | `string` | - | No | Lyrics url | | `container` | `HTMLDivElement` | - | Yes | Element where the lyrics will be inserted | | `emptyLineText` | `string` | `🎝` | No | Custom text for empty lines of the lyrics | > Neither `file` nor `url` are β€œmandatory”, but **at least one of these properties must be specified**, otherwise an error will be thrown. ## πŸ‘Ύ Generated HTML structure The `div#kashi` represents the `container` passed to `Kashi` where the song lyrics will be inserted. Each line of lyrics present in the lrc file will be wrapped by a `<p></p>` tag and inserted into the `container`. Here's an example: ```html <div id="kashi"> <!-- ... --> <p>Binkusu no sake wo todoke ni yuku yo</p> <p>Umikaze kimakase namimakase</p> <p>Shio no mukou de yuuhi mo sawagu</p> <p>Sora nya wa wo kaku tori no uta</p> <!-- ... --> </div> ``` ## πŸ“‚ Methods and attributes The instance generated by `Kashi` has some public methods and attributes that can be used to query or change properties on the fly. | Name | Type | Description | | ------------------ | --------- | ------------------------------------------------------------ | | `url` | Attribute | Returns the url from the current lyrics if it was fetched from a link | | `file` | Attribute | Returns the file from the current lyrics | | `emptyLineText` | Attribute | Returns the default text set for empty lines | | `setUrl` | Method | Function capable of changing the current lyrics file by passing the **url** of the new file | | `setFile` | Method | Function capable of changing the current lyrics file by passing the the new **file** | | `setEmptyLineText` | Method | Function capable of changing the text defined for empty lines | | `subscribe` | Method | Function capable of defining a callback to be executed when a given event is triggered | | `unsubscribe` | Method | Function capable of making a callback to stop listening to an event | | `notify` | Method | Function capable of triggering an event | ## 🍾 Events When creating a new instance using `Kashi` you will have access to the `subscribe`, `unsubscribe` and `notify` methods, these methods can be used respectively to listen for an event, stop listening for an event and manually trigger an event. Below is the list of events triggered internally: | Event | Data | Trigger | | ------------------- | --------------------------- | ------------------------------------------------------------ | | `urlSet` | `{ url: string }` | When instantiating by informing `url` or calling the `setUrl` method | | `fileSet` | `{ file: Blob }` | When instantiating or calling the `setFile` method (when calling the `setUrl` method the file will be fetched and the `setFile` method called) | | `emptyLineTextSet` | `{ emptyLineText: string }` | When instantiating by informing `emptyLineText` or calling the `setEmptyLineText` method | | `lyricLinesUpdated` | `{ lyricLines: string[] }` | When inserting/updating lyrics in HTML | ## πŸ€” How do I run the project on my machine? The first step is to clone the project, either via terminal or even by downloading the compressed file (.zip). After that, go ahead. ### πŸ› οΈ Requirements - [NodeJS and NPM](https://nodejs.org) ### ✨ Running the project With the dependencies properly installed, still in the terminal, run `npm start`. Create a simple demo project using vanilla HTML/JS and use the files in the `dist` folder for testing. You can also create a demo project using React and use [npm link](https://docs.npmjs.com/cli/v9/commands/npm-link). ### πŸŽ‰ If everything went well... Now you are running the project beautifully! ## ✏️ License This project is under the GPL v3 license. See the [LICENSE](https://gitlab.com/lucasmc64/kashi/-/blob/main/LICENSE) for more information. --- Made with πŸ’™ by lucasmc64 πŸ‘‹ [Get in touch!](https://www.linkedin.com/in/lucasmc64/)