Jump to content

DocumentObjectContainer.Visible = false causing odd behavior


Recommended Posts

I have a problem that's sort of hard to describe. 

To try and sum it up, setting the visibility of a DOC to false and then updating the position of the non-visible DOC, when setting the DOC back to visible, the DOC isn't where it's supposed to be.


See? sorry... it's hard to explain :)


I have a page set up as an example


EDIT: And HERE is a jsfiddle to mess with (but using black squares instead of actual images because of cross-domain problems)


The code is very messy, but this is more of a "proof of concept" test page to work out some ideas to implement on the main project. 


Let me try to explain the goal of what I'm doing:

I took a large image and separated it out into multiple smaller images. I've then "stitched" them together as sprites on a DOC.

I've then taken the same large image, made it half sized, and then split it up into the same sized "tiles" as the previous, and then placed those tiles on a second DOC.

Once more with a 3rd iteration, making the image 1/4 of the original size.


On mouse wheel, all three DOCs scale in and out and click-dragging pans all 3 DOCs around. (there's also some culling going on for tiles that get placed outside of the canvas bounds).

At a certain zoom level, I hide one DOC and show another (the corresponding "zoom-levels", think Google Earth)


All of this works beautifully. Except when I scale in and out AFTER panning the DOCs around. 

What's weird is that when panning, the position is getting updated and that's pretty much it. When scaling, the position is ALSO updated.

If I don't set the visibility to false on either 3 DOCs, they never shift in their positioning. You can pan them and scale them and they'll never "jump".

Once you start setting the visibility to "none" and then pan them around, when it gets set back to visible=true, its position is off. Like something doesn't get updated properly when the visible is set to false. 


BTW, sorry for the crazy image I'm demoing with. It's just a placholder instead of the actual game's image, but it get's the point across :)

Here's the code for what's going on in the link listed above


Again, sorry for how disheveled the code is, it's me playing with ideas and learning how to do them for later on in a projects dev. You can safely ignore the big blob of code at the top, It should be a link to another js file (The bunny examples stats.js) but instead I just copied the lines directly into the page.

