SHOW:
|
|
- or go back to the newest paste.
| 1 | package com.kpulv {
| |
| 2 | import flash.display.Bitmap; | |
| 3 | import flash.display.BitmapData; | |
| 4 | import flash.geom.Point; | |
| 5 | import flash.geom.Rectangle; | |
| 6 | import net.flashpunk.FP; | |
| 7 | import net.flashpunk.graphics.Image; | |
| 8 | /** | |
| 9 | * NineSlice.as | |
| 10 | * @author kpulv | |
| 11 | */ | |
| 12 | public class NineSlice extends Image {
| |
| 13 | ||
| 14 | private var _width:uint; | |
| 15 | private var _height:uint; | |
| 16 | ||
| 17 | public var gridX:uint; | |
| 18 | public var gridY:uint; | |
| 19 | ||
| 20 | public var snapWidth:Boolean = false; | |
| 21 | public var snapHeight:Boolean = false; | |
| 22 | ||
| 23 | public var stretchLeft:Boolean = false; | |
| 24 | public var stretchTop:Boolean = false; | |
| 25 | public var stretchRight:Boolean = false; | |
| 26 | public var stretchBottom:Boolean = false; | |
| 27 | public var stretchCenter:Boolean = false; | |
| 28 | ||
| 29 | private static var cachedPoint:Point = new Point(); | |
| 30 | private static var cachedRect:Rectangle = new Rectangle(); | |
| 31 | ||
| 32 | private var _sliceSource:BitmapData; | |
| 33 | ||
| 34 | public var sliceBuffer:BitmapData; | |
| 35 | ||
| 36 | public var image:Image; | |
| 37 | ||
| 38 | public var slices:Vector.<BitmapData> = new Vector.<BitmapData>(9); | |
| 39 | ||
| 40 | private var needsRefresh:Boolean = false; | |
| 41 | ||
| 42 | public function NineSlice(sliceSource:*, width:uint = 1, height:uint = 1) {
| |
| 43 | _bitmap = new Bitmap | |
| 44 | _width = width; | |
| 45 | _height = height; | |
| 46 | ||
| 47 | if (source is Class) {
| |
| 48 | this.sliceSource = FP.getBitmap(sliceSource); | |
| 49 | } | |
| 50 | else {
| |
| 51 | this.sliceSource = sliceSource | |
| 52 | } | |
| 53 | ||
| 54 | copy(); | |
| 55 | ||
| 56 | super(sliceBuffer); | |
| 57 | } | |
| 58 | ||
| 59 | public function updateSliceBuffer():void {
| |
| 60 | if (_source) {
| |
| 61 | _source.dispose(); | |
| 62 | } | |
| 63 | _source = sliceBuffer; | |
| 64 | _sourceRect = sliceBuffer.rect; | |
| 65 | createBuffer(); | |
| 66 | updateBuffer(); | |
| 67 | } | |
| 68 | ||
| 69 | public function copy():void {
| |
| 70 | if (_width == 0 || _height == 0) {
| |
| 71 | sliceBuffer = new BitmapData(1, 1); | |
| 72 | sliceBuffer.fillRect(sliceBuffer.rect, 0); | |
| 73 | return; | |
| 74 | } | |
| 75 | ||
| 76 | var i:uint = 0; | |
| 77 | var j:uint = 0; | |
| 78 | for (i = 0; i < 9; i++) {
| |
| 79 | slices[i] = new BitmapData(gridX, gridY); | |
| 80 | var xx:uint = convert2dX(i, 3) * gridX; | |
| 81 | var yy:uint = convert2dY(i, 3) * gridY; | |
| 82 | slices[i].copyPixels(_sliceSource, cacheRect(xx, yy, gridX, gridY), cachePoint(0, 0)); | |
| 83 | } | |
| 84 | ||
| 85 | sliceBuffer = new BitmapData(_width, _height); | |
| 86 | sliceBuffer.fillRect(sliceBuffer.rect, 0); | |
| 87 | ||
| 88 | ||
| 89 | ||
| 90 | var bd:BitmapData; | |
| 91 | ||
| 92 | /** Draw the center */ | |
| 93 | if (stretchCenter) {
| |
| 94 | if (_width > gridX + gridX) {
| |
| 95 | if (_height > gridY + gridY) {
| |
| 96 | bd = scaleBitmapData(slices[4], (_width - gridX - gridX) / gridX, (_height - gridY - gridY) / gridY); | |
| 97 | sliceBuffer.copyPixels(bd, bd.rect, cachePoint(gridX, gridY)); | |
| 98 | bd.dispose(); | |
| 99 | } | |
| 100 | } | |
| 101 | } | |
| 102 | else {
| |
| 103 | for (i = gridX; i < _width - gridX; i += gridX) {
| |
| 104 | for (j = gridY; j < _height - gridY; j += gridY) {
| |
| 105 | sliceBuffer.copyPixels(slices[4], slices[4].rect, cachePoint(i, j)); | |
| 106 | } | |
| 107 | } | |
| 108 | } | |
| 109 | ||
| 110 | /** Draw the edges */ | |
| 111 | if (stretchTop) {
| |
| 112 | if (_width > gridX + gridX) {
| |
| 113 | bd = scaleBitmapData(slices[1], (_width - gridX - gridX) / gridX, 1); | |
| 114 | sliceBuffer.copyPixels(bd, bd.rect, cachePoint(gridX, 0)); | |
| 115 | bd.dispose(); | |
| 116 | } | |
| 117 | } | |
| 118 | else {
| |
| 119 | for (i = gridX; i < _width - gridX; i += gridX) {
| |
| 120 | sliceBuffer.copyPixels(slices[1], slices[1].rect, cachePoint(i, 0)); | |
| 121 | } | |
| 122 | } | |
| 123 | ||
| 124 | if (stretchBottom) {
| |
| 125 | if (_width > gridX + gridX) {
| |
| 126 | bd = scaleBitmapData(slices[7], (_width - gridX - gridX) / gridX, 1); | |
| 127 | sliceBuffer.copyPixels(bd, bd.rect, cachePoint(gridX, _height - gridY)); | |
| 128 | bd.dispose(); | |
| 129 | } | |
| 130 | } | |
| 131 | else {
| |
| 132 | for (i = gridX; i < _width - gridX; i += gridX) {
| |
| 133 | sliceBuffer.copyPixels(slices[7], slices[7].rect, cachePoint(i, _height - gridY)); | |
| 134 | } | |
| 135 | } | |
| 136 | ||
| 137 | if (stretchLeft) {
| |
| 138 | if (_height > gridY + gridY) {
| |
| 139 | bd = scaleBitmapData(slices[3], 1, (_height - gridY - gridY) / gridY); | |
| 140 | sliceBuffer.copyPixels(bd, bd.rect, cachePoint(0, gridY)); | |
| 141 | bd.dispose(); | |
| 142 | } | |
| 143 | } | |
| 144 | else {
| |
| 145 | for (i = gridY; i < _height - gridY; i += gridY) {
| |
| 146 | sliceBuffer.copyPixels(slices[3], slices[3].rect, cachePoint(0, i)); | |
| 147 | } | |
| 148 | }a | |
| 149 | ||
| 150 | if (stretchRight) {
| |
| 151 | if (_height > gridY + gridY) {
| |
| 152 | bd = scaleBitmapData(slices[5], 1, (_height - gridY - gridY) / gridY); | |
| 153 | sliceBuffer.copyPixels(bd, bd.rect, cachePoint(_width - gridX, gridY)); | |
| 154 | bd.dispose(); | |
| 155 | } | |
| 156 | } | |
| 157 | else {
| |
| 158 | for (i = gridY; i < _height - gridY; i += gridY) {
| |
| 159 | sliceBuffer.copyPixels(slices[5], slices[5].rect, cachePoint(_width - gridX, i)); | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | /** draw corners */ | |
| 164 | sliceBuffer.copyPixels(slices[0], slices[0].rect, cachePoint(0, 0)); | |
| 165 | sliceBuffer.copyPixels(slices[2], slices[2].rect, cachePoint(_width - gridX, 0)); | |
| 166 | sliceBuffer.copyPixels(slices[6], slices[6].rect, cachePoint(0, _height - gridY)); | |
| 167 | sliceBuffer.copyPixels(slices[8], slices[8].rect, cachePoint(_width - gridX, _height - gridY)); | |
| 168 | ||
| 169 | bd = null; | |
| 170 | } | |
| 171 | ||
| 172 | ||
| 173 | private function cachePoint(x:Number = 0, y:Number = 0):Point {
| |
| 174 | cachedPoint.x = x; | |
| 175 | cachedPoint.y = y; | |
| 176 | return cachedPoint; | |
| 177 | } | |
| 178 | ||
| 179 | private function cacheRect(x:Number = 0, y:Number = 0, width:Number = 0, height:Number = 0 ):Rectangle {
| |
| 180 | cachedRect.x = x; | |
| 181 | cachedRect.y = y; | |
| 182 | cachedRect.width = width; | |
| 183 | cachedRect.height = height; | |
| 184 | return cachedRect; | |
| 185 | } | |
| 186 | ||
| 187 | public function get sliceSource():BitmapData { return _sliceSource; }
| |
| 188 | public function set sliceSource(value:*):void {
| |
| 189 | if (value == _sliceSource) return; | |
| 190 | ||
| 191 | if (value is Class) {
| |
| 192 | _sliceSource = FP.getBitmap(value); | |
| 193 | } | |
| 194 | else {
| |
| 195 | _sliceSource = value; | |
| 196 | } | |
| 197 | ||
| 198 | gridX = _sliceSource.width / 3; | |
| 199 | gridY = _sliceSource.height / 3; | |
| 200 | ||
| 201 | copy(); | |
| 202 | updateSliceBuffer(); | |
| 203 | } | |
| 204 | ||
| 205 | public function set width(value:uint):void {
| |
| 206 | if (value == _width) return; | |
| 207 | ||
| 208 | var temp:uint = _width; | |
| 209 | _width = value; | |
| 210 | if (snapWidth) {
| |
| 211 | _width = Math.floor(_width / gridX) * gridX; | |
| 212 | if (temp == _width) return; | |
| 213 | } | |
| 214 | ||
| 215 | copy(); | |
| 216 | updateSliceBuffer(); | |
| 217 | } | |
| 218 | ||
| 219 | public function set height(value:uint):void {
| |
| 220 | if (value == _height) return; | |
| 221 | ||
| 222 | var temp:uint = _height; | |
| 223 | _height = value; | |
| 224 | if (snapHeight) {
| |
| 225 | _height = Math.floor(_height / gridY) * gridY; | |
| 226 | if (temp == _height) return; | |
| 227 | } | |
| 228 | ||
| 229 | copy(); | |
| 230 | updateSliceBuffer(); | |
| 231 | } | |
| 232 | ||
| 233 | public function get y2():Number {
| |
| 234 | return y + height; | |
| 235 | } | |
| 236 | ||
| 237 | public function get x2():Number {
| |
| 238 | return x + width; | |
| 239 | } | |
| 240 | ||
| 241 | public function get centerX():Number {
| |
| 242 | return x + width / 2; | |
| 243 | } | |
| 244 | ||
| 245 | public function get centerY():Number {
| |
| 246 | return y + height / 2; | |
| 247 | } | |
| 248 | ||
| 249 | protected function scaleBitmapData(bitmapData:BitmapData, scaleX:Number, scaleY:Number):BitmapData {
| |
| 250 | scaleX = Math.abs(scaleX); | |
| 251 | scaleY = Math.abs(scaleY); | |
| 252 | var width:int = (bitmapData.width * scaleX) || 1; | |
| 253 | var height:int = (bitmapData.height * scaleY) || 1; | |
| 254 | var transparent:Boolean = bitmapData.transparent; | |
| 255 | var result:BitmapData = new BitmapData(width, height, transparent); | |
| 256 | var matrix:Matrix = new Matrix(); | |
| 257 | matrix.scale(scaleX, scaleY); | |
| 258 | result.draw(bitmapData, matrix); | |
| 259 | return result; | |
| 260 | } | |
| 261 | ||
| 262 | protected function convert2dX(i:int, width:uint):int {
| |
| 263 | return i % width; | |
| 264 | } | |
| 265 | ||
| 266 | protected function convert2dY(i:int, width:uint):int {
| |
| 267 | return Math.floor(i / width); | |
| 268 | } | |
| 269 | ||
| 270 | } | |
| 271 | ||
| 272 | } |