Non-Potable Macchiato

    cdgraphics

    6.0.0 • Public • Published

    cdgraphics

    A fast, flexible CD+Graphics (CD+G) renderer.

    Installation

    $ npm i cdgraphics
    

    API

    new CDGraphics()

    Instantiates a new parser/renderer.

    import CDGraphics from 'cdgraphics'
    const cdg = new CDGraphics()

    .load(buffer)

    Loads a CD+G file. Accepts an ArrayBuffer, which can be had via the Response of a fetch(). You must load() a CD+G file before calling render().

    fetch(cdgFileUrl)
      .then(response => response.arrayBuffer())
      .then(buffer => cdg.load(buffer))

    .render(time, [options])

    • time: Number (in seconds) of the frame to render. This will usually be the currentTime of an <audio> element.
    • options: Object with one or more of the following:
      • forceKey: Forces backgrounds 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 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 the canvas.
    • backgroundRGBA: Array containing the color of the frame's background 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 scales and draws to a canvas. See the demo code for a more complete example.

    const audio = document.getElementById('audio')
    const canvas = document.getElementById('canvas')
    const ctx = canvas.getContext('2d')
    let frameId
    
    const doRender = time => {
     const frame = cdg.render(time)
     if (!frame.isChanged) return
    
     createImageBitmap(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 <audio> events
    audio.addEventListener('play', play)
    audio.addEventListener('pause', pause)
    audio.addEventListener('ended', pause)
    audio.addEventListener('seeked', () => doRender(audio.currentTime))

    NOTE: As of this writing Safari does not fully implement createImageBitmap, however there are other methods of scaling the image data when drawing to a canvas.

    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
    6. Browse to http://localhost:8080 (the demo is served by webpack-dev-server)

    Acknowledgements

    License

    ISC

    Install

    npm i cdgraphics

    DownloadsWeekly Downloads

    70

    Version

    6.0.0

    License

    ISC

    Unpacked Size

    40.6 kB

    Total Files

    11

    Last publish

    Collaborators

    • radrootllc