Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@MSGhero
Last active September 3, 2016 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MSGhero/5f64e8d09beb4e4766a9b87721fb0b94 to your computer and use it in GitHub Desktop.
Save MSGhero/5f64e8d09beb4e4766a9b87721fb0b94 to your computer and use it in GitHub Desktop.
9-Slice Algo Test
package;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flixel.FlxSprite;
import flixel.FlxState;
/**
* ...
* @author MSGHero
*/
class PlayState extends FlxState{
var sprite:FlxSprite;
override public function create():Void {
sprite = new FlxSprite(108, 108);
loadSpriteSheet();
add(sprite);
}
function loadSpriteSheet():Void {
var bmd = new BitmapData(9, 9, false, 0xffffffff);
var rect = new Rectangle(0, 0, 3, 3);
bmd.fillRect(rect, 0xffff0000);
rect.setTo(3, 0, 3, 3);
bmd.fillRect(rect, 0xffff8800);
rect.setTo(6, 0, 3, 3);
bmd.fillRect(rect, 0xffffff00);
rect.setTo(0, 3, 3, 3);
bmd.fillRect(rect, 0xff00ff00);
rect.setTo(3, 3, 3, 3);
bmd.fillRect(rect, 0xff0000ff);
rect.setTo(6, 3, 3, 3);
bmd.fillRect(rect, 0xffff00ff);
rect.setTo(0, 6, 3, 3);
bmd.fillRect(rect, 0xffffffff);
rect.setTo(3, 6, 3, 3);
bmd.fillRect(rect, 0xff888888);
rect.setTo(6, 6, 3, 3);
bmd.fillRect(rect, 0xff000000);
// ----------------------------------------------- 9 slice starts here
var slices = [3, 3, 6, 6];
var leftW = slices[0];
var topH = slices[1];
var rightW = bmd.width - slices[2];
var botH = bmd.height - slices[3];
var centerW = slices[2] - slices[0];
var centerH = slices[3] - slices[1];
var finalW = 257; // <------------------------------------------------ CHANGE THESE
var finalH = 21; // <--------------------
var finalCenterW = finalW - leftW - rightW;
var finalCenterH = finalH - topH - botH;
var scaleHoriz = finalCenterW / centerW;
var scaleVert = finalCenterH / centerH;
var mat = new Matrix();
var pt = new Point();
var finalImg = new BitmapData(finalW, finalH);
// TL
rect.setTo(0, 0, leftW, topH);
pt.setTo(0, 0);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// T
rect.setTo(leftW, 0, finalCenterW, topH);
mat.setTo(scaleHoriz, 0, 0, 1, leftW * (1 - scaleHoriz), 0);
finalImg.draw(bmd, mat, null, null, rect);
// TR
rect.setTo(leftW + centerW, 0, rightW, topH);
pt.setTo(finalW - rightW, 0);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// L
rect.setTo(0, topH, leftW, finalCenterH);
mat.setTo(1, 0, 0, scaleVert, 0, topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// C
rect.setTo(leftW, topH, finalCenterW, finalCenterH);
mat.setTo(scaleHoriz, 0, 0, scaleVert, leftW * (1 - scaleHoriz), topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// R
rect.setTo(leftW + finalCenterW, topH, rightW, finalCenterH);
mat.setTo(1, 0, 0, scaleVert, finalCenterW - leftW, topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// BL
rect.setTo(0, topH + centerH, leftW, botH);
pt.setTo(0, topH + finalCenterH);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// B
rect.setTo(leftW, topH + finalCenterH, finalCenterW, botH);
mat.setTo(scaleHoriz, 0, 0, 1, leftW * (1 - scaleHoriz), finalCenterH - topH);
finalImg.draw(bmd, mat, null, null, rect);
// BR
rect.setTo(leftW + centerW, topH + centerH, rightW, botH);
pt.setTo(leftW + finalCenterW, topH + finalCenterH);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// render
sprite.pixels = finalImg;
sprite.dirty = true;
}
}
@MSGhero
Copy link
Author

MSGhero commented Apr 6, 2016

Just to clear things up:

When 9-slice scaling, the 4 corners are untouched. The top and bottom widen, the left and right heighten, and the center does both.

So I copyPx'd the corners. Drawing with clip rects and matrices is weird af.

clipRect is the rect of the chunk you're scaling AFTER it's been scaled. I think. Not totally sure why the CENTER rect needs the + leftW, but it breaks the RIGHT rect otherwise. It honestly doesn't make any sense.

matrix was just trial and error. The scaling is fairly clear, but the offsets are not.

I'll play around later and see which offsets actually aren't necessary (even though they don't change the results). ¯\_(ツ)_/¯

@MSGhero
Copy link
Author

MSGhero commented Apr 6, 2016

Oh wait I messed up lol. WORK IN PROGRESS

@MSGhero
Copy link
Author

MSGhero commented Apr 6, 2016

Maybe now? Can I squash revisions and 12:00 AM comments? Going to sleep now bye

@IBwWG
Copy link

IBwWG commented Aug 25, 2016

Please see my fork, there were a couple corrections needed to the algorithm (you can see a few revisions where I show how it's broken.) It only worked in the above code because your bezel widths were all equal. With the corrections the bezels can be whatever you want.

BTW thanks for the starting point, this saved me a lot of time. :)

@MSGhero
Copy link
Author

MSGhero commented Sep 3, 2016

Wow I didn't get a notification for your post, but awesome I'll check it out. Beeblerox did something, and haxeui2 will have something, so 9slice code is highly fragmented and incomplete

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment