consider the following code:
window.stage = bonsai.run(document.getElementById('stage'), {
code: function() {
var circle;
circle = new Circle(200, 200, 50);
circle.stroke('green', 2);
circle.addTo(stage);
circle.on('click', function(ev) {
stage.sendMessage('click', ev);
});
},
width: 500,
height: 500
});
stage.on('load', function() {
console.log('loaded');
stage.on('message:click', function(ev) {
console.log('click', ev);
});
});
So, clicking on the circle gives me the error: DATA_CLONE_ERR: DOM Exception 25
If I just send out properties like ev.x and ev.y, they pass out just fine. I can also reconstruct the object from its properties before sending and it passes fine.
How can I send the event object out intact to the parent context without deconstructing-> reconstructing it? And by the way, why does bonsai work this way?
Great that you've asked why we do the separation that way. Just went through the BonsaiJS documentation and realized that we don't explicitely say a word about why we separate the rendering from the execution thread.
BonsaiJS code is mostly executed in a worker (falls back to iframe, if workers aren't available) and uses
postMessage
to communicate with the context which created the worker. TheDATA_CLONE_ERR: DOM Exception 25
is raised because the DOM event object can't be serialized bypostMessage
. To solve your problem, you could create a simple function, which removes all nested objects / functions of the object, which should be passed:Or you can force BonsaiJS to be executed in an iFrame. Then you'll have access to the DOM and you can serialize any object (note: see below, why I wouldn't recommend that):
The main reason for putting the main code execution into a worker, is, that we don't want any computation to block the rendering "thread", so that we get more fluent animations (if the code is executed in an iFrame, rendering + code execution will happen in the same thread and it won't be as fluent as with the worker). Another advantage of executing JS code in a worker, is, that we don't rely on the DOM and can also take the same JS code and execute it in a different JS environment like Rhino or NodeJS (here is some example code, how you could execute BonsaiJS on node and send the rendering messages to the browser through SocketIO: https://github.com/uxebu/bonsai-server).