ScrollBar.as 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. package
  2. {
  3. import flash.display.*;
  4. import flash.events.*;
  5. import flash.geom.Point;
  6. import flash.geom.Rectangle;
  7. import flash.utils.Timer;
  8. public class ScrollBar
  9. {
  10. public static const H = "H";
  11. public static const L = "L";
  12. public const name = "滚动条窗口";
  13. private var _speed:Number = 15;
  14. private var _upBtn:Sprite;
  15. private var _downBtn:Sprite;
  16. private var _tween:Number;
  17. private var _elastic:Boolean;
  18. private var _lineAbleClick:Boolean;
  19. private var _mouseWheel:Boolean;
  20. private var _direction:String;
  21. private var _scale9Grid:Rectangle;
  22. private var _target:DisplayObject;
  23. private var _maskTarget:DisplayObject;
  24. private var _scrollBar:Sprite;
  25. private var _scrollLine:Sprite;
  26. private var _timer:Timer = null;
  27. private var _scrollBarOriginalPoint:Point;
  28. private var _parentMC:DisplayObjectContainer;
  29. private var _rectangle:Rectangle;
  30. private var _distanceX:Number;
  31. private var _distanceY:Number;
  32. private var _targetPoint:Number = NaN;
  33. private var _coor:String;
  34. private var _length:String;
  35. private var _mouse:String;
  36. private var _oldLength:Point;
  37. private var _abled = true;
  38. public function set tween($value:Number):void
  39. {
  40. _tween = $value < 1||$value > 20?1:$value;
  41. }
  42. public function set elastic($value:Boolean):void
  43. {
  44. _elastic = $value ;
  45. if (_abled)
  46. makeScrollBar();
  47. }
  48. public function set lineAbleClick($value:Boolean):void
  49. {
  50. _lineAbleClick = $value ;
  51. if (_lineAbleClick)
  52. _scrollLine.addEventListener(MouseEvent.MOUSE_DOWN, scrollLineMouseDownHandler, false, 0, true );
  53. else
  54. _scrollLine.removeEventListener(MouseEvent.MOUSE_DOWN, scrollLineMouseDownHandler);
  55. }
  56. public function set mouseWheel($value:Boolean):void
  57. {
  58. _mouseWheel = $value ;
  59. if (_mouseWheel && _abled)
  60. _parentMC.stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler, false, 0, true );
  61. else if(_abled)
  62. _parentMC.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
  63. }
  64. public function set direction($value:String):void
  65. {
  66. _direction = $value ;
  67. _coor = _direction == "H"?"x":"y";
  68. _length = _coor == "x"?"width":"height";
  69. _mouse = _coor == "x"?"mouseX":"mouseY";
  70. if (_abled)
  71. makeScrollBar();
  72. }
  73. public function set scale9Grid($value:Rectangle):void
  74. {
  75. _scale9Grid = $value ;
  76. try { _scrollBar.scale9Grid = _scale9Grid } catch (e) { _scrollBar.scale9Grid = null }
  77. }
  78. public function set speed($value:Number):void
  79. {
  80. _speed = $value<5||$value>35?15:$value;
  81. }
  82. public function set UP($target:Sprite):void
  83. {
  84. _upBtn = $target;
  85. if (!_abled)
  86. {
  87. _upBtn.visible = false;
  88. _upBtn.removeEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler );
  89. return;
  90. }
  91. _upBtn.addEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler, false, 0, true );
  92. }
  93. public function set DOWN($target:Sprite):void
  94. {
  95. _downBtn = $target;
  96. if (!_abled)
  97. {
  98. _downBtn.visible = false;
  99. _downBtn.removeEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler );
  100. return;
  101. }
  102. _downBtn.addEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler, false, 0, true );
  103. }
  104. /**
  105. * 双向(横板+竖版)滚动条
  106. * @param $target DisplayObjectContainer * 被遮罩对象
  107. * @param $maskTarget * * 遮罩对象(可传入Rectangle类型)
  108. * @param $scrollBar Sprite * 滚动滑块
  109. * @param $scrollLine Sprite * 滚动条
  110. * @param $tween Number * 缓动系数
  111. * @param $elastic Boolean * 滑块可否拉伸
  112. * @param $lineAbleClick Boolean * 滚动条可否点击
  113. * @param $mouseWheel Boolean * 滚轮可用
  114. * @param $direction String * 方向(默认纵向)
  115. */
  116. public function ScrollBar($target:DisplayObjectContainer, $maskTarget:*, $scrollBar:Sprite, $scrollLine:Sprite, $tween:Number = 0, $elastic:Boolean = true, $lineAbleClick:Boolean = false, $mouseWheel:Boolean = true, $direction:String = "L")
  117. {
  118. if (!(($maskTarget is DisplayObject) || ($maskTarget is Rectangle))) throw(new Error("没有传入遮罩对象"));
  119. _target = $target;
  120. _maskTarget = $maskTarget is Rectangle?drawMaskTarget($maskTarget):$maskTarget;
  121. _scrollBar = $scrollBar;
  122. _scrollLine = $scrollLine;
  123. _tween = $tween < 1||$tween > 20?1:$tween;
  124. _elastic = $elastic;
  125. _lineAbleClick = $lineAbleClick;
  126. _mouseWheel = $mouseWheel;
  127. _direction = $direction;
  128. _parentMC = _scrollBar.parent;
  129. _coor = $direction == "H"?"x":"y";
  130. _length = _coor == "x"?"width":"height";
  131. _mouse = _coor == "x"?"mouseX":"mouseY";
  132. _oldLength = new Point(_scrollBar.width, _scrollBar.height);
  133. makeScrollPane();
  134. }
  135. /**
  136. * 刷新UI
  137. */
  138. public function refresh():void
  139. {
  140. checkAbled();
  141. }
  142. private function makeScrollPane():void
  143. {
  144. initAllThing();
  145. _scrollBarOriginalPoint = new Point(_scrollBar.x, _scrollBar.y);
  146. makeMask();
  147. checkAbled();
  148. }
  149. //检查可用性
  150. private function checkAbled():void
  151. {
  152. _scrollBar.y = _scrollLine.y;
  153. if (_maskTarget[_length] >= _target[_length])
  154. {
  155. _scrollBar.visible = false;
  156. _scrollLine.visible = false;
  157. if (_downBtn)_downBtn.visible = false;
  158. if (_upBtn)_upBtn.visible = false;
  159. _abled = false;
  160. if (_upBtn&&_downBtn) {
  161. _upBtn.removeEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler );
  162. _downBtn.removeEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler );
  163. }
  164. if (_mouseWheel) makeMouseWheel("stop");
  165. }else
  166. {
  167. _scrollBar.visible = true;
  168. _scrollLine.visible = true;
  169. if (_downBtn)_downBtn.visible = true;
  170. if (_upBtn)_upBtn.visible = true;
  171. _abled = true;
  172. makeScrollBar();
  173. if (_upBtn&&_downBtn) {
  174. _upBtn.addEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler, false, 0, true );
  175. _downBtn.addEventListener(MouseEvent.MOUSE_DOWN, upDownBtnMouseDownHandler, false, 0, true );
  176. }
  177. if (_lineAbleClick) makeScrollLine();
  178. if (_mouseWheel) makeMouseWheel();
  179. timeListener();
  180. }
  181. }
  182. //timer检测器
  183. private function timeListener():void
  184. {
  185. if (_timer != null) return;
  186. _timer = new Timer(1000 / 30, 0);
  187. _timer.addEventListener(TimerEvent.TIMER, timeHandler, false, 0, true );
  188. _timer.start();
  189. }
  190. //注册点
  191. private function initAllThing():void
  192. {
  193. setRegistration(_maskTarget as DisplayObjectContainer);
  194. setRegistration(_target as DisplayObjectContainer);
  195. setRegistration(_scrollLine);
  196. setRegistration(_scrollBar);
  197. }
  198. //初始化遮罩
  199. private function makeMask():void
  200. {
  201. _target.x = Math.floor(_target.x); //防止文字模糊
  202. _target.y = Math.floor(_target.y);
  203. _maskTarget.x = _target.x;
  204. _maskTarget.y = _target.y;
  205. if (_maskTarget.parent == null)_parentMC.addChild(_maskTarget);
  206. _target.mask = _maskTarget;
  207. /*
  208. GaiaDebug.warn("mask:h"+_target.mask.height+",w"+_target.mask.width+",x"+_target.mask.x+",y"+_target.mask.y);
  209. GaiaDebug.warn("target:h" + _target.height + ",w" + _target.width + ",x" + _target.x + ",y" + _target.y);
  210. */
  211. }
  212. //背景条
  213. private function makeScrollLine():void
  214. {
  215. _scrollLine.buttonMode = false;
  216. _scrollLine.addEventListener(MouseEvent.MOUSE_DOWN, scrollLineMouseDownHandler, false, 0, true );
  217. }
  218. //滚轮
  219. private function makeMouseWheel(state:String = "start" ):void
  220. {
  221. if(state=="start")
  222. _parentMC.stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler, false, 0, true );
  223. else if (state == "stop")
  224. _parentMC.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
  225. }
  226. //滑块
  227. private function makeScrollBar():void
  228. {
  229. _scrollBar.buttonMode = true;
  230. _scrollBar.mouseChildren = false;
  231. scrollBarLength(); //计算滑块长度
  232. if (_coor == "y")
  233. _rectangle = new Rectangle(_scrollBarOriginalPoint.x, _scrollBarOriginalPoint.y, 0, _scrollLine.getRect(_parentMC)[_length] - _scrollBar.getRect(_parentMC)[_length]);
  234. else
  235. _rectangle = new Rectangle(_scrollBarOriginalPoint.x, _scrollBarOriginalPoint.y, _scrollLine.getRect(_parentMC)[_length] - _scrollBar.getRect(_parentMC)[_length], 0);
  236. _scrollBar.addEventListener(MouseEvent.MOUSE_DOWN, scrollBarMouseDownHandler );
  237. _scrollBar.addEventListener(MouseEvent.MOUSE_UP, scrollBarMouseUpHandler);
  238. _scrollBar.parent.stage.addEventListener(MouseEvent.MOUSE_UP, scrollBarMouseUpHandler);
  239. _scrollBar.root.stage.addEventListener(Event.MOUSE_LEAVE, scrollBarMouseUpHandler);
  240. }
  241. //计算滑块长度
  242. private function scrollBarLength():void
  243. {
  244. if (_elastic)
  245. try { _scrollBar.scale9Grid = _scale9Grid } catch (e) { _scrollBar.scale9Grid = null }
  246. else
  247. _scrollBar.scale9Grid = null;
  248. _scrollBar.width = _oldLength.x;
  249. _scrollBar.height = _oldLength.y;
  250. _scrollBar[_length] = _elastic ? _scrollLine[_length] * _maskTarget[_length] / _target[_length] : _oldLength[_coor];
  251. }
  252. private function scrollBarMouseDownHandler(e:MouseEvent):void
  253. {
  254. _distanceX = _scrollBar.x - _parentMC.mouseX;
  255. _distanceY = _scrollBar.y - _parentMC.mouseY;
  256. _scrollBar.addEventListener(Event.ENTER_FRAME, scrolBarEnterFrameHandler);
  257. }
  258. private function scrollBarMouseUpHandler(e:*):void
  259. {
  260. _scrollBar.removeEventListener(Event.ENTER_FRAME, scrolBarEnterFrameHandler);
  261. }
  262. private function scrolBarEnterFrameHandler(e:Event):void
  263. {
  264. makeDragBar();
  265. }
  266. private function timeHandler(e:TimerEvent):void
  267. {
  268. scrollMachine();
  269. }
  270. //滚动条点击
  271. private function scrollLineMouseDownHandler(e:MouseEvent):void
  272. {
  273. if (_parentMC[_mouse] > _scrollBar[_coor])
  274. _scrollBar[_coor] += 3*_speed;
  275. else
  276. _scrollBar[_coor] -= 3*_speed;
  277. judgeBoundary();
  278. }
  279. //上下按钮点击
  280. private function upDownBtnMouseDownHandler(e:MouseEvent):void
  281. {
  282. if (e.currentTarget == _downBtn)
  283. _scrollBar[_coor] += 3*_speed;
  284. else
  285. _scrollBar[_coor] -= 3 * _speed;
  286. judgeBoundary();
  287. }
  288. //鼠标滚轮
  289. private function mouseWheelHandler(e:MouseEvent):void
  290. {
  291. if (e.delta < 0)
  292. _scrollBar[_coor] += _speed;
  293. else
  294. _scrollBar[_coor] -= _speed;
  295. judgeBoundary();
  296. }
  297. //拖动滑块
  298. private function makeDragBar():void
  299. {
  300. _scrollBar.x = _parentMC.mouseX + _distanceX;
  301. _scrollBar.y = _parentMC.mouseY + _distanceY;
  302. judgeBoundary();
  303. }
  304. //判断边界
  305. private function judgeBoundary() :void
  306. {
  307. if (_scrollBar.x < _rectangle.x)
  308. _scrollBar.x = _rectangle.x;
  309. if (_scrollBar.x > _rectangle.right)
  310. _scrollBar.x = _rectangle.right;
  311. if (_scrollBar.y < _rectangle.y )
  312. _scrollBar.y = _rectangle.y;
  313. if (_scrollBar.y > _rectangle.bottom)
  314. _scrollBar.y = _rectangle.bottom;
  315. }
  316. //滚动计算公式
  317. private function scrollMachine():void
  318. {
  319. _targetPoint = _maskTarget[_coor] - (_scrollBar[_coor] - _scrollBarOriginalPoint[_coor]) * (_target[_length] - _maskTarget[_length]) / (_scrollLine[_length] - _scrollBar[_length]);
  320. if (Math.abs(_target[_coor] - _targetPoint) < .3)
  321. {
  322. if (_target[_coor] != _targetPoint) _target[_coor] = _targetPoint;
  323. return;
  324. }
  325. if (_tween != 0)
  326. _target[_coor] += (_targetPoint - _target[_coor]) / _tween;
  327. else
  328. _target[_coor] = _targetPoint;
  329. }
  330. //绘制遮罩
  331. private function drawMaskTarget($rect:Rectangle):Sprite
  332. {
  333. var maskTarget:Sprite = new Sprite();
  334. maskTarget.graphics.beginFill(0xffffff);
  335. maskTarget.graphics.drawRect($rect.x, $rect.y, $rect.width, $rect.height);
  336. maskTarget.graphics.endFill();
  337. return maskTarget;
  338. }
  339. //注册点移到左上角
  340. private function setRegistration($target:DisplayObjectContainer):void
  341. {
  342. var rect = $target.getRect($target);
  343. var _x = rect.x;
  344. var _y = rect.y;
  345. var depth:Number = $target.numChildren;
  346. if (depth == 0) return;
  347. for (var i:uint = 0; i < depth; i++ )
  348. {
  349. var target:DisplayObject = $target.getChildAt(i);
  350. target.x -= _x;
  351. target.y -= _y;
  352. }
  353. if ($target.parent != null)
  354. {
  355. $target.x += _x;
  356. $target.y += _y;
  357. }
  358. }
  359. }
  360. }