The following are just small web apps developed as a way of porting, testing and optimising some of my C#/Java analysis and visualisation libraries into JavaScript. These first few deal mainly with solar position and shading, but do get into some real-time geometry and mesh manipulation. With some I have been able to flesh them out into independent educational apps, however some are marked only as experiments. As I get time I’ll try to keep polishing up some of the rest, but I got a bit lazier as I progressed and started moving stuff into core a bit earlier, so turning some of my later experiments into independent apps that make sense takes a bit more time and effort.


Educational Apps

Launch web-app...
Earth/Sun Relationship
Launch web-app...
Supershapes Generator
Launch web-app...
Interactive 3D Sun-Path
Launch web-app...
Interactive 2D Sun-Path

Simple Experiments

Launch web-app...
Dynamic Soft Shadows
Launch web-app...
Polygon Tessellation
Launch web-app...
2D Sun-Path on a Map

Background

If you have followed this blog or looked back over previous posts, you will see that I have struggled with cross-platform app development for quite some time now. I started out using Java and Processing, and then moved to C# and Xamarin Studio, with a bit of Swift thrown in there for good measure. With these new web apps you can see that I have switched again - this time to JavaScript and WebGL.

There are three main reasons for this:

  1. First, trying to coordinate applications across multiple platforms and devices is extremely time-consuming. Generating and managing the shared and platform-specific code for an app is relatively straightforward, however it is the management of all the different installers, digital certificates and signings that seems to take an unreasonable amount of time. A simple iterative update - which I seem to do a lot - involves rebuilding, re-signing and zipping a Windows setup.exe file, regenerating an OSX package file, rebuilding and gzipping both 32-bit and 64-bit Linux installers, then rebuilding and re-signing an Android APK file. Not to even mention iOS, where you can only develop on specific registered devices and have to physically lend your own hardware to anyone you might want to review or beta-test your app. Maybe someone else could turn all this into a nice simple script, but for me getting it right typically involves several different applications on multiple operating systems and lots of mindlessly repetitive steps. With a web-based application, you simply FTP the new files to the server and then get people to hit ‘Refresh’ in the browser of their choice on any device they want - pure unadulterated pleasure in comparison.

  2. Second, I have been stunned by how weII the speed of calculations in JavaScript compares with those in Java and C#. Stuff that I originally thought would be completely impractical or way too slow regularly turns out to be pretty straightforward and remarkably fast. Obviously C, C++ and Swift will always be the fastest as they compile directly to native code. However, Java and C# compile to byte-code which is then converted to platform-specific native code at run-time. JavaScript is an interpreted language that is parsed line by line in the browser’s JavaScript engine at run-time, so it should be very noticeably if not unusably slower. However, most modern JavaScript engines include an additional optimising parser that constantly profiles running code looking for ways to convert frequently used functions and classes into more efficient native code equivalents. I am very lucky here as much of what I need to do is pretty repetitive floating point calculations which, if I follow some standard performance guidelines, are usually converted to run at near native-code speeds. This means that those highly optimised functions and classes can potentially run faster in JavaScript than their Java/C# equivalents. Obviously it takes a second or so for the optimisation to actually kick in, plus there is plenty of ancillary code that doesn’t get optimised so well. However, it’s still pretty darn good and it can only get better as engines improve.

  3. Third, Safari 8 for OSX Yosemite and iOS 8.3 now both fully support WebGL by default - so no more trying to explain to people how to manually enable it. As browsers for Linux, Android and Windows have supported WebGL for some time, this represents a bit of a tipping point as now up-to-date versions of browsers for all the commonly used desktop and mobile platforms now have good, reliable support for HTML5 and WebGL.

All That Wasted Effort...

Thankfully coding work is very rarely completely wasted. I’ve been using the libraries I did in C# for some Revit plug-ins as well as with Node.JS as part of a back-end analysis server. Similarly I am using JPFF a lot for distributed back-end processing, so all my Java libraries are getting good use there. Despite that, a lot of the 3D and user interface code I wrote in Java is pretty close to wasted now. However, having done certain things like interactive selection, a 3D cursor and model manipulation code a couple of times before in different languages does seem to make doing them all again in JavaScript a little less painful (and hopefully a little more robust) than starting from scratch.

Discovery...

One really good thing that has made this process a whole lot more enjoyable is my discovery of Knockout. I first started out using React and Angular, but the learning curve and organisational structure they impose just didn’t sit right for the types of small web apps I was doing. Then I finally found Knockout and the way it did things just seemed so much more logical and intuitive to me. Obviously this is a purely personal preference, but a few days spent learning Knockout is so worth it in the long run as it makes dynamic interaction within web pages an absolute breeze.


Comments

Dr. Andrew Marsh 15 October, 2015 - 00:29

Some Browser/Platform Issues

In my testing of several different devices and browsers, I have found the following ‘idiosyncrasies’:

  • Chrome on Android has recently changed to require support for the GL_EXT_robustness extension before it will run WebGL on a device. Unfortunately even though they are perfectly WebGL capable, most Samsung Galaxy tabs/phones and some Nexus don’t support this particular extension so WebGL is automatically disabled regardless of your settings in chrome://flags (see: https://code.google.com/p/chromium/issues/detail?id=306938).

    There are three possible workarounds for this.

    1. You can simply use Firefox or the native Android browser that came with your device instead.

    2. You can install the developer version of Chrome on Android as this issue is resolved there (see: https://play.google.com/store/apps/details?id=com.chrome.dev&hl=en).

    3. You can try going to chrome://flags in the address bar and then turning on “Override software rendering list” at the top of the displayed options. This has worked for some people but not all.

  • Chrome in iOS 8 seems to implement the devicePixelRatio weirdly for Retina screens, at least it does on my iPad 3. This means that it reports a devicePixelRatio of 2 (which is right) but then seems to display the WebGL canvas at double the required size (as if assuming a devicePixelRatio of 1). The same app works fine in Safari so I’ll have to look into this to see if it’s something I am doing or if I have to specifically detect for Chrome.

  • The latest Samsung phones with hi-res screens seem to report a ridiculously low resolution to the browser when rendering a page (something like 360x640 when the screen itself is actually 1440x2560) but does show a devicePixelRatio of 3. This makes all the buttons and UI elements far too large relative to the screen, so I will have to do some experimentation with scaling on devices with that kind of configuration and post an update.

Andrew


Click here to comment on this page.