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 | } |