Janus, The Two-Faced God

Stas Lisetsky  —  5 months, 1 week ago [Edited 2 minutes later]
Ok. First of all, there is more than one way to pronounce Janus, and I want you to specifically choose the latin version [ˈjaː.nus] when reading this post. This is how it's intented.
Just fyi.

When dealing with 2 different concepts, that are essentially just 2 ways of looking at the same thing - the image of the two-faced god Janus pops into my mind.
At my old job I wrote a thing that was visually comparing 2 sets of georgaphical data, and of course I called it Janus. It's just so nice to have an actual name, instead of 'whatever admin tool for whatever analysis'.
What I'm trying to say is I always try to find the metaphorical way of thinking about the stuff I do. It's just fun.

Anyways. Today I want to talk about 2 things, that are sort of the same thing. Or another instance of the Janus problem.

The core idea of Cascade is that it's going to be used for websites. So it's essentially an html editor. And we want people to view how their layouts work. In other words, we are making our own browser as well.
But. We cant be just using html/css engine for everything. I've seen a couple of chromium-based UI editors and you can literally feel that you're in the browser, and not in a 2d editor. Even if the web layout is super constrained by all the css rules - just being able do freely drag stuff around, or draw, without caring about the html nature of things - is super valuable. The way our designer describes it - you need the freedom of creativity.

So we decided that the objects that you edit and manipulate - have to be a representation of the html code, that is completely decoupled from the actual html/css data.

As always, I chose the intuitive approach and in the beginning the concepts of html code and objecs on the screen were completely separate.
So to edit html code you must first perform a translation of css rules to our engine rules. And they are somewhat similar.

We too have units (px, em, percent), but they work slighlty different. And we have the concept of absolute, relative positioning and 'the flow'. But eg. relative positioning - actually means 'relative', and you can set what it's relative to (defaults to parent, but any object is possible. As well as any part of an object - corners, side midpoints, center). And so on. I even sense that we're going to have to use 'stylesheets' but again, in a different way then css uses them.

And this all sounds fine, but as times goes by - the 2 representations become more and more intertwined.

For example, initially all the interaction was happening only inside our engine. And then, when needed, the changes were translated back to css.
But it caused all kinds of problems - beacuse sometimes you need to edit just the css. Like here, in the styles window - the actual css properties:



And supporting 2 ways of interaction was just too much. Sometimes it was our engine to css, sometimes vice versa. That meant we can't have a function that just copies properties each frame. The position could be always taken from the object tree, yes, but some properties have to be loaded from html tree to the object tree. And you had to figure out what operation has most priority, what overwrites what etc. A complete mess.

Thus, whe had to choose one and only way to edit things. And html won. It had to. It's an html editor after all.
Now we change the css properties at the time of interaction with objects. And later, in the main engine function, after we have the final css for the object (after all the class cascades have been calculated as well), only then we translate things into our internal representation. And send that to the renderer.

And so far this has worked really well. We still have to support 'the old way' of doing things for the actual Cascade UI. But this is not that big of a deal - it doesnt interfere with anything and just lives sepate from all the css business.

Chnages like that happen very slowly, and I'm really interested how this will look when we're close to release.

Right now the biggest problem with that approach is supporting css's cascading rules. Each time you make a change the html tree hierarchy - place one tag into another, for example, - I re-caclulate all the tag styles from 0, because oly God knows what class/style combination change happened with the hierarchy change. (This is probably dumb!) On top of that, the object tree has to be re-generated as well! And all that takes like 200ms, for not that big of a tree.

Flicker visible when I drag the tag 3rd time:



So that's that. I think that post concludes the 'old stuff' series. It's all been about what happened 6 months or more ago. Now I'm going to focus on current stuff. Right now I'm finishing some bugs to make a preview video. Next I have the curve drawing, font system update, HTML importer and many, many other things to choose from... So it's foing to be lots of fun.

Bye-bye!

Log in to comment