GithubHelp home page GithubHelp logo

visgl / hubble.gl Goto Github PK

View Code? Open in Web Editor NEW
133.0 5.0 27.0 23.5 MB

A client-side JavaScript library for animating data visualizations and rendering videos.

Home Page: https://hubble.gl

License: MIT License

JavaScript 99.77% Shell 0.23%
web video data-visualization animation recording encoding

hubble.gl's Introduction

version build downloads

This project is experimental and the APIs may change.

hubble.gl | Website

Animate and encode WebGL data visualizations.

hubble.gl maps parameters (usually animating over time) to a visualization - e.g. deck.gl, kepler.gl; and encode what you see into media - e.g. MP4, PNG, GIF.

  • High Quality Video: 60+fps framerates, up to 8k resolution, and a variety of formats. Render a quick draft or with loseless encoding. Fine tune timing and look with keyframe markers and render everything in the same app.

  • Easy Integration: Define animations for deck.gl or kepler.gl features, then render videos. Integrate with React UI components to interact with animation and rendering settings.

  • Client Side Library: Videos render and encode directly in the web browser. User data never leaves their machine. Since nothing runs on a server, sites can scale without computation costs.

Installation

npm install hubble.gl

Documentation

You can find the Hubble.gl documentation on the website.

Examples

We have examples on the website.

Contributing

The main purpose of this repository is to continue to evolve Hubble.gl core, making it faster and easier to use. Development of Hubble.gl happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving Hubble.gl.

Code Of Conduct

Uber has adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.

Contributing Guide

Read our contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Hubble.gl.

License

This project is licensed under the MIT License - see the LICENSE file for details.

hubble.gl's People

Contributors

97morningstar avatar amuramoto avatar athomann avatar chrisgervang avatar dependabot[bot] avatar heshan0131 avatar igordykhta avatar isaacbrodsky avatar macrigiuseppe avatar raymonddashwu avatar unconed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

hubble.gl's Issues

[Bug] Rendering an empty animation with the GIF encoder may prompt webcam image captures.

Describe the bug
When hubble.gl is only partially integrated there is an edge case that can cause a developers webcam to be captured and saved onto their local machine. The data never leaves their local computer, and the web browser prompts the developer for permission before the webcam is active. That said, we don't want this occurring so we should fix this issue.

To Reproduce
We believe this issue occurs as default behavior of gifshot when there aren't any image frames passed in: https://github.com/yahoo/gifshot/blob/master/src/gifshot.js#L2733-L2765

Steps to reproduce the behavior:

const encoder = new GifEncoder();
encoder.start();
// no calls to encoder.add(), so no frames.
encoder.end();
// browser prompts for webcam permission
encoder.save();

Expected behavior
Hubble should use gifshot such that it never will capture from webcam.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Mac
  • Browser Chrome

Additional context
Add any other context about the problem here.

Faster rendering

Hubble depends on the WebMWriter library to record webm video within the WebMEncoder class.

WebMWriter uses canvas.toDataURL under the hood to serialize the canvas state as a base64-encoded string, which it later turns into a blob with the atob function. In my exploration this is the major cause of latency in recording with Hubble.

I did some testing with the more recent canvas.toBlob API with massive speedup improvements, but it seems like the webm-wasm library is even better suited to this task. See this example for how it could work in practice. I also looked into the MediaRecorder API (which Hubble exposes as StreamEncoder) but it seems to only support realtime stream capture (even though the stream API supports manual frame additions).

Further gains might be made with an OffscreenCanvas (which deck appears to support) to keep everything off the main thread, though my theory is that simply replacing the renderer will be sufficient.