<html>    <head>        <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>        <script src="<?php echo base_url()."js/pixi/bin/pixi.js"; ?>"></script>        <script src="<?php echo base_url()."js/jquery.mousewheel.min.js"; ?>"></script>            </head>        <body>        <script> $(document).ready(onReady);var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function({b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function({s=b;switch(s){case 0:a.style.display="block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};var islandSprites = [];var scale = 1;function onReady(){	renderer = new PIXI.autoDetectRenderer(1920, 1080, {transparent:true});		stage = new PIXI.Stage(0xFFFFFF);		$('canvas').attr('id','canvas');	$('body').on('mousewheel','canvas', function(event) {		event.preventDefault();		var evt = event.originalEvent;		var currentMouseX = evt.pageX - $(this).offset().left;		var currentMouseY = evt.pageY - $(this).offset().top;				scaleFactor = 1.1;				var zoom = (scaleFactor - (evt.wheelDelta < 0 ? 0.2 : 0));		var newScale = scale * zoom;		var newScale2 = (scale * zoom) * 2;		var newScale3 = (scale * zoom) * 4;				var origin = map1.position;		origin.x = currentMouseX - (currentMouseX - origin.x) * zoom;		origin.y = currentMouseY - (currentMouseY - origin.y) * zoom;		map1.position = new PIXI.Point(origin.x, origin.y);				var origin2 = map2.position;		origin2.x = currentMouseX - (currentMouseX - origin2.x) * zoom;		origin2.y = currentMouseY - (currentMouseY - origin2.y) * zoom;		map2.position = new PIXI.Point(origin2.x, origin2.y);				var origin3 = map3.position;		origin3.x = currentMouseX - (currentMouseX - origin3.x) * zoom;		origin3.y = currentMouseY - (currentMouseY - origin3.y) * zoom;		map3.position = new PIXI.Point(origin3.x, origin3.y);				map1.scale.x = newScale;		map1.scale.y = newScale;		map2.scale.x = newScale2;		map2.scale.y = newScale2;		map3.scale.x = newScale3;		map3.scale.y = newScale3;				if(newScale > .5){			map1.visible = true;			map2.visible = false;			map3.visible = false;		}		if(newScale <= .5 && newScale > .25){			map1.visible = false;			map2.visible = true;			map3.visible = false;		}		if(newScale <= .25){			map1.visible = false;			map2.visible = false;			map3.visible = true;		}				scale *= zoom;	});		renderer.view.style["transform"] = "translatez(0)";	document.body.appendChild(renderer.view);	renderer.view.style.position = "absolute";	stats = new Stats();			document.body.appendChild( stats.domElement );	stats.domElement.style.position = "absolute";	stats.domElement.style.top = "0px";	requestAnimFrame(update);		map1 = new PIXI.DisplayObjectContainer();	map2 = new PIXI.DisplayObjectContainer();	map3 = new PIXI.DisplayObjectContainer();		map2.scale.x = 2;	map2.scale.y = 2;	map3.scale.x = 4;	map3.scale.y = 4;		map2.visible = false;	map3.visible = false;	stage.addChild(map1);	stage.addChild(map2);	stage.addChild(map3);		var map1Count1 = 0;	var map1Count2 = 0;	for (var i = 0; i <= 47; i++){			createIslandTile((i+1), 512*map1Count1, 512*map1Count2, map1, '../images/ui/lush/test-map/images/test-map_');		if(map1Count1 < 7){			map1Count1++;		}else{			map1Count1=0;			map1Count2++;			if(map1Count2 > 5){				map1Count2=0;			}		}	}	map1.addChild(new PIXI.Text("MAP1", { font: "20pt monospace", fill: "gray" }));		var map2Count1 = 0;	var map2Count2 = 0;	for (var i = 0; i <= 11; i++){			createIslandTile((i+1), 512*map2Count1, 512*map2Count2, map2, '../images/ui/lush/test-map/images-half/test-map_');		if(map2Count1 < 3){			map2Count1++;		}else{			map2Count1=0;			map2Count2++;			if(map2Count2 > 2){				map2Count2=0;			}		}	}	map2.addChild(new PIXI.Text("MAP2", { font: "20pt monospace", fill: "gray" }));		var map3Count1 = 0;	var map3Count2 = 0;	for (var i = 0; i <= 3; i++){			createIslandTile((i+1), 512*map3Count1, 512*map3Count2, map3, '../images/ui/lush/test-map/images-quarter/test-map_');		if(map3Count1 < 1){			map3Count1++;		}else{			map3Count1=0;			map3Count2++;			if(map3Count2 > 1){				map3Count2=0;			}		}	}	map3.addChild(new PIXI.Text("MAP3", { font: "20pt monospace", fill: "gray" }));		}function createIslandTile(tileNumber,x,y, doc, filePath){	var islandTile = new PIXI.Sprite.fromImage(filePath+tileNumber+'.png');	islandTile.interactive = true;	 	 islandTile.mousedown = islandTile.touchstart = function(data)	{		// store a refference to the data		// The reason for this is because of multitouch		// we want to track the movement of this particular touch		this.data = data;		this.alpha = 0.9;		this.dragging = true;        map1.sx = this.data.getLocalPosition(map1).x * map1.scale.x;        map1.sy = this.data.getLocalPosition(map1).y * map1.scale.y;                map2.sx = this.data.getLocalPosition(map2).x * map2.scale.x;        map2.sy = this.data.getLocalPosition(map2).y * map2.scale.y;                map3.sx = this.data.getLocalPosition(map3).x * map3.scale.x;        map3.sy = this.data.getLocalPosition(map3).y * map3.scale.y;			};		// set the events for when the mouse is released or a touch is released	islandTile.mouseup = islandTile.mouseupoutside = islandTile.touchend = islandTile.touchendoutside = function(data)	{		this.alpha = 1		this.dragging = false;		// set the interaction data to null		this.data = null;	};	// set the callbacks for when the mouse or a touch moves	islandTile.mousemove = islandTile.touchmove = function(data)	{		if(this.dragging)		{			// need to get parent coords..			var newPosition = this.data.getLocalPosition(doc.parent);			            map1.position.x = newPosition.x - map1.sx;            map1.position.y = newPosition.y - map1.sy;            map2.position.x = newPosition.x - map2.sx;            map2.position.y = newPosition.y - map2.sy;            map3.position.x = newPosition.x - map3.sx;            map3.position.y = newPosition.y - map3.sy;        }       	}		islandTile.position.x = x;	islandTile.position.y = y;	doc.addChild(islandTile);}function update(){			stats.begin();		//culling	 for(var i = 0; i < map1.children.length; i++){		//if your right side goes out of the left bounds or your bottom side goed out of the top bounds OR if your left side goes out of the right bounds or your top side goes out of the bottom bounds, then hide	 	if((map1.position.x <= (((map1.children[i].position.x * map1.scale.x) + (map1.children[i].width* map1.scale.x)) * -1)) || (map1.position.y <= (((map1.children[i].position.y * map1.scale.x) + (map1.children[i].height * map1.scale.x)) * -1)) || ((map1.position.x + (map1.children[i].position.x * map1.scale.x) >= renderer.width) || (map1.position.y + (map1.children[i].position.y * map1.scale.x) >= renderer.height))){	 		map1.children[i].visible = false;	 	}else{	 		map1.children[i].visible = true;		 	}	 }		renderer.render(stage);	requestAnimFrame(update);	stats.end();}             </script>    </body></html>


Link to comment
Share on other sites

So, since the scaling on mouse wheel re-position the DOCs, I'm not sure why it ONLY happens AFTER you click-drag to pan... which also re-positions the doc...and THEN zoom in an out.

Comment out lines 109 and 110, and lines 70-84 (so that everything is visible=true and doesn't change) and nothing jumps around.

Link to comment
Share on other sites

UPDATE: here is a jsfiddle to mess with for anyone wanting to help solve this bug. 

It's using black squares instead of images because I cant pull them in due to cross-site origin problems :)

But you can still see how the DOCs jump around when scaling (but again, only when visible gets set to false, repositioned x,y, and then visible set back to true)



Link to comment
Share on other sites

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.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...