What does window.__context do? - javascript

I know it’s usually better to answer these questions with a google search, but I can’t seem to find it anywhere online. I wrote a function for creating a GlowScript canvas and adding it to an inputted div. I based it off of the code given on the website with some changes. Here is the function (it won't run on here because you need to import libraries, but it does create a 3D shape and put it in the div):
make_box("my_div")
function make_box(my_div){
window.__context = {glowscript_container: document.getElementById(my_div)}
var scene = canvas();
// create some shapes:
box( {pos:vec(.25,-1.4,0), size:vec(4.8,.3,2.5), color:color.red} )
}
I think the first line is required to add the canvas to the div. Without the line, I get the error:
Uncaught TypeError: Cannot set property ‘canvas_selected’ of undefined
I don’t really understand what it’s doing, however, and what the window context means. Does anyone have any insight into the line? Thanks!

This is what I found when I searched for window and context separately via google.
Apparently window is an object and .__context is a version of this. More information can be found in the links below.
https://www.w3schools.com/js/js_window.asp
https://towardsdatascience.com/javascript-context-this-keyword-9a78a19d5786

Related

How to set canvas attributes from P5.js?

I am using P5.js (https://p5js.org/) for an application where I need multiple off-screen canvases. This is working just fine. Each canvas is created within a class as follows:
this.canvas = createGraphics(w, h);
In an attempt to experiment with performance, I decided it might be interesting to set willReadFrequently to true:
https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently
This, in response to a warning I got:
Canvas2D: Multiple readback operations using getImageData are faster
with the willReadFrequently attribute set to true.
I can read the canvas attributes just fine using:
console.log(this.canvas.drawingContext.getContextAttributes());
The result is:
alpha: true
colorSpace: "srgb"
desynchronized: false
willReadFrequently: "undefined"
However, I can't seem to come-up with a way to set this attribute. P5.js does have a setAttributes() method:
https://p5js.org/reference/#/p5/setAttributes
When I try to use it, like this, I get a setAttributes is not a function or Cannot read proproties of undefined error:
this.canvas.drawingContext.setAttributes("willReadFrequently", true);
// or
this.canvas.setAttributes("willReadFrequently", true);
// or
this.canvas.setAttributes[{"willReadFrequently": true}];
These two attempts (tried all lower case as well) result in Cannot set properties of undefined (setting 'willReadFrequently'):
this.canvas.drawingContext.setAttributes.willReadFrequently = true;
this.canvas.drawingContext.setAttributes["willReadFrequently"] = true;
This attempt did not generate any errors, yet getContextAttributes() shows that nothing changed:
this.canvas.drawingContext.willReadFrequently = true;
Finally, looking at the Canvas API documentation...
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
I thought I should be able to do something like this:
this.canvas.drawingContext({willReadFrequently:true});
Once again, the error is is not a function.
I'm pretty sure I am missing something very fundamental here. I don't have the freedom to completely abandon P5 for the entire application. Do I need to rewrite this class to use the raw Canvas API for this to work? That's a lot of work. I wanted to get a sense of potential performance improvement before doing something like that.

Query.swap Backwards compatibility

I'm trying to use a datepicker known as flexcal on my site. It is important for me to use it accurately, to allow selection from a Jewish calendar. My site is based on jQuery v3.3.1, but flexcal was designed for jQuery v2.1.3. I thought it shouldn't cause any problems, but I came across the following error:
Uncaught TypeError: $.swap is not a function
After searching, I found here that this is a method that was intended to be private and was never documented, Anyway at the moment I'm having trouble embedding a widget on my site. Reviewing the source code of the widget reveals that the use of the method looks like this:
return $.swap(
parent,
{display:'inline-block'}, // make it visible but shrink to contents
swapper.bind(this, elem, parent.parentNode)
);
Does anyone know what the purpose of the method is, does it have a parallel alternative, or some other troubleshooting advice?
If you look at the source of jQuery.swap (https://github.com/jquery/jquery/blob/3.4.1/src/css/var/swap.js), you'll see that all it does is temporarily change some CSS attributes of the first argument (parent, in your case), run a calculation, and the restore the original attribute values. You can implement that yourself. It's particularly easy in your case, since the only CSS attribute we're temporarily changing is display:
var old_display = parent.style['display'];
parent.style['display'] = 'inline-block';
var ret = swapper.bind(this, elem, parent.parentNode).apply(parent, []);
parent.style['display'] = old_display;
return ret;

CreateJS - Type not recognized error thrown during sound registration

I am trying to load sounds through the SoundJS sound registration, and getting the following error:
createjs.js:15 Uncaught Error: Type not recognized.
I figure that the soundjs library is having issues either locating my files or having trouble with the file extensions, but I am using .ogg, which is inline with all the examples I've seen.
Here is my code:
createjs.Sound.alternateExtensions = ["mp3", "ogg"];
createjs.Sound.on("fileload", function(event) {
console.log(event);
}, this);
for (var i = 0; i < soundManifest.length; i++) {
soundManifest[i].loaded = false;
console.log("loading " + soundManifest[i].src);
createjs.Sound.registerSound(soundManifest[i].src, soundManifest[i].id)
}
soundManifest is an array of objects with a source item giving the path to the .ogg files, and an id. I've double and triple checked the path names, so pretty sure that's not it. Any ideas? I am developing on Chrome.
Thanks for posting a github link. It was helpful. Fortunately, I have a super simple answer for you.
Rename the "Object" class you made in Main.js, and you should be good to go.
-- The long answer --
I tossed a breakpoint the error that is thrown, and it showed that when SoundJS tries to create a LoadItem, it fails. This is because it should be treating the LoadItem it receives as an Object, but the line below is failing:
} else if (value instanceof Object && value.src) {
// This code should be executed
}
At first I thought there was a bug in SoundJS that we had somehow missed in the last 2 years, but closer inspection showed that object prototypes in your application are messed up. If you open any browser window, and hit the console, this will return true:
({}) instanceof Object
// true
However while running your app, it returns false.
The issue became clear when I removed all your other classes other than CreateJS and main, and then tried this:
new Object();
// Throws an error that includes info about "Victor"
In main.js, you are defining an "Object" class, which extends a CreateJS Shape. It is global because there is no method closure around the code, so it overwrites the global Object class/prototype.
The reason I included this explanation, is because I couldn't figure out what was going on until I had my steps to show that prototypes were broken in the app mostly written out before the reason dawned on me. I thought it might be of some interest :)

TypeError: this._url is undefined at Dojo FilteringSelect onChange callback

I keep getting following error: TypeError: this._url is undefined at the callback of a Dojo FilteringSelect.
I simplified my code to this:
var testFeatures = [
{ "id": 1, "Adresa": "Pyšvejcova 6, Kotěhůlky"},
...
];
var filteringSelect = new FilteringSelect({
id: "testSelect",
autoComplete: false,
searchAttr: "Adresa",
store: new Memory({ data: testFeatures }),
onChange: this.onSelected
}, "testSelect");
filteringSelect.startup();
//end of the function, still in the same define callback
onSelected: function () {
//custom processing
var queryTask = new esri.tasks.QueryTask(this.serviceUrl);
var query = new esri.tasks.Query();
query.outFields = ["OBJECTID"];
query.where = "Adresa=" + dojo.byId("testSelect").value;
query.returnGeometry = true;
queryTask.execute(query, this.zoomToSelected);
}
zoomToSelected: function (featureSet) {
//custom map processing
}
and HTML:
<input id="testSelect" data-dojo-attach-point="testSelect" />
I have no idea where's the problem, Google found no case similar to mine. FireBug says the error occurs in init.js. Console says line 199, but the code in question (...nction(){},onExecuteForCountComplete:function(){},onExecuteForExtentComplete:fun...) is on line 256.
One possible cause of problems might be ArcGIS JavaScript API or Web AppBuilder - this seems not to be one of the "ArcGIS-heavy" parts of the code, but I don't know for sure. It's ArcGIS JS API 3.15 (Dojo 1.10) and Web AppBuilder for developers version 1.4.
EDIT: with help of #KenFranqueiro and this post I made some progress. I can't say that I fully understand the onChange callbacks, but I learnt to omit the parentheses while calling a named function. The onSelected still wasn't called, but modifying the input data to include id solved this. But it didn't solve the main problem...
Now the old good TypeError: this._url is undefined occurs at queryTask.execute, or between it and start of zoomToSelected method. The exact place where the error occurs changed to line 256, column 351, with following referenced code:
...e:function(a,b,c,d,f){var m=f.assembly;a=this._encode(n.mixin({},this._url.query...
There is a pointer at the = after "a", so the error seems to be to the right of it, trying to mixin something non-existent to something else. I have no idea what the this in the init.js should mean. Unfortunately, dojo core code is almost undebuggable without some de-obfuscation. Is this my only option, or does anybody know how to solve it?
So debugging the init.js wasn't so hard, it takes QueryTask as this. As far as I know, this shouldn't have a _url attribute. So I must have some mistake in the queryTask as well.
Obsolete part of the question, archived:
I wonder whether the problem might be caused by the onChange callback's argument, which I don't really understand. I've read several examples of Dojo FilteringSelect with onChange event set, like the official one. Usually it has some argument, but I don't know what does it mean and where it gets from. In the official example it corresponds to the div id and nothing else. However, how is the id translated to a variable and even whether my assumption that it's the id is correct. The detailed documentation is not much helpful in this case.
Older EDIT: testSelect is an object. Seems it was created implicitly with the dom - it's a childnode of this.domNode. So now I understand where it comes from, but not how to prepare another function to be called on change and why the correct syntax is what it is.
Also, I don't know where exactly is the problematic undefined this._url supposed to exist. In my example, this refers to the dijit, but I have no idea what is the scope of the part of init.js where the problem occurs.
I'm not sure how much related are the two subquestions (confusion in the onChange callback and identification of this in init.js), I only suppose they are symptoms of the same issue since the error is thrown at the onChange event in my code.
The problem at the query was caused by this.serviceUrl either missing as a part of wrong coontext, or being an object instead of a URL string. So the final step was to make sure the correct context is used (by lang/hitch) and then setting this.serviceUrl to be what I originally thought, one of the attributes of the object referenced as serviceUrl before.

how to target a MovieClip with createjs

Im trying to export an group photo animation that works fine in flash but not when exported in html5 canvas.
The trick is "simple" : each photo is a button and when you roll your mouse over the picture of someone, his jobtitle appears.
Ican't make it happen with createjs !
I have a MovieClip instance on my stage named "jobs_cont" whose timeline has different keyframes and labels for everyone's jobtitles.
The thing is i'm not successfull with targeting "jobs_cont" and using gotoAndPlay a specific frame or label in its timeline when a button is hovered.
the "alert instruction" alone is recognised but not the "jobs_cont.gotoAndPlay":
var frequency = 3;
stage.enableMouseOver(frequency);
this.mybutton.addEventListener("mouseover", fl_MouseOverHandler);
function fl_MouseOverHandler(){
this.jobs_cont.gotoAndPlay("mylabel");
alert("hovered by mouse");
// end of your personalized code
}
I think i must miss something targeting "jobs_cont" in createjs but i'm newbie in javascript and can't figure it out despite my day of researches.
If someone could give a hint.
Thank you.
You are dealing with scope issues. If you define a function on your timeline using the above syntax, the function doesn't have a scope, so this becomes Window.
You can change the function syntax to be defined on the current object:
this.fl_MouseOverHandler = function(){
this.jobs_cont.gotoAndPlay("mylabel");
alert("hovered by mouse");
// end of your personalized code
}
Lastly, JavaScript doesn't automatically provide function scope for event listeners (yet!) so you have to scope the function yourself. If you have a version 0.7.0 or later of EaselJS, you can use the on method instead of addEventListener (docs). Note that you have to use this.fl_MouseOverHandler as well.
this.mybutton.on("mouseover", this.fl_MouseOverHandler, this);
You can also scope the function using a utility method such as Function.prototype.bind() (docs):
this.mybutton.addEventListener("mouseover", this.fl_MouseOverHandler.bind(this));
Hope that helps!

Categories