I encountered a problem when I was reading the page
http://processingjs.org/articles/PomaxGuide.html
Please note the section "Processing.js as javascript graphics library":
the setup method is rewrote as following:
pjs.setup = function() {
pjs.size(200,200);
// we want to turn off animation, because this is a demo page and it
// would use cpu while not being looked at. Only draw on mousemoves
pjs.noLoop();
}
and Finally, we can call setup() to kickstart the sketch.
pjs.setup();
The question is that the setup() is already override, how can the processing run the loop? there's no such code to invoke draw() loop in setup().
The draw() method gets called automatically according to the value of a field called doLoop inside the Processing class (source code: https://s3.amazonaws.com/github/downloads/processing-js/processing-js/processing-1.4.1.js).
When you call noLoop() you are setting this value to false, disabling in fact the loop. If don't do this, then Processing.js behaves in its default way executing the loop: there's no need to state it explicitly in the setup() method.
Related
I have a python file outputting a .png file to a local directory once a second, and this p5.js Javascript file is being hosted from this directory on a server. My issue is in trying to use the loadImage() function to load this local .png -- if I do so, it'll only refer to the initial value of it, and not its new changed value. Even when using a callback function inside draw(), it is very buggy, and does not change. Here's the file:
let splot;
//...
//irrelevant classes
//...
function draw() {
background(245);
solOnePane.display();
s1plot = loadImage("plot.png", imageLoaded);
}
function imageLoaded()
{
console.log("Debug");
image(s1plot,200,200);
}
The result is a super buggy and unchanging image file that only reflects the image file at the state of loading the site. Upon a refresh, the file is updated. So, how can I write code with loadImage() to load an image at the current moment?
Thanks so much.
If the image is saved at a set internal externally, let's say every second, you could use setInterval() every 1100ms for example to reload the image:
var s1plot;
function setup(){
//...init your things here
//reload the image every 1.1s
setInterval(loadImage, 1100, "plot.png", imageLoaded, imageLoadFailed);
}
function imageLoaded(loadedImage)
{
s1plot = loadedImage;
console.log("image loaded", s1plot);
}
function imageLoadFailed(event){
console.warn("image load failed", event);
}
function draw() {
background(245);
if(s1plot){// try to display the image only when it's available
image(s1plot, 200, 200);
}
}
You could use draw() as well and change the frameRate() to so a new frame is rendered every second or so. Here's a modified version of the above using frameRate():
var s1plot;
function setup(){
//...init your things here
//set frameRate to 1 frame every 1.1s
frameRate(1000 / 1100);
}
function imageLoaded(loadedImage)
{
s1plot = loadedImage;
console.log("image loaded", s1plot);
}
function imageLoadFailed(event){
console.warn("image load failed", event);
}
function draw() {
background(245);
if(s1plot){// try to display the image only when it's available
image(s1plot, 200, 200);
}
// reload the image
loadImage("plot.png", imageLoaded, imageLoadFailed);
}
This may be simpler (sometimes setInterval's scope can get hairy), but it also means you're limited to slow render updates. You may want this if the p5 sketch if simply displaying an image, but not if for example you want to handle reactive user interaction as well.
The code above isn't tested, but hopefully illustrates the idea.
It's worth double checking loadImage() reference when in doubt.
For example, these details are important:
The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the loadImage() call in preload(). You may also supply a callback function to handle the image when it's ready.
In your case the second option (supplying a callback function) applies, however you've forgotten to add the image argument to the image load callback.
This assumes there are no issues writing plot.png to disk with no errors and the timing is a bit of a hack.
In an ideal world you would have the first system which writes plot.png send a message to p5 when the image has been successuflly been written and is ready to be loaded. (If plot.png is for example generated by a python script using matplotlib or something similar you could use a server sent event or websocket library to which p5 can connect to and listen for the message to load the image)
This question already has an answer here:
JavaScript setTimeOut doesn't seem to work like I expect
(1 answer)
Closed 4 years ago.
Relative newcomer to JS trying to keep my code class-oriented for the sake of best practice. I found a piece of code here for a text cycling effect I wanted to employ on a project. Using the code as-is within my main App.js worked fine. I then attempted to make it class/module oriented for later possible recycling, but thus far I've hit a brick wall. Passing console logs instead I've noticed that my attempts to use SetInterval, both within the class and in my App.js file calling the class into my HTML, don't seem to work, never properly looping more than once outside of isolating it.
Here's the current state of my code, possibly far removed from what I was doing previously, but it should give an idea where my head's at.
TextCycle.js:
import $ from 'jquery';
class TextCycle{
constructor(){
this.cycledText = $('.cycled-text');
this.i = 0;
}
cycle(){
//this.cycledText.removeClass('cycled-text--active');
//this.cycledText.eq(this.i).addClass('cycled-text--active');
this.i++;
console.log(this.i);
}
}
export default TextCycle;
App.js:
import TextCycle from './components/TextCycle';
var textCycle = new TextCycle();
setInterval(textCycle.cycle(), 3000);
Given I have a working version this isn't a critical issue, but given the point was practicing this sort of JS organization and modularization due to how I was taught, any insight on making this work is immensely helpful!
There is a problem with the way you're using setInterval() , along with your call to .cycle().
In short, you will want to update your code that calls setInterval so that cycle() is only called during the callback. Something like this would do:
setInterval(function() { textCycle.cycle() }, 3000);
One of the reasons your current code fails is that, textCycle.cycle() is called immediately, during this line:
setInterval(textCycle.cycle(), 3000); // Notice the () after cycle?
// That's causing the cycle
// method to be called immediately
By placing this in a callback function, as shown above, this does a few things:
it ensures that cycle() is invoked from the correct context (ie the context of your textCycle object. That basically means that when your use this inside of cycle(), then this will be the textCycle object, rather than the global object
it ensures that the cycle() method only gets invoked during the setInterval "callback", which is called on your set internal, rather than being called immediately
Hope this helps!
I'm an HTML5 newbie and I was wondering if someone could tell me what I'm doing wrong here. I would like to be able to use GSAP to animate a vector file I'd add to the stage and would need to be able to make it animate when I call a function, however when I try to do this I keep getting cannot tween a null object, but if it's not wrapped in a function the animation plays fine.
I created a new HTML5 canvas to see if the issue persisted and it did, so this is what I did:
Added a symbol to a blank HTML5 canvas, made it a Movie Clip and drew a circle. I called the instance mcThing
In the Timeline, I selected the first frame and went into Actions
I wrote:
function playAnimation() {
TweenMax.to(this.mcThing, 3, {y:500});
}
playAnimation();
When testing in Chrome, I get cannot tween a null object. If I reference it as mcThing (omitting the this. I instead get mcThing is not defined.
If I then remove the function and just have this:
TweenMax.to(this.mcThing, 3, {y:500});
It plays fine, but now I can't call it when I need to.
Some context:
Essentially what I currently have is a WebSocket listening for messages. When it receives a message, it's added to the queue. I am trying to get it to play an animation and insert the text from that message. The text itself should be okay: I used CreateJS to instantiate a text in the code and TweenMax works there, the problem is animating shapes/drawings. I suppose I could instantiate all the shapes in the code itself and TweenMax would work then but I don't think this is realistic as the animation/shapes are fairly complex, so I'm trying to target the stage. The animation would play out, stop, then the message would be removed from the queue and the next one would play (same animation, different text).
I think this is a scope issue, but I'm not sure what I need to change. Any help would be much appreciated!
This issue is because of the scope. Your playAnimation is not scoped to this, so it is called in the global scope.
Try this:
this.playAnimation = function() {
TweenMax.to(this.mcThing, 3, {y:500});
}
this.playAnimation();
Putting your mcThing into the function scope would also work:
var thing = this.mcThing;
function playAnimation() {
TweenMax.to(thing, 3, {y:500});
}
playAnimation();
Or you could scope the function call itself!
function playAnimation() {
TweenMax.to(this.mcThing, 3, {y:500});
}
playAnimation.call(this);
There are lots of ways to get around it once you understand how the scoping works. I recommend the first approach.
Hope that helps!
I'm getting into game developing online. I am trying to make an online FPS game, and I've only gotten to the point where I need to update my character. I am trying to keep my code simple, using only a draw and update function. When the html loads, I execute both: (Is this necessary?)
<body onload='DRAW(); UPDATE();'>
The draw function draws the player to the screen, and the update is supposed to check for a keypress to move the character. I am trying to make the script update using this:
function UPDATE()
{
update = setInterval(UPDATE, 60);
}
and to my knowledge, it is working fine because when I try and edit code in my online IDE (c9.io) which I use to test the site, it freezes when the site is running. I am also calling eventListeners in the draw function. (Is this proper if I want to test for a key down every frame?)
function DRAW()
{
window.addEventListener('keydown', function (e) {
keys.keys = (keys.keys || []);
keys.keys[e.keyCode] = true;
});
window.addEventListener('keyup', function (e){
keys.keys[e.keyCode] = false;
});
}
My questions are:
Is there an easier way to make a script update every frame?
Is there a JavaScript addon (like Three.js) I can use to make
developing this easier on myself?
Any knowledge is greatly appreciated.
This makes everything crash:
function UPDATE()
{
update = setInterval(UPDATE, 60);
}
You are recursively creating a new interval every 60ms; the first time you call UPDATE, you create an interval that creates a new interval every 60ms. All newly create intervals do the same. Don't really know what you actually want to do here.
I am also calling eventListeners in the draw function. (Is this proper
if I want to test for a key down every frame?)
It's fine to create eventlisteners in the draw function, provided you only call this function once. Which I guess you don't. Each time you call DRAW() a new set of eventlisteners will be added, and you really don't want that.
What you need is a form of game loop. Explaining how to create an FPS game is a bit more than I can do, but you can start by looking at this article Anatomy of a video game
So, I've been trying to understand a specific js library by running it through my browser's debugger, and something happens that just confuses me.
I first encountered this in the Phaser game library, but I've seen it another library as well. I'll use Phaser as an example:
<script>
(function(){
var game = new Phaser.Game(800, 600, Phaser.CANVAS, '');
game.state.add('Game', Game);
game.state.start('Game');
})();
</script>
So that anonymous function finishes setting some things up, and I step over and out of that function, and after a couple more steps (the pointer just sitting at the top of the html doc in the meantime) my program out of nowhere ends up here:
Phaser.Device._readyCheck = function () {
var readyCheck = this._readyCheck;
....
}
It didn't look like anything within my flow of control called that function, so how did I get here? What's calling this function? I've read a bit about 'asynchronous functions' and that sounds like a pretty good explanation, but the stuff I've glanced at on Google don't really explain anything well, so I can't say I understand it enough to be sure. I'm relatively new to JavaScript.
The library sets up event handlers for various events which then get called asynchronously. In this case, event handlers are setup to to watch for the completion of the loading of the DOM, among other things, so that the internal state of the library can be initialized. You can see how it happens in the source
src/system/Device.js:Phaser.Device._readyCheck
and Phaser.Device.whenReady in the same file. With a little searching you can easily find who calls whenReady.
The function you pointed out at the top is a self-executing function. (); causes everything contained in the preceding parentheses to be executed immediately.