Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bhj/cdgraphics
A fast, flexible CD+Graphics (CD+G) renderer
https://github.com/bhj/cdgraphics
canvas cdg cdgraphics createimagebitmap html5 html5-canvas html5-canvas-element html5-canvas-js javascript karaoke
Last synced: 12 days ago
JSON representation
A fast, flexible CD+Graphics (CD+G) renderer
- Host: GitHub
- URL: https://github.com/bhj/cdgraphics
- Owner: bhj
- License: mit
- Created: 2016-02-22T20:36:45.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2024-06-21T11:19:37.000Z (5 months ago)
- Last Synced: 2024-10-14T04:24:36.788Z (25 days ago)
- Topics: canvas, cdg, cdgraphics, createimagebitmap, html5, html5-canvas, html5-canvas-element, html5-canvas-js, javascript, karaoke
- Language: JavaScript
- Homepage:
- Size: 657 KB
- Stars: 23
- Watchers: 4
- Forks: 12
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# cdgraphics
A fast, flexible [CD+Graphics (CD+G)](https://en.wikipedia.org/wiki/CD%2BG) renderer.
* Designed for [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
* Audio synchronization when used with [currentTime](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#attr-currentTime)
* Optional background keying (transparency)
* Reports background RGBA and content bounds for each frame
* Supports all [modern browsers](https://caniuse.com/mdn-api_imagedata_imagedata)
* No dependencies## Installation
```
$ npm i cdgraphics
```## API
### `new CDGraphics()`
Instantiates a new parser/renderer.
```js
import CDGraphics from 'cdgraphics'
const cdg = new CDGraphics()
```### `.load(buffer)`
Loads a CD+G file from an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), which can be had via the [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) of a [fetch()](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). You must `load()` a CD+G file before calling `render()`.
```js
fetch(cdgFileUrl)
.then(response => response.arrayBuffer())
.then(buffer => cdg.load(buffer))
```### `.render(time, [options])`
- `time`: Number (in seconds) of the frame to render. Should usually be the [currentTime](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#attr-currentTime) of an `` element.
- `options`: Object with one or more of the following:
- `forceKey`: Boolean forcing the background to be transparent, even if the CD+G title did not explicitly specify it. Defaults to `false`.Returns an object with the following properties:
- `imageData`: [ImageData object](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) containing the rendered frame's pixel data.
- `isChanged`: Boolean indicating whether the frame changed since the last render. Useful for skipping unnecessary re-paints to a canvas.
- `backgroundRGBA`: Array containing the frame's background color in the form `[r, g, b, a]` with alpha being `0` or `1`. The reported alpha includes the effect of the forceKey option, if enabled.
- `contentBounds`: Array containing the coordinates of a bounding box that fits the frame's non-transparent pixels in the form `[x1, y1, x2, y2]`. Typically only useful when the forceKey option is enabled.## Usage
The following excerpt demonstrates an audio-synced render loop that draws to a canvas. See [the demo code](https://github.com/bhj/cdgraphics/blob/master/demo/demo.js) for a more complete example.
```js
const audio = document.getElementById('audio')
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
let frameIdconst doRender = time => {
const frame = cdg.render(time)
if (!frame.isChanged) returncreateImageBitmap(frame.imageData)
.then(bitmap => {
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight)
ctx.drawImage(bitmap, 0, 0, canvas.clientWidth, canvas.clientHeight)
})
}// render loop
const pause = () => cancelAnimationFrame(frameId)
const play = () => {
frameId = requestAnimationFrame(play)
doRender(audio.currentTime)
}// follow events
audio.addEventListener('play', play)
audio.addEventListener('pause', pause)
audio.addEventListener('ended', pause)
audio.addEventListener('seeked', () => doRender(audio.currentTime))
```## Demo
To run the demo and see how it all comes together:
1. Clone the repo
2. Place your audio and .cdg file in the `demo` folder
3. Update lines 1 and 2 of `demo/demo.js` with those filenames
4. `$ npm i`
5. `$ npm run demo`## Acknowledgements
* Originally based on the [player by Luke Tucker](https://github.com/ltucker/html5_karaoke), with improvements from [Keith McKnight's fork](https://github.com/kmck/karaoke)
* [Jim Bumgardner's CD+G Revealed](http://jbum.com/cdg_revealed.html) document/specification## License
[ISC](https://opensource.org/licenses/ISC)