Created
September 5, 2015 12:58
-
-
Save m93a/1dc1f46114c92664a7bc to your computer and use it in GitHub Desktop.
Advanced anchor-pivot switching support for every DisplayObject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//create some dummy containers & sprites | |
var container = new PIXI.Container; | |
var sprite1 = new PIXI.Sprite(texture); | |
sprite1.position = new PIXI.Point(0,0); | |
sprite1.width = 20; | |
sprite1.height = 20; | |
var sprite2 = new PIXI.Sprite(texture); | |
sprite2.position = new PIXI.Point(100,0); | |
sprite2.width = 20; | |
sprite2.height = 20; | |
//first the basic behavior | |
//by default pivot is the default property | |
//and anchor is automatically computed | |
container.addChild(sprite1); | |
container.pivot = new PIXI.Point(10,10); //center | |
container.addChild(sprite2); | |
//now, the pivot is not in the center | |
//of the container but remains on 10,10 | |
container.removeChildren(); | |
//now swapping the default property to anchor | |
//you can swap def. prop. by assigning to it | |
container.addChild(sprite1); | |
container.anchor = new PIXI.Point(.5,.5); //center | |
container.addChild(sprite2); | |
//now, the pivot is still in the center | |
//let's try another thing | |
container.pivot = container.pivot; //set pivot as default | |
container.removeChild(sprite2); | |
//pivot stays in the former center | |
//on the point 60,10 | |
//TODO | |
//setting computed point's properties doesn't work yet | |
//so this will take no effect on computed properties | |
container.anchor.x = 42; | |
//TODO | |
//also this doesn't work on sprites because they've | |
//got their anchor property defined in the constructor | |
//then, during rendering, pivot and anchor are summed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function main(){ | |
if(typeof PIXI !== "object") return requestAnimationFrame(main); | |
//helper function to define getters and setters | |
function getSet(obj,prop,get,set){ | |
Object.defineProperty(obj,prop,{ | |
enumerable: true, | |
configurable: true, | |
get: get, set: set | |
}); | |
}; | |
//helper function to remove getters and setters | |
function realValue(obj,prop,value){ | |
Object.defineProperty(obj,prop,{ | |
enumerable: true, | |
configurable: true, | |
writable: true, | |
value: value | |
}); | |
}; | |
//apply automatic .anchor property calculation on obj | |
function autoAnchor(obj,anchorCache,pivotCache){ | |
var firstRun = true; | |
/* | |
* if WeakMap is not supported by browser, | |
* the computed property getter will always | |
* return a new object | |
*/ | |
if(!anchorCache && typeof WeakMap === "function"){ | |
anchorCache = new WeakMap; | |
} | |
if(!pivotCache && typeof WeakMap === "function"){ | |
pivotCache = new WeakMap; | |
} | |
getSet(obj,"anchor",function getter(){ | |
//if the object exist in cache, return it | |
if(!firstRun && anchorCache && anchorCache.has(this)) return anchorCache.get(this); | |
//else create a new auto-computing point | |
var self = this; | |
var point; | |
if(firstRun && anchorCache && anchorCache.has(this)){ | |
point = anchorCache.get(this); | |
}else{ | |
point = new PIXI.Point(); | |
} | |
getSet(point,"x",function(){ return self.pivot.x/self.width },function(){}); | |
getSet(point,"y",function(){ return self.pivot.y/self.height },function(){}); | |
if(anchorCache) anchorCache.set(this,point); //save to cache | |
/* | |
* if the user tries to force change the computed property | |
* to pivot, he would logically do `obj.anchor=obj.anchor` | |
* this would however result in infinite recursion, therefore | |
* we mark the point as possibly recursive so we know we | |
* should remove the getters and setters | |
*/ | |
point._maybeRecursive = true; | |
return point; | |
},function setter(newValue){ | |
//remove getsetters from a recursive value | |
if(newValue._maybeRecursive){ | |
realValue(newValue,"x",newValue.x); | |
realValue(newValue,"y",newValue.y); | |
} | |
//remove getsetters from anchor | |
realValue(this,"anchor",newValue); | |
//this feature is not compatibile with Sprite | |
if(this instanceof PIXI.Sprite) return; | |
if(pivotCache && this.pivot instanceof PIXI.Point){ | |
pivotCache.set(this.pivot); | |
} | |
//enable pivot auto-computation | |
autoPivot(this,anchorCache,pivotCache); | |
}); | |
}; | |
//apply automatic .pivot property calculation on obj | |
//this is essentially the same, so I won't comment it | |
function autoPivot(obj,anchorCache,pivotCache){ | |
var firstRun = true; | |
if(!anchorCache && typeof WeakMap === "function"){ | |
anchorCache = new WeakMap; | |
} | |
if(!pivotCache && typeof WeakMap === "function"){ | |
pivotCache = new WeakMap; | |
} | |
getSet(obj,"pivot",function getter(){ | |
if(!firstRun && pivotCache && pivotCache.has(this)) return pivotCache.get(this); | |
//else create a new auto-computing point | |
var self = this; | |
var point; | |
if(firstRun && pivotCache && pivotCache.has(this)){ | |
point = pivotCache.get(this); | |
}else{ | |
point = new PIXI.Point(); | |
} | |
getSet(point,"x",function(){ return self.anchor.x*self.width },function(){}); | |
getSet(point,"y",function(){ return self.anchor.y*self.height },function(){}); | |
if(pivotCache) pivotCache.set(this,point); | |
point._maybeRecursive = true; | |
return point; | |
},function setter(newValue){ | |
if(newValue._maybeRecursive){ | |
realValue(newValue,"x",newValue.x); | |
realValue(newValue,"y",newValue.y); | |
} | |
realValue(this,"pivot",newValue); | |
if(this instanceof PIXI.Sprite) return; | |
if(anchorCache && this.anchor instanceof PIXI.Point){ | |
anchorCache.set(this.anchor); | |
} | |
autoAnchor(this,anchorCache,pivotCache); | |
}); | |
}; | |
//apply automatic anchor computation on DisplayObjects | |
autoAnchor(PIXI.DisplayObject.prototype); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment