ScottK Posted January 31, 2016 Share Posted January 31, 2016 I'd like to encapsulate my PIXI rendering in a JavaScript Prototype Object-Oriented fashion. The problem I'm running into is that there is no 'this' object when my animate method is invoked as the callback from requestAnimationFrame(). Can someone suggest a means to do this? I realize this is likely just a general JavaScript issue, as opposed to something related to PIXI, so sorry if this is trivial. Thank you in advance of any help you can provide! Here is what I believe is the minimal code needed to demonstrate the issue: var FFT = function() { this.renderer = PIXI.autoDetectRenderer(600, 800, {antialias: true}); document.body.appendChild(this.renderer.view); this.stage = new PIXI.Container(); this.stage.interactive = true; this.graphics = new PIXI.Graphics(); this.stage.addChild(this.graphics); }; FFT.prototype.renderLines = function() { // todo render lines here }; FFT.prototype.renderLoop = function() { // when this method is invoked via the requestAnimationFrame // callback there is no 'this' object bound, so this.graphics // is undefined. my goal is to avoid adding global functions, // if possible. this.graphics.clear(); this.renderLines(); this.renderer.render(this.stage); requestAnimationFrame(this.renderLoop); }; FFT.prototype.start = function() { this.renderLoop(); }; var fft = new FFT(); fft.start(); Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 1, 2016 Share Posted February 1, 2016 //1. use bind requestAnimationFrame(this.renderLoop.bind(this)); //2. use new function var self = this; requestAnimationFrame(function() { self.renderLoop(); } ); //3. use ES6 requestAnimationFrame(() => { this.renderLoop() } ); //4. bind function in constructor function FFT() { //... this.renderLoop = this.renderLoop.bind(this); } One cannot just walk into mordor^W^W^W use "this" in the function that is passed somewhere. Crash course on javascript. JimRealto and skeddles 2 Quote Link to comment Share on other sites More sharing options...
mattstyles Posted February 2, 2016 Share Posted February 2, 2016 5. Use class properties // This is still in draft but compilers such as babel or webpack can be configured to understand it class Foo { constructor() { ... } loop = () => { raf( this.loop ) } } Note that natively this is currently supported nowhere, babel transpilation turns it into number 4 in Ivans examples. Use bind, get in to good habits. Using the arrow function is fine but it does not bind scope to the function, instead it invalidates this, which means that scope is inferred from the outer scope of the function. "Wat?", yeah, its confusing. The upshoot is, arrow functions usually work as you probably expect, but not absolutely everywhere. This is a great article on the subject. Note that by binding functions you are creating a new instance of the function for every object you create, whereas normally JS will try to be smart about function invocation and grab them from the prototype. In your case it will not matter at all but it is something to consider if you are creating 1000+ objects with bound functions. And for your own piece of mind, this is not trivial. JS scoping rules can get a little funky so get your head round them early. I've tried to hire too many contractors who are shaky on these details and I just can not trust them, and they're asking for a lot per day. Get learning this stuff early, your future self will thank you. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 2, 2016 Share Posted February 2, 2016 @mattstyles Yep, that's why 4. and class properties are the best. But really, one more allocated function per frame isnt a problem. Its a problem if there are thousands of new objects in render loop. Quote Link to comment Share on other sites More sharing options...
ScottK Posted February 2, 2016 Author Share Posted February 2, 2016 Thank you ivan.popelyshev & mattstyles! That is very helpful information and exactly what I was looking to understand. mattstyles and ivan.popelyshev 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.