Why do it this way rather than using C3's provided dynamic texture system?
You could do that too. As with everything in engineering, there are usually different ways to do things, each of which have different trade-offs, and choosing between them involves judgement and the particulars of what you're trying to do.
The main problem with dynamic textures is likely to be that texture uploads can be slow. They might be a GPU copy, but some combinations of data/browser/OS/driver may end up doing a slow copy from CPU, which will kill performance. It's hard to know in advance how well it will work without lots of testing. Some texture upload paths are also async which can cause some tricky synchronization issues. On the other hand, it gives you true in-engine rendering.
If the goal is to render a viewport-sized image, then rendering in-engine with dynamic textures seems slightly odd in that it doesn't actually draw anything correlated with an object position. It's more like an entire layer of custom content. In that case, HTML layers seem a suitable solution. I'd say it's particularly good for 3D content, as generally you'd have a 3D world with 2D content layered on top (e.g. for a HUD) and perhaps some 2D content layered underneath too, which HTML layers solve nicely. Additionally it simplifies the integration, as a library like three.js keeps control of the canvas and renders it like anything else, just using the browser compositor to blit the canvas to the display, avoiding any extra texture upload overhead.
Perhaps it would still work fine with dynamic textures. Try making a prototype and seeing how it works out. With 3D content I'm not sure there will be much benefit to doing that, but it might be a good approach for 2D content.