[Add] montage image export example

  • basic proof of concept with 1920x1080
  • solution that works on any resolution (5000x5000 isn't correct)
  • docs on how to concatenate the images

Before opening an issue...

Generic Q&A and help are moved to Discussions!

Screen Shot 2020-12-29 at 1 37 33 PM

Thank you for contributing to hubble.gl! We currently accept two types of issues: bug report and feature proposal. When opening an issue, please choose one of the templates, and fill in the information as required by the template. Including code snippets, Codepen/CodeSandbox links and screenshots usually help bugs get resolved faster.

Many of the maintainers are volunteers. Please be courteous to each other. If you are new to the community, we encourage you to try to debug and fix minor issues and submit a PR. Visit our Contribution Guide and Code of Conduct for more information.

[Package] standalone hubble.gl bundle

Websites that do not use javascript bundlers should be able to import core hubble.gl classes using something like

<html>
  <head>
    <script src="https://unpkg.com/hubble.gl@latest/dist.min.js"></script>
  </head>
  ...
</html>

[Bug] installing on next.js causes error

Describe the bug
Fatal error thrown when importing hubble.gl related to webm-writer running require('fs') in a browser environment.

To Reproduce
Steps to reproduce the behavior:

  1. Create a new next.js app
  2. npm install [email protected]
  3. Import anything from hubble in code
  4. npm run dev
  5. See error 'webm-writer fs not defined'

Expected behavior
hubble.gl should not throw this error in a browser environment.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser chrome
  • Version 93

Additional context
The issue is coming from hubble's webm-writer dependency and this line of code:

https://github.com/thenickdude/webm-writer-js/blob/ccec843765a4c8fe2e77b0d808730108de0e4353/src/BlobBuffer.js#L222-L226

Animation settings export/import for kepler component

Currently the kepler component only supports a limited subset of animations the libraries are capable of supporting. Camera, resolution, layer animations, and filter animations could all be possible - but the user needs a way to configure them.

Let's consider adding a JSON template exporter for the user to fill in a custom animation, and an JSON importer to apply the animation.

This advanced mode could be enabled with a toggle on the video export component, which when enabled replaces the existing configuration UI with a JSON editor and/or a download/upload button.

Time scrubber for kepler component

Currently it's difficult and time consuming to preview the ending of an animation because it needs to played back in full.

A simple time scrubber in the kepler video export component would solve this issue, and allow users to see any moment in the animation before rendering.

[Bug] Export video preview - Mapbox map isn't visible without layers

Describe the bug
Export video preview - Mapbox map isn't visible without layers.

To Reproduce
Steps to reproduce the behavior:

  1. In export-video-panel-preview.js update createLayers method to:
createLayers(){ 
   return []; 
}
  1. Go to examples/kepler-integration, run the example with yarn start-local

Expected behavior
Mapbox map should be visible.

Additional context
Creating a dummy layer without data or an invisible layer makes the Mapbox map visible.

createLayers(){ 
   // ...
   if(!layers.length) return [new ScatterplotLayer({})];
}

Screenshots
image

Export videos with the additive layer blend

Hi !

I am having an export issue with Hubble.gl for a Kepler.gl map.

You have to know that I don't know anything about coding even JS.
My request may seems easy to resolve but I can't find the solution.

So, I made a map (everything is made manually) and i'd like to have this map with the 'additive' layer blend like this

Capture

But when I try to export the map as a video the layer blend goes back to 'normal'

Capture123

It would be really thanksful if someone can help me :)

[Bug] Kepler Integration - Ratio in UI resets to 16:9

Describe the bug
The ratio in UI resets to 16:9 when a user switches between Animation and Settings tabs.

To Reproduce
Steps to reproduce the behavior:

  1. Run examples/kepler-integration
  2. Click on Settings tab
  3. Select 4x3 ratio
  4. Click on Animation tab
  5. Click on Settings tab
  6. Ratio is 16:9

Expected behavior
Ratio should stay 4x3

Persistent settings on the kepler component

Currently the settings are reset whenever the video export component for kepler is closed. This makes iteration very difficult.

It'd be better if the view state and render settings were saved and recalled whenever the window opens.

Add embedded video player in all example projects

The Pure JS and Standalone examples have embedded video players that also support video downloading. Let's add this to all of the website examples so that they can be set to auto-render and not automatically download files onto computers.

Hubble should support multiple viewStates

Summary & Description of Feature

Currently Hubble only has support for one viewState at a time in contrast to Deck, which can support multiple views and viewStates. If the user wants to use 2+ views they'll need more control over the viewState prop. Currently overwritten by Hubble during the animation here

Possibly adapter.getProps could be refactored to behave differently when the views prop is an array of two or more things, and figure out how to ensure this._getViewState() is nested under the correct key

Screenshot

image

Remove deck.gl version pinning

Root cause: the kepler.gl example needs deck.gl 8.2 to match the version used in kepler.gl. Currently this example is built into the hubble.gl website, so that is required to also pin to deck.gl 8.2. This pinning is cascaded throughout the repo currently, but if the kepler example is built separately from the rest of the website and examples we should be able to remove that pinning and always use the latest deck.gl version (or any version a user prefers to use).

  • build keplerlgl example eperatly from other website examples
    • deck.gl does this for the playground example. hubble needs to refactor the website build scripts to use deck's newer technique that allows for seperation.
  • remove version pins throughout repo.
    • remove resolutions
    • use peer dependencies where required based on minimum major API version compatibility
    • pin the kepler example, as needed.
  • build and test website
    • deploy and test
  • release hubble.gl patch that removes pinning

Backgroundable rendering

Hubble currently relies on Luma's Timeline and AnimationLoop classes which utilize the browser's requestAnimationFrame timer.

This is higher-precision and more realtime than alternatives (notably setTimeout) but requires that the tab be foregrounded in order for the timer to fire. The AnimationLoop class also, as far as I can tell, utilizes "wall time" to update animation state (i.e. Date.now for engineTime) instead of rendering frame-by-frame.

Because browsers only throttle timers running in the main thread and not on Worker threads, it should be possible to use a package like worker-timers to ensure that timers are always rendered.

[Bug] Gatsby docs aren't compiling

Describe the bug
There is an error generating the website during the gatsby start-up within the markdown plugin.

To Reproduce
Steps to reproduce the behavior:

node -v
>> v14.17.5
git clone [email protected]:visgl/hubble.gl.git
yarn boostrap
cd website
yarn
yarn start

Expected behavior
The website should compile all the existing markdown files, like these: https://github.com/visgl/hubble.gl/tree/master/docs/api-reference

Screenshots
Screen Shot 2021-10-07 at 3 08 12 PM
Screen Shot 2021-10-07 at 3 08 20 PM
Screen Shot 2021-10-07 at 3 09 42 PM
Screen Shot 2021-10-07 at 3 50 18 PM
Screen Shot 2021-10-07 at 3 52 54 PM
Screen Shot 2021-10-11 at 2 18 57 PM

Desktop (please complete the following information):

  • OS: Mac
  • Browser Chrome
  • Version 94

Additional context
Add any other context about the problem here.

[Proposal] [Small] Remove unnecessary design

How should we size the canvas for best experience and render?

I'm trying to create a canvas with these properties:

  1. the framebuffer size is set to the desired video resolution (and can re-scale as export settings change)
  2. the canvas element is scaled to fit in the user interface (and can re-scale as the user resizes the window)
  3. the viewport boundaries in the world don't change when framebuffer resolution changes

So far we've implemented this two ways with different results. Each only satisfy 2 of the 3 requirements.

Solution A: window.devicePixelRatio = factor

  1. ⛔️ - The actual framebuffer size is not always the expected size.
  2. ⛔️ - When container changes size the viewport bounds change.

Through an understanding of deck/mapbox internals we've determined the framebuffer size is set as a function window.devicePixelRatio and canvas css size. If we control these variables, we can indirectly control the framebuffer size. This sometimes works as expected, but also may result in an inaccurate height in the export depending on the container's size. The issue results in images with this resolution discrepancy:

Expected resolution: 3840 x 2160
Actual: 3840 x 216*5*

Here is where we set the devicePixelRatio which will internally be used by deck.gl and mapbox-gl-js to set the framebuffer size. Note: The issue also occurred before we rounded to the nearest even.

this._setDevicePixelRatio(nearestEven(dimension.width / width));

The canvas is styled to fit a container, and the container is set to an explicit size.

const deckStyle = {
width: '100%',
height: '100%'
};
const containerStyle = {
width: `${width}px`,
height: `${height}px`,
position: 'relative'
};

Note: The deck width/height props are set explicitly to the expected dimensions. But these are not used to set framebuffer size.

width={dimension.width}
height={dimension.height}

Current Conclusion

Resolution error is introduced when framebuffer size is derived in deck.gl and mapbox by multiplying their container size by devicePixelRatio. There doesn't appear to be an interface for explicitly setting framebuffer width/height in both libraries.

At some container sizes this solution works as expected, but further investigation is needed to ensure the output is always the expected resolution.

So far we've observed this solution works as expected when:

  • When requirement 2. is relaxed: when the scale factor is 1.0 and the container size matches the resolution.
  • When the browser window is sized to 1920x1080 with chrome dev tools, and the container height is hard coded to 1080px.

Solution B: transform: scale(${factor})

  1. ⛔️ - The boundary of the viewports have changed in these two images where the viewState is fixed and canvas internal size has changed.

If we apply a scale factor to the deck/mapbox canvas as a CSS transform we can fit a canvas of any size into a container of any size. Deck and mapbox were designed to be explicitly sized, so standard methods can be used to get actual framebuffer matching our desired resolution. However, window.devicePixelRatio = 1 is necessary to ensure retina (or other HiDPI) displays do not effect the framebuffer size.

In this example we set window.devicePixelRatio = 1, a random container size, the same view state. We switch between 1080p or 4K resolution. See the framebuffer size in the images as "Canvas Internal Size".

1080p

4K

Current Conclusion

It is very common to resize a video and expect the same boundary given a viewState, so this method is not viable unless there is a way to set the viewState and the bounds of the viewport. Currently we do not have a get/setBounds function for our viewports which works at any perspective.

Staticmap not included in export, but ok in preview.

Hi,
While trying the "trips" example, everything is working fine, data layers, trips are animated and the underlaying static map is displayed.
When i run a "Preview" render it's ok too.
But when i export to gif or any other format, only the layers are displayed, but not the staticmap in the background.
How can i get the map to be rendered too?
Thanks a lot for your help

[Bug] An extra, stale frame captured at start of render

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to camera example
  2. Zoom out a lot
  3. Change render to JPEG
  4. Click render
  5. Once finished, open .tar, see the 000000.jpeg is the improper zoom level and there is one more image than expected.

Expected behavior
000000.jpeg should look like the programmed frame value, not the user-controlled viewState.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser Chrome

Additional context
Bug is likely caused by an extra adapter.onAfterRender call occurring before the map is redrawn to the correct keyframe values. We'll need a better way of understanding when it's time to capture the frame.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.