43
Views
12
Comments
Canvas element timing issues
Application Type
Reactive

Dear community,

I've been working on a block that uses a canvas element to be able to connect items left and right (to be used in a quiz application). Think of something like this: 

The good news is that I have been able to built something like that, but I am having some timing issues that I find hard to explain. The easiest way to explain it is via the attached OML. In that application I have 1 page and 2 blocks. 1 block is the one containing the canvas element, and all logic to draw the lines ( please note that the red background is just to make sure it is there ). The second block act as a sort of wrapper for that drawing block, and in this application only acts to delay the feeding of the input parameters of the drawing block. Please note, this seems like a odd thing to do, but in the actual application that I would like to use this in a similar wrapper block is used but instead of a forced delay the delay is caused because of the fetching of data. That last wrapper block is used on the single page. 

Here comes the magic. Open the page, and set the delay (input parameter for the page) to 500. The canvas will be drawn with 8 small circles ( 4 left, and 4 right ). Now set the delay to 1500 (or 2000), and observe how the circles do not appear until you click on the canvas. This is not a necessary step when using a smaller delay, and it seems to tie in with the fact that the canvas block itself also has a delay built into it ( this is required because otherwise it is possible that the rendering is stull busy whilst we try to draw on it ) .... but it doesn't make any sense to me. I've added a bunch of console logs in the various javascript statements, butI haven't been able to understand why it is showing this behaviour.

In short, I do not understand why the circles do not appear until clicked in some scenario's. Anybody here any idea as to what is going on?

kind regards,

Vincent

CanvasBug.oml
2021-03-18 21-03-15
Benjith Sam
 
MVP

Hi Vincent,

I tried to access the shared OML file using Service Studio, but I received a failure message as mentioned below:

I'm completely unsure about the cause of this issue. Note that I'm using the most recent Service Studio version.

Would it be possible for you to create a separate canvas implementation in a sample OML file and provide it here - that doesn't rely on any dependencies from your project modules? 


Kind regards,

Benjith Sam

2021-09-06 15-09-53
Dorine Boudry
 
MVP

Hi @Vincent Klijs ,

this sounds like the kind of puzzle i'd like to solve, but i can't open your module.

My personal environment is on automatic update, so I don't think there's any 'later' version i could be upgrading to.

Dorine

2020-09-01 10-42-42
Stefano Valente

Could this be ODC?

2021-09-06 15-09-53
Dorine Boudry
 
MVP

Yeah, makes sense, there is an ODC tag.

It's the application type reactive that confused me.

UserImage.jpg
Vincent Klijs

My apologies for the reactive tag, I forgot to remove it and I do not seem to be able to remove it now. But as mentioned, the app is indeed an ODC app. Do I still need to recreate it from scratch then? 

2021-09-06 15-09-53
Dorine Boudry
 
MVP

a thing that just came to mind, is the drawing dependent on data coming into the block, if so, do you have an OnParametersChanged to redo the drawing ?

UserImage.jpg
Vincent Klijs

The drawing of the dots that can be connected depends on incoming data. So, yes there is an OnParametersChanged, but before I have been experimenting with making the canvas size part of the input parameters and I was able to handle that just fine. Also, the canvas is getting redrawn all the time as a result of the mouse events (which works just fine after that 1 click). 

UserImage.jpg
Vincent Klijs

I've recreated the application in OS11 as an reactive app, not only ensuring the tags are correct, but also making the puzzle accessible to a large group ;). Please note that I'm getting the exact same behaviour. 

CanvasBugReactive.oml
2020-09-01 10-42-42
Stefano Valente

I will try to look at it this evening, if Dorine hasnt fixed the problem before that :)


With Javascript in Web blocks, combined with input params there is a possibility of trying to load the javascript before the DOM was loaded. I used to fix this with setting the input params in the OnRender of the screen instead of the OnInitialize. Be sure to have a variable set so you will only set it one time (as OnRender gets fired quite a lot of times).


You could check in the browser if the first time loading your screen, you get javascript errors telling you the dom was not ready.

2021-09-06 15-09-53
Dorine Boudry
 
MVP

Some progress :

If you change the canvas shape (width or height property) it looses all drawing on it.

If you delay in your enclosing webblock, and then later change the width and height, and the dots were already drawn, they get removed.

2021-09-06 15-09-53
Dorine Boudry
 
MVP

So : 

  • you are delaying the DrawConnectTest block from setting the height and width a variable amount of milliseconds, passed in as a parameter from the page
  • you regulate this by only setting the height and with after that waiting time


  • you are also delaying the DrawConnect block from drawing the dots, a fixed amount of 1000 milliseconds
  • you regulate this by setting the IsReady variable after 1000 milliseconds

So what happens, is if the variable test delay is larger than the 1000 milliseconds, the Ready is set to true before the height and width, and when height and width get set, your OnParametersChanged draws the dots.  

My guess is, the effect of the changed height and width only gets applied in the next render after the OnParametersChanged action finishes, so after the dots are drawn, erasing them again. 


A quick fix is to postpone drawing the dots until after that render, you can use the outsystems javascript api for that.  See blue option on attached oml

A simpler option is to just enclose the block in a container, and make it visible after all data is available and it is ready to get drawn.  This might not work though if during the lifetime of the canvas, the data can change.  See green option on attached oml.  Not sure also why you added a delay in the canvas block itself, is it the intention that this will also retrieve some data ?  In that case, this is also problematic, as it will only start retrieving after parent data is retrieved.

But if all data is fetched on the parent wrapper block, you can just simply use the IsDataFetched (or some other boolean if you still want to do extra calculations after the fetch) as the visible property of the enclosing container.  But in that case, I don't understand what your delay on the actual canvas block (1000) is supposed to simulate ???

Did you have rendering problems in the OnParametersChanged or the OnReady ???

Dorine

CanvasBugReactiveChanged.oml
2021-09-06 15-09-53
Dorine Boudry
 
MVP

added cyan option to show what i would probably do, with no delay inside the inner block


CanvasBugReactiveChanged.oml
Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.