Jump to content

Borders For More Primitives


Recommended Posts

Hi guys.  Pinging @Nockawa for this one.  I've been working him hard, lately, and I want to thank him for all the recent help.

Today I am thinking about borders.  Well, I HAVE been thinking about borders for quite some time, but those borders were international borders.  Now, about Canvas2D primitives borders.

Currently, I think there are only a few ways to make a Canvas2D based border.  1. Rectangle2D  2. Shape2D  3. Sprite2D.  Each CAN be used to place a border around a Text2D, or just about anything else.  But none of these bordering methods... automatically size-to-fit their contents, right?

Perhaps that is reserved for a layer above the currently-completed "base" of Canvas2D.

At what point do we "assemble" the FitBorderedText2D and FitBorderedGroup2D?  In fact, for maximum-easy bordered tracked-node labeling, I could use a FitBorderedTrackingText2d.

It seems strange and clumsy to need Group2D for node tracking, Rectangle2D for text border, and then Text2D... just for a single label.

Anyway, I saw mention-of allowing trackNode for WorldSpaceCanvas itself (future feature).  That is allowing trackNode on a "higher level" than Group2D.  (WSC2D is higher level than a Group2D child of it.)

What are the chances of allowing trackNode on LOWER level things... such as Text2D or Rectangle2D?

What are the chances of allowing border on Text2D and Group2D?

You see, a FitBorderedTrackingText2d... would have a border and trackNode... without needing any help from Rectangle2D or Groupd2D.  Potential lines-of-code savings across 10 years of Canvas2D usage - 2 million metric tonnes.  :)

Am I de-primitiving the primitives?  :)  (i.e. FitBorderedTrackingText2d is a "combo" of primitives, and therefore would be offered on the next layer -  the GUI Lib currently under dev?)  Perhaps part of a Canvas2D Tools thing... programmer assistance?  Of course, programmers can do this "combining" themselves in a little makeLabel() function.  But still, I'm curious if Noxxy has any plans for "SuperText2D" features like this. 

Thoughts, anyone?  Thx.

Link to comment
Share on other sites

Ok, let's address, one topic/one issue...

Concerning this topic: Borders.

Today Border is a concept which is part of the Shape2D abstract class, along with the Fill one. They are both accepting IBrush2D based instances. Shaped2D based classes are Rectangle2D, Ellipse2D and Lines2D.

In theory, you can declare a Rec2D with only a border, no fill, with no size and with a child being a Text2D, the Rect2D should take the size from its content. I say should because in the current implem there's a bug about that, but if I remember it's more for the Group2D. Auto sizing/fitting is a very complex (well, for me) thing to implement, specially when some Prim can either constraint the size of their children or fit to the size of their children, it's not easy to do.

I will fix this bug once i've finished the three features I was talking about in the Canvas2D main post.

Link to comment
Share on other sites

Hey, thx.  I guess I'm hoping for... someday... having a simple one-liner that creates a bordered Text2D with node tracking.  One call, 4-5 params, options object-ready, Lots of assumed defaults (fontfam, fontsize, border styles, etc).  Perhaps one of the constructor params is clickable?  If set true, this super label automatically has a click observer that tries to call a function of the same name as the super-label button.  :)  (okay, that's probably too much user-friendly)

(Hey folks, I wanted it to be a one-liner. I never said how ridiculously overloaded with parameters it could be.)  :D

But even if its constructor didn't offer an options/parameter object, and maybe just 6 parameters... that would be fine.  A node-tracking bordered button in one line.  That... would rock.  Think we could talk DK into allowing...  IF !screenSpaceCanvas2D, make a full canvas one FOR the user?

So, you can call this one-liner button-label maker thing... and it creates a SSC2D if one doesn't yet exist.  COOL.  Ridiculous?  Yeah, probably.  Thx agn, be well, no hurry on any of these things.  Curious.  :)

Link to comment
Share on other sites

What you're asking is, from my point of view, a possible class/feature of a GUI Library. Canvas2D is about low level stuffs, I know it takes time to code all these low level stuffs, because well, it's almost all by myself, and I want things to be flexible and yet with good performances, but next would come a GUI Library that will address needs on a much higher user level.

On another hand, I try to make Canvas2D good for Game type UI, WebApp type UI and also some features more purely 2D Engine based. So C2D is broad, yes. But truth is it's broad because of all the requirements/needs the people are expressing/asking for.

Link to comment
Share on other sites

Is this something like that you would like? http://babylonjs-playground.com/#2AVSFH#146

The Rect2D's size adapt to the text's one, there's padding for give "more room" to the text, the rect only has a red border. I've noticed the roundRadius would mess things up and this is something I was working on (the autosize in its broader sense) before I got sick.

Link to comment
Share on other sites

Okay, that's TECHNICALLY a one-liner.  :)

But... nooo...  I'm hoping for...

var label = BABYLON.Canvas2D.FastLabel(name, size, text, justify, bordered, clickable, trackNode/origin, scene);

That's all that's needed.

if (!scene.hasFullScreenSpaceCanvas) -> it makes one.... behind the scenes... no fill, no round corners, full canvas sized.

name - String
size (a single float/int). Possibly applied like  fontName: size * 5 + "pt Arial".  It's simply a general size.  Nockawa gets to determine what this simple value is applied-to.
text has to be there, of course.
justify - String - essentially use this to set marginAlignment h: left... which is probably useless, considering that border "length" is automatic anyway (sized to fit).  So maybe remove this param.
border - Boolean - install the auto-border or not? (use a rectangle2d on this label, or not?)
clickable - Boolean - Put a click observer on this label?  If so, it automatically targets a function named name() or perhaps onNameClick().
trackNode/Origin - ANY - IF value is a node, set that mesh as the trackNode.  If a Vector2, place label at this position on-screen (on ssc2d).
scene - standard stuff.

This function would be provided by Canvas2D system... IF user has Canvas2D included/installed.  Big trouble if not installed.  :o

Notice that it returns the label object (whatever the heck THAT is).  User/Programmer must query its .canvas property to get a ref to the SSC2D that it was childed-to.

These labels would have no fill/background by default, I suppose.  It can be added late... by reffing/setting label.backgroundFill or similar.  IF the label had a Rectangle2D-provided border, then THAT would be used as the filled background.  If no Rectangle2D because border = false, it would use the Text2D background fill.

And don't forget the trackNode.  If it will ALWAYS require the use of Group2D, then... hmm... label.group could be available, too, to get a ref to that... and make pokes to it.

A power wrapper.  ONE liner... as in... seriously a one-liner.  80 chars.  Can it be done?  Wise?  Best done on a separate Canvas2D.ToolsAndToys class?  I hope I'm being clear.  Thoughts?  (thx)

Link to comment
Share on other sites

I've already told you: the one line thing you're wishing for will be delivered in the GUI Lib, not in the C2D one.

In the GUI Lib, the user doesn't even know about a Canvas, it's all taken care of underneath. You have to wait, it will  come, but it's about patience, I try to do things with the appropriate priority...But it's my own point of view, I understand other have different ones.

Link to comment
Share on other sites


Want to comment on another one?  No requirements, and sorry if you've already addressed this.  I'm a bit forgetful.


Besides the hell of trying to get scene.clearColor to act in any way sane... I am also having issues with the rect2d pointer-overs and pointer-exits. 

I'm still trying to get a working pointer-change (canvasZone.style.cursor)... when pointerOver a click-active prim.

You said MasterK had his over/exit stuff working, but I don't know which playground you saw that in.  This one?  Know?  I can't get much of anything working on his PG, there.

Back to my #6 demo... watch console and ease the pointer onto the rect.  As you cross the red border, you'll get a quick OVER and then an immediate EXIT.  Keep moving inward toward the text2d, and it will happen again - an over, followed by an immediate exit. 

My canvasZone.style.cursor adjustment IS working, but it leaves OVER state SO FAST... that we never see the change.

Remark-out line 34, and you can see the cursor change to pointer, and get stuck that way (expected).  :)

I am also getting an exit... after the click.  Not sure if that is optimal.  Also seeing a "stream" of exits... when mousing-over text2d... left/right/left/right, etc.

I'm just a FOUNTAIN of positive good news, huh?   Sorry.

Any thoughts?  I bet you already taught me/told us about this issue, and I forgot.  Sorry if I did.  I promise I'll leave you alone soon.  Really.  :)

Here's another version.  It uses 'enter' and 'out' observers, instead of 'over' and 'exit'.  It acts like the MasterK demo. (expected, because his demo uses enter and out, too)


Link to comment
Share on other sites

*nod*.  Thx Adam! 

Yeah, "over" and "out".  Works pretty well.  Both "bubble" (according to docs).  Cool.

