Git Product home page Git Product logo

webgl-app-playground's Introduction

This is a WebGL App Learning Playground

Using Antipasto by Luruke, I'm going to try to replicate the engineering techniques in this case study: Epic Agency We Cargo Case Study

Boilerplate for three.js, using some juicy stuff:

๐Ÿƒโ€โ™€๏ธ To Run

npm install
npm run dev

๐Ÿ“ Notes

12/25/2019

Transitions and Async

The pipeline

Wrapping the app together

12/18/2019

TextureLoader

Unlike a THREE.TextureLoader, I attempted to make textures.js, a wrapper on top of THREE.TextureLoader. I use this wrapper to connect THREE.TextureLoader and assets.js. Idea is to integrate the TextureLoader more integrated into the pipelines.

12/17/2019

Images

THREE.TextureLoader

This will give us a sampler2D in the fragment shader.

Preload

Preload is arguably one of the most important parts of getting a WebGL app done right. If the stuff isn't loaded and you attempt to work with that uncreated stuff, you get infested with bugs you don't even know where. It's likely because something didn't load on time or it's just not ready yet. For now, there are 2 very important things that must be loaded before doing anything. That's scroll for virtual scroll and positioning, and Resources for loading images, videos, and other things that should be downloaded beforehand.

For virtual scroll, it's loaded on window.load, and for resources, it's loaded in assets.js with resource-loader.

During load, it's a good idea to have a load screen. This is handled on the onProgress event "hook" in assets.js.

Virtual Scroll...

There were so many issues that came when bringing in virtual scroll. The main benefit of virtual scroll (despite the accessiblity and usability risks) is that it synchronizes MUCH better with WebGL. It also allows certain effects like parallax, navigation, and any eased scroll effects to be easy peasy. I opted to not go for my own implementation because there are so many layers of complexity to virtual scroll (getBoundingClientRect(), maintaining transforms for all DOM elements, parallax, etc.). Locomotive Scroll does all of this and more.

Also, for the positional sychronization issues, scroll.update() must be called before passing the relevant scrollX and scrollY values to the scene and viewport.

Common Patterns

deferred() promises

This is theoretically an Anti-Pattern for some, but for its implementation in this project, deferred creates a new promise. This promise works like a normal promise, but you can access the resolve() and reject() methods to use later.

12/16/2019

More on the libraries

Both bidello and kapla have components and are laid out very similarly. These 2 libraries serve 2 completely different functions. For this project, we use a kapla component to manage the actual DOM element and a bidello component to manage the global events associated with that component.

Kapla components manage DOM elements by having a lifecycle and registering components labeled with data-component="componentName". In this project, we use Kapla to "querySelectAll()" components with data-component="trackable". Then we "register" the component. The registration is really making a "WebGL Component" and associating meta-data with it.

In dom.js, when we register a component, we register a DOM component and its WebGL counterpart. Based on the component type, different WebGL Components will draw. These WebGL components are Dom3D objects and bidello components. Bidello components are components that tap into the bidello event system. Bidello events can be localized or "triggered" (example: scroll) to update interactions across the site.

WebGL Components

WebGL components are DOM elements converted to WebGL. Common things to do with WebGL components are assigning it states, events, and materials. dom3D.js contains the skeleton for what a WebGL component should be. WebGL components get dimensions and relevent info from its DOM counterparts, and are added into the WebGL scene through calculations from the DOM. For WebGL components, 2 vital things must happen: resize and scroll events. Resize determines the shape and size of the WebGL component, even when the page dimensions changes. Scroll events let the webGL component sync its position on the page. Because many WebGL components extend from dom3D, we're able to create reusable and customizable webGL components. Each webGL component has an event system that can be extended and possibly its own materials and shaders. Because of all these properties, adding WebGL components are very easy and done without any harm to the DOM elements.

Interesting Details on This Architecture

How is the WebGL managed?

The trackable Kapla component registers anything that should be a WebGL component. The dom.js creates a WebGL component through three.js and bidello to manage events inside this new component. The new component extends from a base dom3D object inside dom3D.js. The new extended component can implement its own materials and events to customize the individual interactions.

dom.js is like a "controller" or "instance manager". dom.js is a controller that creates and destroys any WebGL component on the site. All the instance references are stored in dom.js which makes them easy and accessible to manipulate.

The best part of this architecture

Everything is a progressive enhancement happening mostly on the Javascript end of things. All of this complexity builds on top of the existing DOM. Because everything is built like a progressive enhancement, the size is super customizable and adaptive to change.

Common Patterns

export default new Object()

This gives us something like a Singleton. Sometimes, we need things to share, but only one thing should exist. The thing we want to exist shouldn't be imported and instanced. We need to access and update information directly. This is the way to do that with ES6 exports.

elements["property"]()

In a JSON, you can access things like a map by using the elements["property"] notation. This is way more readable and flexible than numbers.

The gl CSS classname

By appending classes whenever certain objects are ready, you're able to sync design changes like hiding visibility more natively; more natively as in not relying on JavaScript to manage all the complexity.

12/14/2019

Explaining the libraries...

WebGL apps need an event management system separated, cleaner, and encapsulated from the default DOM Event Handling system. Bidello helps manage this confusion.

WebGL apps need transpilation, loading, and code optimizations. WebPack has a lot of config so we're using parcel-bundler as our bundler. Parcel is zero-config.

Sometimes, it would be great if we could interactively manage the uniforms and attributes inside our shader. It'd be great to see more data and get an interactive view to debug shaders. Magicshader comes in for this.

For WebGL apps, the preload phase is extremely important. You need to load everything beforehand to load the textures properly throughout the entire app. resource-loader does this.

To help manage the interaction between DOM and JS without something heavy like jQuery, we're using kapla. We're mainly using Kapla for this WEbGL app because of its MutationObserver implementation.

MutationObserver

MutationObserver watches if anything changes in the DOM tree. It'll call a specified callback when a DOM change happens.

webgl-app-playground's People

Contributors

ryuuart avatar luruke avatar

Stargazers

Mohnish Landge avatar Oliver Belmont avatar Pigloo avatar

Watchers

James Cloos avatar Pigloo avatar  avatar

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.