Emmiter & tabs

Hi Dan,
I'm using the Emitter, and when I switch between tabs, it sometimes gets stuck and keeps running "indefinitely". How can this be resolved?
thanks.

What version of ZIM?

We try and fix that by pauseOnBlur but occasionally we see it run when it comes back from a different browser tab. We will do some more testing on it. How are you using your emitter? startPaused:true to start and then spurt()? Is it running when you switch tabs? Or is it paused when you switch tabs?

We will see if the visibilitychange event helps - you can try that yourself too.

We are already using the visibilitychange event...

zim.setBlurDetect = function() {
	z_d("83.36");
	
	zim.blurCheck = true;
	zim.pauseAnimateOnBlur = true;
	zim.pauseOnBlur = [];
	zim.blurDetect = (function(){
		var stateKey,
			eventKey,
			keys = {
					hidden: "visibilitychange",
					webkitHidden: "webkitvisibilitychange",
					mozHidden: "mozvisibilitychange",
					msHidden: "msvisibilitychange"
		};
		for (stateKey in keys) {
			if (stateKey in document) {
				eventKey = keys[stateKey];
				break;
			}
		}
		return function(c) {
			if (c) document.addEventListener(eventKey, c);
			return !document[stateKey];
		};
	})();

	zim.blurDetect(function(){
		
		var i,obj,id;
		if(zim.blurDetect()){
			setTimeout(function(){		
				
				// coming back from blur into focus so set back animations									
				if (zim.pauseOnBlur) {					
					for (i=0; i<zim.pauseOnBlur.length; i++) {
						obj = zim.pauseOnBlur[i];
						if (!obj.pauseOnBlurPaused) obj.pause(false);
					}
				}
				if (zim.pauseAnimateOnBlur && zim.animatedObjects) {	
					var emitterCheck = [];
					var lastParent;
					for (i=0; i<zim.animatedObjects.objects.length; i++) {
						obj = zim.animatedObjects.objects[i];	
						var currentStates = zim.copy(obj.tweenStates);							
						if (!obj.tweenStates) {
							obj.pauseAnimate(false);
						} else if (zot(currentStates.all) || currentStates.all) {	
							obj.pauseAnimate(false);
							if (!obj.dynamicAnimation) {
								for (id in currentStates) {
									if (id=="all") continue;
									if (currentStates[id]===false) {
										obj.pauseAnimate(true, id);
									}
								}
							}
						} else {	
							obj.pauseAnimate(true);
							for (id in currentStates) {
								if (id=="all") continue;
								if (currentStates[id]) obj.pauseAnimate(false, id);
							}
						}	
						if (obj.type == "Sprite") obj.paused = true;
						if (
							obj.parent && 
							obj.parent.type == "Particles" 
							&& obj.parent.emitter 
							&& obj.parent.emitter.focusWarm
						) {
							lastParent = obj.parent.emitter;
							if (emitterCheck.indexOf(obj.parent.emitter) < 0) emitterCheck.push(obj.parent.emitter);
						}
					}
					if (emitterCheck.length>0) {
						for (i=0; i<emitterCheck.length; i++) {
							emitterCheck[i].doWarm(emitterCheck[i].focusWarm);
                            emitterCheck[i].clearPool();
						}
					}
				}
			},300);
			if (WW.zdf) WW.zdf.dispatchEvent("tabfocus");
		} else {
			
			// going out of focus so set pauses 
				
			if (zim.pauseOnBlur) {
				for (i=0; i<zim.pauseOnBlur.length; i++) {
					obj = zim.pauseOnBlur[i];
					obj.pauseOnBlurPaused = obj.paused;
					obj.pause(true);
				}
			}
			if (zim.pauseAnimateOnBlur && zim.animatedObjects) {
				// zim.loop(zim.animatedObjects.objects, function(obj) {
				// 	obj.pauseOnBlurPaused = obj.type=="Sprite"?obj.runPaused:obj.paused; 
				// });
				zim.pauseAnimate(true, "pauseOnBlur");
			}
			if (WW.zdf) WW.zdf.dispatchEvent("tabblur");
		}
	});

};//-83.36

I can't seem to replicate on purpose. If anyone else can somehow always get an emitter to go when it should not go as you come back from another tab in a way that is reproduceable, let us know.

Oh! Got one. I was trying with startPaused:true - but if you have no startPaused and start running and then later will do pauseEmitter() and go back and forth between tabs when you come back it keeps going.

const e = new Emitter().center()

timeout(2, ()=>{
	e.pauseEmitter();
})

So the timeout is happening when you are not on the tab. Come back and the emitter goes - because it did not realize it was going to turned off. Will think about it.

Yes, I’m using startPaused: true and spurt(). While it’s running, I switch between tabs. It seems like it keeps running (I’m not completely sure), but when I come back it looks like it restarts, and sometimes it gets stuck and continues indefinitely.

Actually, I tried setting zim.pauseAnimateOnBlur = true even before I asked you, and it seems to get stuck even more easily.

Interesting... I could not make it break with startPaused:true and spurt. Will test that again. I did get it to break with running and then in a timeout pauseEmitter() and then switch tabs just before the timeout and come back after the timeout. Oh... are you spurting a number or are you spurting for a time?

I think we fixed it. We fixed our test page - and have patched ZIM 019 and updated NPM too.

If the ZIM Emitter was paused or unpaused when browser tab is not in focus, the bug was causing the emitter to sometimes incorrectly stop or start when switching tabs.

When tabs lose or gain focus we record the last setting of the emitter but if the pauseEmitter is triggered when the tab is not in focus, it was remembering the wrong value. We now set the recorded setting as well when we run pauseEmitter.

It fixed our test... it is possible that your situation was different, so let us know. Do a hard refresh.

1 Like

tanks.
I checked and it still hasn't been solved for me, I get error:

Cannot set properties of undefined (setting 'pauseOnBlurPaused')
    at t.Emitter.pauseEmitter (zim_min019.js?v=6:7:1031591)
    at t.Emitter.spurt (zim_min019.js?v=6:7:1030545)

Ah... fixed. Had not tested to see if we had run the interval yet.

Please hard refresh and try again.