No such thing as 'pointerExit'.  (I'm not too bright.) 

There's pointerEnter and pointerLeave, both non-bubblers, but they don't work so well.  Perhaps normal.

Wingnut learning... slowly.  Thx agn, Adam.  Your version is the best working version so far, by far.

Link to comment
Share on other sites

Thx Nox!  Your health is first priority, though, you know.  As far as I'm concerned, no hurry at all.  I have plenty of other things to do, and if you're not 100%... don't worry about it.  YOU are more important than pointerOvers and pointerOuts.  Hope you're feeling okay.

Link to comment
Share on other sites

Watching the colors, it almost seems like the text2d has observers, too, even though none were set.  Possibly auto-inherited from the rect2d?

I can understand if the event "cascades" down to the text2d, but no observers on text2d.  Not sure why we get color change when entering the text2d.

But if the event DOES cascade down to text2d and then text2d bubbles it back up to rect2d container... then... maybe THAT is causing the apparent "color change at text2d edge". 

Err, wait.  That's not right.  No event should be genned from rect2d... when pointer crosses text2d edge.  hmm.  *scratch scratch*

(Wingy offers himself and Nockawa a cool compress and a shot of Wild Turkey)  :) 

Have you done a little TV producing, N-Man?  Is that you?  (no answer required, of course).

Link to comment
Share on other sites

Ahh, there you are.  Hi Loic!  Thanks for all your hard work, and for teaching me stuff along the way.  I appreciate that.

Ya know... that c2d.createCanvasProfileInfoCanvas(); ... that's a pretty nice "force-assembled" panel.  It's cooool.

c2d.fastLabel(name, size, text, bordered, clickable, trackNode/origin, scene); ...would sit nicely, right next to it.  ;)  createCanvasProfileInfoCanvas() needs a friend, right?  (ahem)

I know, I know, I'm pestering you.  But, one section of my new "Labels Tutorial"... would go from "big fat code example"... to one line code example... IF I had that fastLabel thing.

My hope for the labeling tutorial... is make simple labels... fast and easy, of course.  (I might even try wordwrapping in dynamicTextures)

Any chance?  I suppose fastLabel() might become a "bootleg" way of doing it, and later, folks would be reluctant to change.  They could get addicted to fastLabel, instead of learning the "proper way" of doing it... with the gui lib.  I can understand that.  *shrug*  Any thoughts?  Am I being annoying?  Hope not.

But yeah, you're right.  I see the pointer leave rect2d and enter text2d... while slowly moving inward (from bottom).  Upper half of rect and text... seem to be pointer-numb... as if a bounding area was only half-height.  *shrug* 

No hurry.  Well, I have an itchy hinder to finish Labeling Tutorial, but that can pull into a rest area, too... no problems.  "Making it clickable" is a little sub-section of each type of labeling.  Mouse events ARE pertinent to the Labels Tutorial... because of that planned sub-section.  The Labeling Tutorial is a bit off-topic, here.  We could go back over to Tutorial Talk for that crap, I suppose.

In this thread, I was essentially hoping for a combination group2d (for tracking), rect2d (for border), and text2d (for label text), all in a single prim2d (with almost all settings... auto-defined).  (To cut down the amount of code it takes to make an ssc2d clickable bordered label).  :)

Link to comment
Share on other sites

I'm still working on it, the event bug was solved, but... the events are not triggered properly because of the auto-size bug I mentioned before.

So I'm trying to make auto sizing working, at least for this case and I'll release the code as soon as it's done.I still can't work a lot though, patience...

But I'm on it! :)

Link to comment
Share on other sites


That dynamicTexture wordwrapping demo I mentioned/showed in my last post... really doesn't work very well.  context2d.measureText() is not perfect, I read.  I guess it is very important to set the font on the context FIRST, and then call measureText(), or else it calculates lengths based on default fonts.  And I think YOU mentioned that measuring text length was not easy for Canvas2d things, too.

Yesterday, thiendv asked about background images/textures for labels/buttons, and I didn't know if Sprite2d was allowed to have rect2d and text2d children.  Later in the day, I tried it, to make a background-textured label.  Worked great.  In my studies, I noticed you had .isContainer property, and wondered about its purpose.

All this made me think about word-wrapping text2d prims... or possibly using a word-wrapping container which dynamically creates more/less text2d children... depending upon how it wraps. 

If this container was scaled in size, it could add/subtract text2d prims as its children... in order to display the entire "paragraph".  I don't know if your .isContainer would ever be used for that stuff... but... I was thinkin'.  :)

Or, maybe power-up the Text2D itself, allowing IT to have multi-lines and do its own wrapping?  Nah, that probably wouldn't be a good idea.  That would be similar to textNodes inside of HTML divs/spans/buttons.  Text2D would need to have sub-text objects, and to do wrapping, it would need to adjust its own sub-text children.  (It would be a mini container, itself.  A container of sub-text objects.)  Weird.

Word wrapping is such a pain, but for a Canvas2d word-wrapping "smart container", it would be a double-strength pain, I would suspect.  But I think users will want it.  Have you (or anyone else) heard-of a user request...  to use a single Text2d... to display an entire paragraph, yet?  I haven't heard one... but it's coming, I'm sure.  :)  Be well.

Link to comment
Share on other sites

@Wingnut the code is done, pushed, and I hope bug free. I'll ask DK to update the PG asap.

Measuring the text is accurate in width, and a bit...hazardous for the height.

All primitives can have children, Sprite2D too. And now with Scale9Sprite and auto size you should be able to design some kind of label with a border as a sprite and a content with any size.

Documentation of isContainer:
isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
MasterK needed both behavior for his game.

Text2D already support line feed/carriage return (\n and \r, which are commonly used are \r\n) but it's planned to add word wrapping, this is not a difficult feature, but well..needs time...

Anyway, only one Text2D prim would be enough to achieve what you're talking about. For now it's not a "rich" Text, but I want to go in this direction, I don't know yet which syntax should be used.. Markdown, BBCode, custom made?


Link to comment
Share on other sites

Thanks N! 

Ok, .isContainer is events-related, and not anything related to scaling children to fit, or wrapping, etc.  Roger that. I should have read docs about it.

Good news about S9S, too.  Sounds fun!

One text2d even if the text wraps tons of times?  Nice.  Re-wrap on resize/re-scale?  I hope so.  :)  That's gonna rock!

Scrollbars on overflow?  Or... stretch height to hold all text?  Or...  heh.  I've been down this curiosity trail before, haven't I?  :) 

I have some kind of obsession/fascination with containers, I think.  :D  thx agn for the work/info, N-man.

Link to comment
Share on other sites

Scrollbar is a whole different things, a way to understand how GUI is working would be like this: the Tex2D prim's size would be whatever is needed to fit its content, so if there's a lot of text, the size is big. Now if there's a constraint on the Text2D's parent which make it smaller than the Text2D's size, for instance a Rect2D with a fixed size of 400x200 containing a Text2D of an autosize of 400x300, then a ScrollBar is to be displayed in order for the user to be able to view the whole Text2D's content.

One way to achieve this would be to dev this feature I've recently announced here:

  1. I will try (but I should succeed) to develop a feature to clip the content of a Group2D, apparently it won't be harder to use a Shape as the Clipping geometry (if no shape then the whole rectangle surface will be used) to get more fancy stuff. But @MasterK and other, you will finally be able to develop scroll-view without relying on hacking! I was reluctant to develop this feature not because of its complexity (it's not a walk in the park anyway), but because if it's overused the performances may drop. But well, it has to be done and maybe the perf won't be that bad. For those who are familiar with the Canvas2D Architecture a Group2D that will Clip its content will be turned into a Renderable Group2D and basically I will draw the clipping geometry to the stencil buffer, then I'll draw the Group2D's content with a stencil check to clip away the pixels that are out of the geometry. So in theory: not hard to code...But there are so many cases, rendering types, that well...Future will tell!

This way the drawing of the Text2D would always be clipped by the Rect2D in our specific case. This is one of the two ways I can think of to achieve Scrollbar. But be aware that scrollbar is definitely a GUI feature.

Link to comment
Share on other sites

Excellent!  New test playground:  http://babylonjs-playground.com/#UAG5H#11

Zones look good, well done!

Test buttons: 
   -  Over/out on the left button/label (canvas.children[0])
   -  Enter/leave on the right (canvas.children[1]) .

Watch console and color changes while passing mouse across buttons (for new followers to this test).  :)

A few questions if I may:

#1:  Over/out events... happen on the Text2D prims (left button only?), even though no observers are assigned on Text2 prims.  Normal/expected?

#2: The .isContainer settings (lines 76/77) have no effect-upon the Text2d being event-active.  Normal/expected?

23 hours ago, Nockawa said:

Documentation of isContainer:
isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.

I'm having a difficult time understanding that.  :)  Sorry.

#3:  Should .isContainer affect the automatic or inherited over/out/enter/leave events on Text2d prims in this example?

#3b:  Should I NOT BE concerned about .isContainer now, because it does not apply to anything in this demo?

I've changed this post 5 times now.  I was having some problems making the SAVE option work correctly in PG, when trying to save #11.  Sorry for temporary bad link.  I wonder if lines 63 and 70 are suppose to be mouseEnter and mouseLeave, not pointerEnter and pointerLeave.  hmm.  Off to the primitivePointerInfo doc to learn.  :)  (It's pointer, not mouse.  All is cool.)  There's SO MANY event names to remember... in my life.  :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...